@devaloop/devalang 0.0.1-alpha.16-hotfix.3 → 0.0.1-alpha.18

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.
Files changed (239) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +10 -10
  3. package/.github/workflows/ci.yml +0 -1
  4. package/Cargo.toml +18 -2
  5. package/README.md +82 -34
  6. package/docs/CHANGELOG.md +91 -0
  7. package/docs/ROADMAP.md +7 -4
  8. package/docs/TODO.md +1 -1
  9. package/examples/index.deva +55 -35
  10. package/examples/pattern.deva +5 -5
  11. package/out-tsc/bin/index.d.ts +2 -0
  12. package/out-tsc/core/functions/index.d.ts +37 -0
  13. package/out-tsc/core/functions/index.js +76 -0
  14. package/out-tsc/core/index.d.ts +6 -0
  15. package/out-tsc/core/index.js +22 -0
  16. package/out-tsc/core/types/index.d.ts +4 -0
  17. package/out-tsc/core/types/index.js +20 -0
  18. package/out-tsc/core/types/plugin.d.ts +18 -0
  19. package/out-tsc/core/types/plugin.js +2 -0
  20. package/out-tsc/core/types/result.d.ts +27 -0
  21. package/out-tsc/core/types/result.js +2 -0
  22. package/out-tsc/core/types/statement.d.ts +106 -0
  23. package/out-tsc/core/types/statement.js +2 -0
  24. package/out-tsc/core/types/value.d.ts +43 -0
  25. package/out-tsc/core/types/value.js +2 -0
  26. package/out-tsc/index.d.ts +7 -0
  27. package/out-tsc/index.js +41 -2
  28. package/out-tsc/pkg/devalang_core.d.ts +7 -0
  29. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
  30. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  31. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  32. package/out-tsc/scripts/postinstall.d.ts +1 -0
  33. package/out-tsc/scripts/postinstall.js +33 -23
  34. package/out-tsc/scripts/version/bump.d.ts +1 -0
  35. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  36. package/out-tsc/scripts/version/index.d.ts +1 -0
  37. package/out-tsc/scripts/version/sync.d.ts +1 -0
  38. package/package.json +16 -4
  39. package/project-version.json +3 -3
  40. package/rust/cli/bank/api.rs +122 -0
  41. package/rust/cli/bank/commands.rs +275 -0
  42. package/rust/cli/bank/mod.rs +29 -0
  43. package/rust/cli/build/commands.rs +107 -0
  44. package/rust/cli/build/mod.rs +2 -0
  45. package/rust/cli/build/process.rs +146 -0
  46. package/rust/cli/{check.rs → check/mod.rs} +18 -31
  47. package/rust/cli/discover/commands.rs +253 -0
  48. package/rust/cli/discover/config.rs +111 -0
  49. package/rust/cli/discover/fs.rs +19 -0
  50. package/rust/cli/discover/install.rs +103 -0
  51. package/rust/cli/discover/metadata.rs +48 -0
  52. package/rust/cli/discover/mod.rs +5 -0
  53. package/rust/cli/{init.rs → init/commands.rs} +88 -87
  54. package/rust/cli/init/mod.rs +1 -0
  55. package/rust/cli/install/addon.rs +126 -0
  56. package/rust/cli/install/bank.rs +53 -0
  57. package/rust/cli/{install.rs → install/commands.rs} +9 -9
  58. package/rust/{installer → cli/install}/mod.rs +2 -3
  59. package/rust/cli/install/plugin.rs +61 -0
  60. package/rust/cli/{login.rs → login/commands.rs} +8 -11
  61. package/rust/cli/login/mod.rs +1 -0
  62. package/rust/cli/mod.rs +2 -2
  63. package/rust/cli/{driver.rs → parser.rs} +7 -2
  64. package/rust/cli/play/commands.rs +324 -0
  65. package/rust/cli/play/io.rs +17 -0
  66. package/rust/cli/play/mod.rs +5 -0
  67. package/rust/cli/play/process.rs +150 -0
  68. package/rust/cli/play/realtime.rs +91 -0
  69. package/rust/cli/play/utils.rs +23 -0
  70. package/rust/cli/{telemetry.rs → telemetry/commands.rs} +4 -4
  71. package/rust/cli/telemetry/event_creator.rs +80 -0
  72. package/rust/cli/telemetry/mod.rs +3 -0
  73. package/rust/cli/telemetry/send.rs +51 -0
  74. package/rust/cli/{template.rs → template/commands.rs} +1 -1
  75. package/rust/cli/template/mod.rs +1 -0
  76. package/rust/cli/{update.rs → update/commands.rs} +6 -6
  77. package/rust/cli/update/mod.rs +1 -0
  78. package/rust/config/driver.rs +57 -72
  79. package/rust/config/mod.rs +1 -2
  80. package/rust/config/ops.rs +26 -0
  81. package/rust/config/settings.rs +40 -42
  82. package/rust/core/audio/engine/helpers.rs +158 -0
  83. package/rust/core/audio/engine/mod.rs +7 -0
  84. package/rust/core/audio/engine/sample.rs +359 -0
  85. package/rust/core/audio/engine/synth.rs +325 -0
  86. package/rust/core/audio/evaluator.rs +68 -27
  87. package/rust/core/audio/interpreter/arrow_call.rs +113 -33
  88. package/rust/core/audio/interpreter/call.rs +232 -56
  89. package/rust/core/audio/interpreter/condition.rs +3 -2
  90. package/rust/core/audio/interpreter/driver.rs +206 -151
  91. package/rust/core/audio/interpreter/let_.rs +1 -1
  92. package/rust/core/audio/interpreter/load.rs +2 -1
  93. package/rust/core/audio/interpreter/loop_.rs +7 -6
  94. package/rust/core/audio/interpreter/sleep.rs +2 -1
  95. package/rust/core/audio/interpreter/spawn.rs +186 -54
  96. package/rust/core/audio/interpreter/tempo.rs +31 -10
  97. package/rust/core/audio/interpreter/trigger.rs +2 -2
  98. package/rust/core/audio/loader/trigger.rs +4 -7
  99. package/rust/core/audio/player.rs +6 -0
  100. package/rust/core/audio/renderer.rs +5 -7
  101. package/rust/core/audio/special/env.rs +3 -1
  102. package/rust/core/audio/special/math.rs +26 -6
  103. package/rust/core/audio/special/modulator.rs +2 -2
  104. package/rust/core/builder/mod.rs +9 -3
  105. package/rust/core/debugger/lexer.rs +1 -1
  106. package/rust/core/debugger/mod.rs +6 -0
  107. package/rust/core/debugger/module.rs +4 -4
  108. package/rust/core/debugger/preprocessor.rs +1 -1
  109. package/rust/core/debugger/store.rs +2 -2
  110. package/rust/core/error/mod.rs +189 -0
  111. package/rust/core/lexer/driver.rs +61 -0
  112. package/rust/core/lexer/handler/arrow.rs +1 -1
  113. package/rust/core/lexer/handler/at.rs +1 -1
  114. package/rust/core/lexer/handler/brace.rs +2 -2
  115. package/rust/core/lexer/handler/colon.rs +1 -1
  116. package/rust/core/lexer/handler/comment.rs +1 -1
  117. package/rust/core/lexer/handler/dot.rs +1 -1
  118. package/rust/core/lexer/handler/driver.rs +1 -1
  119. package/rust/core/lexer/handler/identifier.rs +4 -3
  120. package/rust/core/lexer/handler/mod.rs +1 -2
  121. package/rust/core/lexer/handler/number.rs +1 -1
  122. package/rust/core/lexer/handler/operator.rs +1 -1
  123. package/rust/core/lexer/handler/parenthesis.rs +2 -2
  124. package/rust/core/lexer/handler/slash.rs +1 -1
  125. package/rust/core/lexer/handler/string.rs +1 -1
  126. package/rust/core/lexer/mod.rs +1 -52
  127. package/rust/core/lexer/token.rs +91 -97
  128. package/rust/core/mod.rs +0 -1
  129. package/rust/core/parser/driver.rs +78 -22
  130. package/rust/core/parser/handler/arrow_call.rs +28 -8
  131. package/rust/core/parser/handler/at.rs +55 -21
  132. package/rust/core/parser/handler/bank.rs +14 -4
  133. package/rust/core/parser/handler/condition.rs +6 -3
  134. package/rust/core/parser/handler/dot.rs +5 -3
  135. package/rust/core/parser/handler/identifier/automate.rs +13 -16
  136. package/rust/core/parser/handler/identifier/call.rs +4 -4
  137. package/rust/core/parser/handler/identifier/emit.rs +9 -5
  138. package/rust/core/parser/handler/identifier/function.rs +20 -7
  139. package/rust/core/parser/handler/identifier/group.rs +11 -7
  140. package/rust/core/parser/handler/identifier/let_.rs +24 -9
  141. package/rust/core/parser/handler/identifier/mod.rs +6 -5
  142. package/rust/core/parser/handler/identifier/on.rs +16 -7
  143. package/rust/core/parser/handler/identifier/print.rs +6 -9
  144. package/rust/core/parser/handler/identifier/sleep.rs +12 -5
  145. package/rust/core/parser/handler/identifier/spawn.rs +4 -4
  146. package/rust/core/parser/handler/identifier/synth.rs +79 -9
  147. package/rust/core/parser/handler/loop_.rs +38 -13
  148. package/rust/core/parser/handler/mod.rs +1 -0
  149. package/rust/core/parser/handler/pattern.rs +74 -0
  150. package/rust/core/parser/handler/tempo.rs +9 -5
  151. package/rust/core/parser/mod.rs +0 -1
  152. package/rust/core/parser/statement.rs +6 -137
  153. package/rust/core/plugin/loader.rs +41 -27
  154. package/rust/core/plugin/runner.rs +68 -17
  155. package/rust/core/preprocessor/loader.rs +181 -99
  156. package/rust/core/preprocessor/processor.rs +9 -9
  157. package/rust/core/preprocessor/resolver/bank.rs +6 -8
  158. package/rust/core/preprocessor/resolver/call.rs +47 -23
  159. package/rust/core/preprocessor/resolver/condition.rs +6 -8
  160. package/rust/core/preprocessor/resolver/driver.rs +28 -28
  161. package/rust/core/preprocessor/resolver/function.rs +6 -6
  162. package/rust/core/preprocessor/resolver/group.rs +6 -8
  163. package/rust/core/preprocessor/resolver/loop_.rs +8 -10
  164. package/rust/core/preprocessor/resolver/mod.rs +1 -0
  165. package/rust/core/preprocessor/resolver/pattern.rs +75 -0
  166. package/rust/core/preprocessor/resolver/spawn.rs +45 -22
  167. package/rust/core/preprocessor/resolver/synth.rs +6 -8
  168. package/rust/core/preprocessor/resolver/tempo.rs +6 -8
  169. package/rust/core/preprocessor/resolver/trigger.rs +22 -19
  170. package/rust/core/preprocessor/resolver/value.rs +99 -4
  171. package/rust/core/store/export.rs +28 -28
  172. package/rust/core/store/function.rs +6 -0
  173. package/rust/core/store/global.rs +7 -1
  174. package/rust/core/store/import.rs +28 -28
  175. package/rust/core/store/variable.rs +16 -2
  176. package/rust/core/utils/mod.rs +0 -1
  177. package/rust/lib.rs +102 -9
  178. package/rust/main.rs +159 -45
  179. package/rust/types/Cargo.toml +11 -0
  180. package/rust/types/src/addons.rs +55 -0
  181. package/rust/types/src/ast.rs +202 -0
  182. package/rust/types/src/config.rs +74 -0
  183. package/rust/types/src/lib.rs +12 -0
  184. package/rust/types/src/telemetry.rs +85 -0
  185. package/rust/utils/Cargo.toml +26 -0
  186. package/rust/utils/{error.rs → src/error.rs} +186 -200
  187. package/rust/utils/src/file.rs +94 -0
  188. package/rust/utils/src/first_usage.rs +97 -0
  189. package/rust/utils/{mod.rs → src/lib.rs} +1 -1
  190. package/rust/utils/{logger.rs → src/logger.rs} +17 -12
  191. package/rust/utils/src/path.rs +88 -0
  192. package/rust/utils/src/signature.rs +41 -0
  193. package/rust/utils/{spinner.rs → src/spinner.rs} +3 -5
  194. package/rust/utils/src/version.rs +27 -0
  195. package/rust/utils/{watcher.rs → src/watcher.rs} +13 -1
  196. package/rust/web/cdn.rs +34 -0
  197. package/templates/minimal/README.md +98 -54
  198. package/templates/welcome/README.md +98 -54
  199. package/templates/welcome/src/index.deva +56 -8
  200. package/templates/welcome/src/variables.deva +2 -4
  201. package/tests/rust/TODO.md +0 -0
  202. package/tests/typescript/index.spec.ts +136 -0
  203. package/tests/typescript/playhead.spec.ts +36 -0
  204. package/tests/typescript/render_e2e.spec.ts +77 -0
  205. package/tsconfig.json +1 -1
  206. package/typescript/core/functions/index.ts +83 -0
  207. package/typescript/core/index.ts +6 -0
  208. package/typescript/core/types/index.ts +4 -0
  209. package/typescript/core/types/plugin.ts +19 -0
  210. package/typescript/core/types/result.ts +29 -0
  211. package/typescript/core/types/statement.ts +47 -0
  212. package/typescript/core/types/value.ts +29 -0
  213. package/typescript/index.ts +7 -2
  214. package/typescript/pkg/devalang_core.d.ts +4 -0
  215. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  216. package/rust/cli/bank.rs +0 -462
  217. package/rust/cli/build.rs +0 -252
  218. package/rust/cli/play.rs +0 -1123
  219. package/rust/common/cdn.rs +0 -5
  220. package/rust/config/loader.rs +0 -165
  221. package/rust/config/stats.rs +0 -257
  222. package/rust/core/audio/engine.rs +0 -696
  223. package/rust/core/shared/bank.rs +0 -21
  224. package/rust/core/shared/duration.rs +0 -9
  225. package/rust/core/shared/mod.rs +0 -3
  226. package/rust/core/shared/value.rs +0 -35
  227. package/rust/core/utils/validation.rs +0 -35
  228. package/rust/installer/addon.rs +0 -84
  229. package/rust/installer/bank.rs +0 -62
  230. package/rust/installer/plugin.rs +0 -54
  231. package/rust/installer/utils.rs +0 -56
  232. package/rust/utils/file.rs +0 -38
  233. package/rust/utils/first_usage.rs +0 -83
  234. package/rust/utils/signature.rs +0 -19
  235. package/rust/utils/telemetry.rs +0 -292
  236. package/rust/utils/version.rs +0 -15
  237. /package/rust/{common → web}/api.rs +0 -0
  238. /package/rust/{common → web}/mod.rs +0 -0
  239. /package/rust/{common → web}/sso.rs +0 -0
@@ -1,21 +0,0 @@
1
- use serde::Deserialize;
2
-
3
- #[derive(Debug, Deserialize)]
4
- pub struct BankInfo {
5
- pub name: String,
6
- pub version: String,
7
- pub description: String,
8
- pub author: String,
9
- }
10
-
11
- #[derive(Debug, Deserialize)]
12
- pub struct BankFile {
13
- pub bank: BankInfo,
14
- pub triggers: Option<Vec<BankTrigger>>,
15
- }
16
-
17
- #[derive(Debug, Deserialize)]
18
- pub struct BankTrigger {
19
- pub name: String,
20
- pub path: String,
21
- }
@@ -1,9 +0,0 @@
1
- use serde::{Deserialize, Serialize};
2
-
3
- #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4
- pub enum Duration {
5
- Number(f32),
6
- Identifier(String),
7
- Beat(String),
8
- Auto,
9
- }
@@ -1,3 +0,0 @@
1
- pub mod bank;
2
- pub mod duration;
3
- pub mod value;
@@ -1,35 +0,0 @@
1
- use serde::{Deserialize, Serialize};
2
- use std::collections::HashMap;
3
-
4
- use crate::core::{
5
- parser::statement::{Statement, StatementKind},
6
- shared::duration::Duration,
7
- };
8
-
9
- #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
10
- pub enum Value {
11
- Boolean(bool),
12
- Number(f32),
13
- Duration(Duration),
14
- Identifier(String),
15
- String(String),
16
- Array(Vec<Value>),
17
- Map(HashMap<String, Value>),
18
- Block(Vec<Statement>),
19
- Sample(String),
20
- Beat(String),
21
- Statement(Box<Statement>),
22
- StatementKind(Box<StatementKind>),
23
- Unknown,
24
- Null,
25
- }
26
-
27
- impl Value {
28
- pub fn get(&self, key: &str) -> Option<&Value> {
29
- if let Value::Map(map) = self {
30
- map.get(key)
31
- } else {
32
- None
33
- }
34
- }
35
- }
@@ -1,35 +0,0 @@
1
- // NOTE: Deprecated functions, kept for reference
2
-
3
- // pub fn is_valid_entity(entity: &str, module: &Module, global_store: &GlobalStore) -> bool {
4
- // let built_ins = ["kick", "snare", "hat", "clap"];
5
-
6
- // if built_ins.contains(&entity) {
7
- // return true;
8
- // }
9
-
10
- // if let Some(val) = module.variable_table.get(entity) {
11
- // match val {
12
- // Value::Sample(_) => true,
13
- // _ => false,
14
- // }
15
- // } else {
16
- // false
17
- // }
18
- // }
19
-
20
- // pub fn is_valid_identifier(ident: &str, module: &Module) -> bool {
21
- // let built_ins = ["auto"];
22
-
23
- // if built_ins.contains(&ident) {
24
- // return true;
25
- // }
26
-
27
- // if let Some(val) = module.variable_table.get(ident) {
28
- // match val {
29
- // Value::Identifier(_) => true,
30
- // _ => false,
31
- // }
32
- // } else {
33
- // false
34
- // }
35
- // }
@@ -1,84 +0,0 @@
1
- use crate::{
2
- common::api::get_api_url,
3
- config::settings::get_user_config,
4
- installer::{bank::install_bank, plugin::install_plugin},
5
- };
6
- use std::path::Path;
7
-
8
- #[derive(Debug, Clone)]
9
- pub enum AddonType {
10
- Bank,
11
- Plugin,
12
- Preset,
13
- }
14
-
15
- pub async fn install_addon(
16
- addon_type: AddonType,
17
- name: &str,
18
- target_dir: &Path,
19
- ) -> Result<(), String> {
20
- match addon_type {
21
- AddonType::Bank => install_bank(name, target_dir).await,
22
- AddonType::Plugin => install_plugin(name, target_dir).await,
23
- AddonType::Preset => Err("Preset installation not implemented".into()),
24
- }
25
- }
26
-
27
- pub async fn ask_api_for_signed_url(addon_type: AddonType, slug: &str) -> Result<String, String> {
28
- let api_url = get_api_url();
29
-
30
- let user_config = get_user_config();
31
- if user_config.is_none() {
32
- return Err("User is not logged in".into());
33
- }
34
-
35
- let stored_token = user_config.unwrap().session.clone();
36
-
37
- let request_url = format!(
38
- "{}/v1/assets/url?type={}&slug={}&token={}",
39
- api_url,
40
- match addon_type {
41
- AddonType::Bank => "bank",
42
- AddonType::Plugin => "plugin",
43
- AddonType::Preset => "preset",
44
- },
45
- slug,
46
- stored_token
47
- );
48
-
49
- let mut headers = reqwest::header::HeaderMap::new();
50
-
51
- headers.insert(
52
- "Authorization",
53
- format!("Bearer {}", stored_token).parse().unwrap(),
54
- );
55
-
56
- let client: reqwest::Client = reqwest::Client::builder()
57
- .default_headers(headers)
58
- .build()
59
- .map_err(|_| "Failed to build HTTP client".to_string())?;
60
-
61
- let req = client
62
- .get(&request_url)
63
- .send()
64
- .await
65
- .map_err(|_| "Failed to receive response".to_string())?;
66
-
67
- let response_body: serde_json::Value = req
68
- .json()
69
- .await
70
- .map_err(|_| "Failed to read response body".to_string())?;
71
-
72
- let signed_url: String = serde_json::from_value(
73
- response_body
74
- .get("payload")
75
- .cloned()
76
- .unwrap_or_default()
77
- .get("url")
78
- .cloned()
79
- .unwrap_or_default(),
80
- )
81
- .map_err(|_| "Failed to parse response body".to_string())?;
82
-
83
- Ok(signed_url)
84
- }
@@ -1,62 +0,0 @@
1
- use crate::{
2
- config::loader::{add_bank_to_config, load_config},
3
- installer::{
4
- addon::{AddonType, ask_api_for_signed_url},
5
- utils::{download_file, extract_archive},
6
- },
7
- utils::logger::{LogLevel, Logger},
8
- };
9
- use std::path::{Path, PathBuf};
10
-
11
- pub async fn install_bank(name: &str, target_dir: &Path) -> Result<(), String> {
12
- let logger = Logger::new();
13
-
14
- let signed_url = ask_api_for_signed_url(AddonType::Bank, name).await?;
15
-
16
- let bank_dir = target_dir.join("bank");
17
- let archive_path = PathBuf::from(format!("./.deva/tmp/{}.devabank", name));
18
- let extract_path = bank_dir.join(name);
19
-
20
- download_file(&signed_url, &archive_path)
21
- .await
22
- .map_err(|e| format!("Failed to download: {}", e))?;
23
-
24
- if extract_path.exists() {
25
- logger.log_message(
26
- LogLevel::Warning,
27
- &format!(
28
- "Bank '{}' already exists at '{}'. Skipping install.",
29
- name,
30
- extract_path.display()
31
- ),
32
- );
33
-
34
- return Ok(());
35
- }
36
-
37
- // Add the bank to the config
38
- let root_dir = target_dir
39
- .parent()
40
- .ok_or_else(|| "Failed to determine root directory".to_string())?;
41
-
42
- let config_path = root_dir.join(".devalang");
43
- if !config_path.exists() {
44
- return Err(format!(
45
- "Config file not found at '{}'. Please run 'devalang init' before adding an addon",
46
- config_path.display()
47
- ));
48
- }
49
-
50
- let mut config = load_config(Some(&config_path))
51
- .ok_or_else(|| format!("Failed to load config from '{}'", config_path.display()))?;
52
-
53
- let dependency_path = &format!("devalang://bank/{}", name);
54
-
55
- extract_archive(&archive_path, &extract_path)
56
- .await
57
- .map_err(|e| format!("Failed to extract: {}", e))?;
58
-
59
- add_bank_to_config(&mut config, &extract_path, dependency_path);
60
-
61
- Ok(())
62
- }
@@ -1,54 +0,0 @@
1
- use crate::{
2
- common::cdn::get_cdn_url,
3
- config::loader::{add_plugin_to_config, load_config},
4
- installer::utils::{download_file, extract_archive},
5
- };
6
- use std::path::{Path, PathBuf};
7
-
8
- pub async fn install_plugin(name: &str, target_dir: &Path) -> Result<(), String> {
9
- let cdn_url = get_cdn_url();
10
- let url = format!("{}/plugin/{}/download", cdn_url, name);
11
-
12
- let plugin_dir = target_dir.join("plugin");
13
- let archive_path = PathBuf::from(format!("./.deva/tmp/{}.devaplugin", name));
14
- let extract_path = plugin_dir.join(name);
15
-
16
- if extract_path.exists() {
17
- println!(
18
- "Plugin '{}' already exists at '{}'. Skipping install.",
19
- name,
20
- extract_path.display()
21
- );
22
- return Ok(());
23
- }
24
-
25
- download_file(&url, &archive_path)
26
- .await
27
- .map_err(|e| format!("Failed to download: {}", e))?;
28
-
29
- extract_archive(&archive_path, &extract_path)
30
- .await
31
- .map_err(|e| format!("Failed to extract: {}", e))?;
32
-
33
- // Add the plugin to the config
34
- let root_dir = target_dir
35
- .parent()
36
- .ok_or_else(|| "Failed to determine root directory".to_string())?;
37
-
38
- let config_path = root_dir.join(".devalang");
39
- if !config_path.exists() {
40
- return Err(format!(
41
- "Config file not found at '{}'. Please run 'devalang init' before adding an addon",
42
- config_path.display()
43
- ));
44
- }
45
-
46
- let mut config = load_config(Some(&config_path))
47
- .ok_or_else(|| format!("Failed to load config from '{}'", config_path.display()))?;
48
-
49
- let dependency_path = &format!("devalang://plugin/{}", name);
50
-
51
- add_plugin_to_config(&mut config, &extract_path, dependency_path);
52
-
53
- Ok(())
54
- }
@@ -1,56 +0,0 @@
1
- use std::error::Error;
2
- use std::fs::File;
3
- use std::io::BufReader;
4
- use std::io::{Cursor, copy};
5
- use std::path::Path;
6
- use zip::ZipArchive;
7
-
8
- pub async fn download_file(url: &str, destination: &Path) -> Result<(), Box<dyn Error>> {
9
- let response = reqwest::get(url).await?;
10
-
11
- if !response.status().is_success() {
12
- return Err(format!("Failed to download file: HTTP {}", response.status()).into());
13
- }
14
-
15
- if let Some(parent) = destination.parent() {
16
- std::fs::create_dir_all(parent)?;
17
- }
18
-
19
- let bytes = response.bytes().await?;
20
- let mut content = Cursor::new(bytes);
21
- let mut file = File::create(destination)?;
22
- copy(&mut content, &mut file)?;
23
-
24
- Ok(())
25
- }
26
-
27
- pub async fn extract_archive(
28
- zip_path: &Path,
29
- destination: &Path,
30
- ) -> Result<(), Box<dyn std::error::Error>> {
31
- let file = File::open(zip_path)?;
32
- let mut archive = ZipArchive::new(BufReader::new(file))?;
33
-
34
- for i in 0..archive.len() {
35
- let mut file = archive.by_index(i)?;
36
- let outpath = destination.join(file.mangled_name());
37
-
38
- if file.name().ends_with('/') {
39
- std::fs::create_dir_all(&outpath)?;
40
- } else {
41
- if let Some(p) = outpath.parent() {
42
- std::fs::create_dir_all(p)?;
43
- }
44
-
45
- let mut outfile = File::create(&outpath)?;
46
- std::io::copy(&mut file, &mut outfile)?;
47
- }
48
- }
49
-
50
- // Clear the temporary folder after extraction
51
- if zip_path.exists() {
52
- std::fs::remove_file(zip_path)?;
53
- }
54
-
55
- Ok(())
56
- }
@@ -1,38 +0,0 @@
1
- use include_dir::{Dir, DirEntry};
2
- use std::{
3
- fs::{self},
4
- path::Path,
5
- };
6
-
7
- pub fn copy_dir_recursive(dir: &Dir, target_root: &Path, base_path: &Path) {
8
- for entry in dir.entries() {
9
- match entry {
10
- DirEntry::Dir(subdir) => {
11
- copy_dir_recursive(subdir, target_root, base_path);
12
- }
13
- DirEntry::File(file) => {
14
- let rel_path = file.path().strip_prefix(base_path).unwrap();
15
- let dest_path = target_root.join(rel_path);
16
-
17
- if let Some(parent) = dest_path.parent() {
18
- fs::create_dir_all(parent).unwrap();
19
- }
20
-
21
- fs::write(&dest_path, file.contents()).expect("Error writing file");
22
- }
23
- }
24
- }
25
- }
26
-
27
- pub fn format_file_size(bytes: u64) -> String {
28
- const KB: u64 = 1024;
29
- const MB: u64 = 1024 * 1024;
30
-
31
- if bytes >= MB {
32
- format!("{:.2} Mb", (bytes as f64) / (MB as f64))
33
- } else if bytes >= KB {
34
- format!("{:.2} Kb", (bytes as f64) / (KB as f64))
35
- } else {
36
- format!("{} bytes", bytes)
37
- }
38
- }
@@ -1,83 +0,0 @@
1
- use crossterm::style::{Attribute, SetAttribute};
2
- use std::fmt::Write;
3
-
4
- use crate::{
5
- config::settings::{get_devalang_homedir, set_user_config_bool, write_user_config_file},
6
- utils::{
7
- logger::{LogLevel, Logger},
8
- signature::get_signature,
9
- },
10
- };
11
-
12
- pub fn check_is_first_usage() {
13
- if get_devalang_homedir().exists() == true {
14
- // Do nothing
15
- } else {
16
- first_usage_welcome();
17
- write_user_config_file();
18
- }
19
- }
20
-
21
- pub fn first_usage_welcome() {
22
- std::fs::create_dir_all(get_devalang_homedir()).ok();
23
-
24
- let version = env!("CARGO_PKG_VERSION");
25
- print!("{}", get_signature(version));
26
-
27
- let homedir = get_devalang_homedir().display().to_string();
28
-
29
- let welcome_msg = format!(
30
- "Welcome to Devalang ! \n\
31
- It looks like this is your first time using the tool.\n\
32
- A configuration file will be created in your home directory.\n\
33
- (location: '{}')",
34
- homedir
35
- );
36
-
37
- let mut s = String::new();
38
- write!(&mut s, "{}", SetAttribute(Attribute::Bold)).unwrap();
39
- write!(&mut s, "{}", welcome_msg).unwrap();
40
- write!(&mut s, "{}", SetAttribute(Attribute::Reset)).unwrap();
41
-
42
- println!("");
43
- println!("{}", s);
44
- println!("");
45
-
46
- first_usage_ask_for_telemetry();
47
- }
48
-
49
- pub fn first_usage_ask_for_telemetry() {
50
- let telemetry_msg = "Would you like to enable anonymous telemetry ?";
51
- let telemetry_desc = "This data helps us improve the tool. You can opt-out at any time.";
52
-
53
- let telemetry_prompt = inquire::Confirm::new(telemetry_msg)
54
- .with_help_message(telemetry_desc)
55
- .with_default(false)
56
- .prompt();
57
-
58
- let telemetry_response = telemetry_prompt.unwrap_or(false);
59
-
60
- write_user_config_file();
61
-
62
- let logger = Logger::new();
63
-
64
- if telemetry_response == true {
65
- println!("");
66
- logger.log_message(
67
- LogLevel::Info,
68
- "Telemetry enabled. You can opt-out at any time by using 'devalang telemetry disable'",
69
- );
70
- println!("");
71
-
72
- set_user_config_bool("telemetry", true);
73
- } else {
74
- println!("");
75
- logger.log_message(
76
- LogLevel::Info,
77
- "Telemetry disabled. You can enable it at any time by using 'devalang telemetry enable'"
78
- );
79
- println!("");
80
-
81
- set_user_config_bool("telemetry", false);
82
- }
83
- }
@@ -1,19 +0,0 @@
1
- pub fn get_signature(version: &str) -> String {
2
- let signature = format!(
3
- r#"
4
- /|_/|
5
- / ^ ^(_o 🦊 Devalang
6
- / __.'
7
- / \ A programming language for music and sound.
8
- / _ \_ Part of the Devaloop project.
9
- (_) (_) '._
10
- '.__ '. .-''-'. https://devalang.com
11
- ( '. ('.____.''
12
- _) )'_, ) v{}
13
- (__/ (__/
14
- "#,
15
- version
16
- );
17
-
18
- signature
19
- }