@devaloop/devalang 0.0.1-beta.3 → 0.1.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.
Files changed (346) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +251 -221
  3. package/out-tsc/api.d.ts +180 -0
  4. package/out-tsc/api.d.ts.map +1 -0
  5. package/out-tsc/api.js +286 -0
  6. package/out-tsc/api.js.map +1 -0
  7. package/out-tsc/bin/index.d.ts +12 -0
  8. package/out-tsc/bin/index.d.ts.map +1 -0
  9. package/out-tsc/bin/index.js +20 -54
  10. package/out-tsc/bin/index.js.map +1 -0
  11. package/out-tsc/examples/basic-usage.d.ts +8 -0
  12. package/out-tsc/examples/basic-usage.d.ts.map +1 -0
  13. package/out-tsc/examples/basic-usage.js +113 -0
  14. package/out-tsc/examples/basic-usage.js.map +1 -0
  15. package/out-tsc/index.d.ts +19 -5
  16. package/out-tsc/index.d.ts.map +1 -0
  17. package/out-tsc/index.js +24 -6
  18. package/out-tsc/index.js.map +1 -0
  19. package/out-tsc/scripts/copy-wasm-dts.d.ts +7 -0
  20. package/out-tsc/scripts/copy-wasm-dts.d.ts.map +1 -0
  21. package/out-tsc/scripts/copy-wasm-dts.js +36 -32
  22. package/out-tsc/scripts/copy-wasm-dts.js.map +1 -0
  23. package/out-tsc/scripts/postinstall.d.ts +1 -0
  24. package/out-tsc/scripts/postinstall.d.ts.map +1 -0
  25. package/out-tsc/scripts/postinstall.js +4 -1
  26. package/out-tsc/scripts/postinstall.js.map +1 -0
  27. package/out-tsc/scripts/version/bump.d.ts +5 -1
  28. package/out-tsc/scripts/version/bump.d.ts.map +1 -0
  29. package/out-tsc/scripts/version/bump.js +122 -44
  30. package/out-tsc/scripts/version/bump.js.map +1 -0
  31. package/out-tsc/scripts/version/fetch.d.ts +12 -1
  32. package/out-tsc/scripts/version/fetch.d.ts.map +1 -0
  33. package/out-tsc/scripts/version/fetch.js +68 -24
  34. package/out-tsc/scripts/version/fetch.js.map +1 -0
  35. package/out-tsc/scripts/version/index.d.ts +6 -0
  36. package/out-tsc/scripts/version/index.d.ts.map +1 -0
  37. package/out-tsc/scripts/version/index.js +44 -22
  38. package/out-tsc/scripts/version/index.js.map +1 -0
  39. package/out-tsc/scripts/version/sync.d.ts +5 -1
  40. package/out-tsc/scripts/version/sync.d.ts.map +1 -0
  41. package/out-tsc/scripts/version/sync.js +95 -29
  42. package/out-tsc/scripts/version/sync.js.map +1 -0
  43. package/out-tsc/types.d.ts +68 -0
  44. package/out-tsc/types.d.ts.map +1 -0
  45. package/out-tsc/{core/types/value.js → types.js} +4 -0
  46. package/out-tsc/types.js.map +1 -0
  47. package/out-tsc/wasm.d.ts +8 -0
  48. package/out-tsc/wasm.d.ts.map +1 -0
  49. package/out-tsc/{core/index.js → wasm.js} +9 -6
  50. package/out-tsc/wasm.js.map +1 -0
  51. package/package.json +42 -42
  52. package/.cargo/config.toml +0 -2
  53. package/.devalang +0 -9
  54. package/.github/workflows/ci.yml +0 -103
  55. package/Cargo.toml +0 -84
  56. package/docs/CHANGELOG.md +0 -622
  57. package/docs/CONTRIBUTING.md +0 -101
  58. package/docs/ROADMAP.md +0 -38
  59. package/docs/TODO.md +0 -71
  60. package/examples/automation.deva +0 -42
  61. package/examples/bank.deva +0 -7
  62. package/examples/bus.deva +0 -10
  63. package/examples/chain.deva +0 -19
  64. package/examples/condition.deva +0 -20
  65. package/examples/duration.deva +0 -9
  66. package/examples/effect.deva +0 -2
  67. package/examples/events.deva +0 -12
  68. package/examples/filter.deva +0 -11
  69. package/examples/function.deva +0 -15
  70. package/examples/group.deva +0 -12
  71. package/examples/index.deva +0 -63
  72. package/examples/lfo.deva +0 -9
  73. package/examples/loop.deva +0 -10
  74. package/examples/pattern.deva +0 -8
  75. package/examples/plugin.deva +0 -16
  76. package/examples/routing.deva +0 -23
  77. package/examples/samples/hat-808.wav +0 -0
  78. package/examples/samples/kick-808.wav +0 -0
  79. package/examples/synth.deva +0 -24
  80. package/examples/synth_types.deva +0 -17
  81. package/examples/variables.deva +0 -9
  82. package/out-tsc/bin/project-version.json +0 -6
  83. package/out-tsc/core/functions/index.d.ts +0 -42
  84. package/out-tsc/core/functions/index.js +0 -87
  85. package/out-tsc/core/index.d.ts +0 -6
  86. package/out-tsc/core/types/index.d.ts +0 -4
  87. package/out-tsc/core/types/index.js +0 -20
  88. package/out-tsc/core/types/plugin.d.ts +0 -18
  89. package/out-tsc/core/types/plugin.js +0 -2
  90. package/out-tsc/core/types/result.d.ts +0 -27
  91. package/out-tsc/core/types/result.js +0 -2
  92. package/out-tsc/core/types/statement.d.ts +0 -106
  93. package/out-tsc/core/types/statement.js +0 -2
  94. package/out-tsc/core/types/value.d.ts +0 -43
  95. package/out-tsc/pkg/devalang_core.d.ts +0 -15
  96. package/out-tsc/pkg/devalang_core.js +0 -65
  97. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +0 -34
  98. package/out-tsc/scripts/version/copy-to-binary.d.ts +0 -1
  99. package/out-tsc/scripts/version/copy-to-binary.js +0 -79
  100. package/project-version.json +0 -6
  101. package/rust/bindings/Cargo.toml +0 -9
  102. package/rust/bindings/src/lib.rs +0 -86
  103. package/rust/cli/addon/commands.rs +0 -35
  104. package/rust/cli/addon/download.rs +0 -234
  105. package/rust/cli/addon/install.rs +0 -33
  106. package/rust/cli/addon/list.rs +0 -224
  107. package/rust/cli/addon/metadata.rs +0 -124
  108. package/rust/cli/addon/mod.rs +0 -8
  109. package/rust/cli/addon/remove.rs +0 -271
  110. package/rust/cli/addon/update.rs +0 -305
  111. package/rust/cli/addon/utils.rs +0 -109
  112. package/rust/cli/build/commands.rs +0 -153
  113. package/rust/cli/build/mod.rs +0 -2
  114. package/rust/cli/build/process.rs +0 -165
  115. package/rust/cli/check/mod.rs +0 -208
  116. package/rust/cli/discover/commands.rs +0 -275
  117. package/rust/cli/discover/config.rs +0 -109
  118. package/rust/cli/discover/fs.rs +0 -19
  119. package/rust/cli/discover/install.rs +0 -214
  120. package/rust/cli/discover/metadata.rs +0 -48
  121. package/rust/cli/discover/mod.rs +0 -5
  122. package/rust/cli/init/commands.rs +0 -88
  123. package/rust/cli/init/mod.rs +0 -1
  124. package/rust/cli/login/commands.rs +0 -124
  125. package/rust/cli/login/mod.rs +0 -1
  126. package/rust/cli/me/commands.rs +0 -52
  127. package/rust/cli/me/mod.rs +0 -1
  128. package/rust/cli/mod.rs +0 -12
  129. package/rust/cli/parser.rs +0 -320
  130. package/rust/cli/play/commands.rs +0 -375
  131. package/rust/cli/play/io.rs +0 -17
  132. package/rust/cli/play/mod.rs +0 -5
  133. package/rust/cli/play/process.rs +0 -159
  134. package/rust/cli/play/realtime.rs +0 -91
  135. package/rust/cli/play/utils.rs +0 -23
  136. package/rust/cli/telemetry/commands.rs +0 -22
  137. package/rust/cli/telemetry/event_creator.rs +0 -80
  138. package/rust/cli/telemetry/mod.rs +0 -3
  139. package/rust/cli/telemetry/send.rs +0 -51
  140. package/rust/cli/template/commands.rs +0 -69
  141. package/rust/cli/template/mod.rs +0 -1
  142. package/rust/cli/update/commands.rs +0 -6
  143. package/rust/cli/update/mod.rs +0 -1
  144. package/rust/config/driver.rs +0 -112
  145. package/rust/config/mod.rs +0 -3
  146. package/rust/config/ops.rs +0 -26
  147. package/rust/config/settings.rs +0 -101
  148. package/rust/core/audio/engine/driver.rs +0 -237
  149. package/rust/core/audio/engine/export.rs +0 -169
  150. package/rust/core/audio/engine/helpers.rs +0 -178
  151. package/rust/core/audio/engine/mod.rs +0 -56
  152. package/rust/core/audio/engine/notes/dsp.rs +0 -88
  153. package/rust/core/audio/engine/notes/mod.rs +0 -53
  154. package/rust/core/audio/engine/notes/params.rs +0 -294
  155. package/rust/core/audio/engine/sample/insert.rs +0 -300
  156. package/rust/core/audio/engine/sample/mod.rs +0 -40
  157. package/rust/core/audio/engine/sample/padding.rs +0 -170
  158. package/rust/core/audio/evaluator/condition.rs +0 -61
  159. package/rust/core/audio/evaluator/mod.rs +0 -9
  160. package/rust/core/audio/evaluator/numeric.rs +0 -152
  161. package/rust/core/audio/evaluator/rhs.rs +0 -16
  162. package/rust/core/audio/evaluator/string_expr.rs +0 -94
  163. package/rust/core/audio/interpreter/driver.rs +0 -574
  164. package/rust/core/audio/interpreter/mod.rs +0 -2
  165. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +0 -179
  166. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +0 -398
  167. package/rust/core/audio/interpreter/statements/arrow_call/methods/effects.rs +0 -323
  168. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +0 -3
  169. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +0 -371
  170. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +0 -3
  171. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +0 -192
  172. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +0 -24
  173. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +0 -116
  174. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +0 -97
  175. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +0 -100
  176. package/rust/core/audio/interpreter/statements/automate.rs +0 -16
  177. package/rust/core/audio/interpreter/statements/call.rs +0 -325
  178. package/rust/core/audio/interpreter/statements/condition.rs +0 -72
  179. package/rust/core/audio/interpreter/statements/function.rs +0 -24
  180. package/rust/core/audio/interpreter/statements/let_.rs +0 -36
  181. package/rust/core/audio/interpreter/statements/load.rs +0 -17
  182. package/rust/core/audio/interpreter/statements/loop_.rs +0 -115
  183. package/rust/core/audio/interpreter/statements/mod.rs +0 -12
  184. package/rust/core/audio/interpreter/statements/sleep.rs +0 -28
  185. package/rust/core/audio/interpreter/statements/spawn.rs +0 -302
  186. package/rust/core/audio/interpreter/statements/tempo.rs +0 -40
  187. package/rust/core/audio/interpreter/statements/trigger.rs +0 -242
  188. package/rust/core/audio/loader/mod.rs +0 -1
  189. package/rust/core/audio/loader/trigger.rs +0 -98
  190. package/rust/core/audio/mod.rs +0 -6
  191. package/rust/core/audio/player.rs +0 -70
  192. package/rust/core/audio/special/easing.rs +0 -189
  193. package/rust/core/audio/special/env.rs +0 -45
  194. package/rust/core/audio/special/math.rs +0 -134
  195. package/rust/core/audio/special/mod.rs +0 -9
  196. package/rust/core/audio/special/modulator.rs +0 -143
  197. package/rust/core/builder/mod.rs +0 -129
  198. package/rust/core/debugger/lexer.rs +0 -27
  199. package/rust/core/debugger/logs.rs +0 -52
  200. package/rust/core/debugger/mod.rs +0 -30
  201. package/rust/core/debugger/preprocessor.rs +0 -27
  202. package/rust/core/debugger/store.rs +0 -38
  203. package/rust/core/error/mod.rs +0 -269
  204. package/rust/core/lexer/driver.rs +0 -59
  205. package/rust/core/lexer/handler/arrow.rs +0 -82
  206. package/rust/core/lexer/handler/at.rs +0 -21
  207. package/rust/core/lexer/handler/brace.rs +0 -41
  208. package/rust/core/lexer/handler/colon.rs +0 -21
  209. package/rust/core/lexer/handler/comment.rs +0 -30
  210. package/rust/core/lexer/handler/dot.rs +0 -21
  211. package/rust/core/lexer/handler/driver.rs +0 -337
  212. package/rust/core/lexer/handler/identifier.rs +0 -47
  213. package/rust/core/lexer/handler/indent.rs +0 -66
  214. package/rust/core/lexer/handler/mod.rs +0 -15
  215. package/rust/core/lexer/handler/newline.rs +0 -23
  216. package/rust/core/lexer/handler/number.rs +0 -31
  217. package/rust/core/lexer/handler/operator.rs +0 -46
  218. package/rust/core/lexer/handler/parenthesis.rs +0 -41
  219. package/rust/core/lexer/handler/slash.rs +0 -21
  220. package/rust/core/lexer/handler/string.rs +0 -63
  221. package/rust/core/lexer/mod.rs +0 -3
  222. package/rust/core/lexer/token.rs +0 -91
  223. package/rust/core/mod.rs +0 -9
  224. package/rust/core/parser/driver/block.rs +0 -111
  225. package/rust/core/parser/driver/cursor.rs +0 -82
  226. package/rust/core/parser/driver/driver_impl.rs +0 -159
  227. package/rust/core/parser/driver/mod.rs +0 -6
  228. package/rust/core/parser/driver/parse_array.rs +0 -120
  229. package/rust/core/parser/driver/parse_map.rs +0 -247
  230. package/rust/core/parser/driver/parser.rs +0 -160
  231. package/rust/core/parser/handler/arrow_call.rs +0 -328
  232. package/rust/core/parser/handler/at.rs +0 -279
  233. package/rust/core/parser/handler/bank.rs +0 -104
  234. package/rust/core/parser/handler/condition.rs +0 -83
  235. package/rust/core/parser/handler/dot.rs +0 -148
  236. package/rust/core/parser/handler/identifier/automate.rs +0 -254
  237. package/rust/core/parser/handler/identifier/call.rs +0 -91
  238. package/rust/core/parser/handler/identifier/emit.rs +0 -70
  239. package/rust/core/parser/handler/identifier/function.rs +0 -113
  240. package/rust/core/parser/handler/identifier/group.rs +0 -89
  241. package/rust/core/parser/handler/identifier/let_.rs +0 -173
  242. package/rust/core/parser/handler/identifier/mod.rs +0 -55
  243. package/rust/core/parser/handler/identifier/on.rs +0 -107
  244. package/rust/core/parser/handler/identifier/print.rs +0 -49
  245. package/rust/core/parser/handler/identifier/sleep.rs +0 -96
  246. package/rust/core/parser/handler/identifier/spawn.rs +0 -91
  247. package/rust/core/parser/handler/identifier/synth.rs +0 -171
  248. package/rust/core/parser/handler/loop_.rs +0 -194
  249. package/rust/core/parser/handler/mod.rs +0 -9
  250. package/rust/core/parser/handler/pattern.rs +0 -97
  251. package/rust/core/parser/handler/tempo.rs +0 -105
  252. package/rust/core/parser/mod.rs +0 -3
  253. package/rust/core/parser/statement.rs +0 -10
  254. package/rust/core/plugin/loader.rs +0 -137
  255. package/rust/core/plugin/mod.rs +0 -2
  256. package/rust/core/plugin/runner/mod.rs +0 -11
  257. package/rust/core/plugin/runner/non_wasm.rs +0 -481
  258. package/rust/core/plugin/runner/wasm32.rs +0 -44
  259. package/rust/core/preprocessor/loader/inject.rs +0 -313
  260. package/rust/core/preprocessor/loader/loader_helpers.rs +0 -110
  261. package/rust/core/preprocessor/loader/mod.rs +0 -235
  262. package/rust/core/preprocessor/mod.rs +0 -4
  263. package/rust/core/preprocessor/module.rs +0 -55
  264. package/rust/core/preprocessor/processor/handlers.rs +0 -107
  265. package/rust/core/preprocessor/processor/mod.rs +0 -1
  266. package/rust/core/preprocessor/resolver/bank.rs +0 -49
  267. package/rust/core/preprocessor/resolver/call.rs +0 -124
  268. package/rust/core/preprocessor/resolver/condition.rs +0 -95
  269. package/rust/core/preprocessor/resolver/driver.rs +0 -324
  270. package/rust/core/preprocessor/resolver/function.rs +0 -69
  271. package/rust/core/preprocessor/resolver/group.rs +0 -122
  272. package/rust/core/preprocessor/resolver/let_.rs +0 -32
  273. package/rust/core/preprocessor/resolver/loop_.rs +0 -318
  274. package/rust/core/preprocessor/resolver/mod.rs +0 -16
  275. package/rust/core/preprocessor/resolver/pattern.rs +0 -95
  276. package/rust/core/preprocessor/resolver/spawn.rs +0 -99
  277. package/rust/core/preprocessor/resolver/synth.rs +0 -54
  278. package/rust/core/preprocessor/resolver/tempo.rs +0 -48
  279. package/rust/core/preprocessor/resolver/trigger.rs +0 -116
  280. package/rust/core/preprocessor/resolver/value.rs +0 -176
  281. package/rust/core/store/global.rs +0 -57
  282. package/rust/core/store/mod.rs +0 -1
  283. package/rust/lib.rs +0 -323
  284. package/rust/macros/Cargo.toml +0 -14
  285. package/rust/macros/src/lib.rs +0 -52
  286. package/rust/main.rs +0 -557
  287. package/rust/types/Cargo.toml +0 -11
  288. package/rust/types/src/addons.rs +0 -57
  289. package/rust/types/src/ast.rs +0 -202
  290. package/rust/types/src/config.rs +0 -82
  291. package/rust/types/src/lib.rs +0 -15
  292. package/rust/types/src/plugin.rs +0 -20
  293. package/rust/types/src/store.rs +0 -139
  294. package/rust/types/src/telemetry.rs +0 -85
  295. package/rust/utils/Cargo.toml +0 -29
  296. package/rust/utils/src/error.rs +0 -186
  297. package/rust/utils/src/file.rs +0 -477
  298. package/rust/utils/src/first_usage.rs +0 -97
  299. package/rust/utils/src/lib.rs +0 -9
  300. package/rust/utils/src/logger.rs +0 -200
  301. package/rust/utils/src/path.rs +0 -158
  302. package/rust/utils/src/signature.rs +0 -41
  303. package/rust/utils/src/spinner.rs +0 -20
  304. package/rust/utils/src/version.rs +0 -58
  305. package/rust/utils/src/watcher.rs +0 -46
  306. package/rust/web/api.rs +0 -5
  307. package/rust/web/auth.rs +0 -5
  308. package/rust/web/cdn.rs +0 -34
  309. package/rust/web/forge.rs +0 -5
  310. package/rust/web/mod.rs +0 -5
  311. package/rust/web/sso.rs +0 -5
  312. package/templates/minimal/.devalang +0 -5
  313. package/templates/minimal/README.md +0 -218
  314. package/templates/minimal/src/index.deva +0 -2
  315. package/templates/welcome/.devalang +0 -5
  316. package/templates/welcome/README.md +0 -218
  317. package/templates/welcome/samples/kick-808.wav +0 -0
  318. package/templates/welcome/src/index.deva +0 -61
  319. package/templates/welcome/src/variables.deva +0 -3
  320. package/tests/integration.rs +0 -21
  321. package/tests/rust/cli_check_build.rs +0 -21
  322. package/tests/rust/cli_help.rs +0 -12
  323. package/tests/rust/cli_template_list.rs +0 -10
  324. package/tests/rust/cli_version.rs +0 -11
  325. package/tests/typescript/index.spec.ts +0 -136
  326. package/tests/typescript/playhead.spec.ts +0 -36
  327. package/tests/typescript/render_e2e.spec.ts +0 -77
  328. package/tsconfig.json +0 -115
  329. package/typescript/bin/index.ts +0 -28
  330. package/typescript/core/functions/index.ts +0 -94
  331. package/typescript/core/index.ts +0 -6
  332. package/typescript/core/types/index.ts +0 -4
  333. package/typescript/core/types/plugin.ts +0 -19
  334. package/typescript/core/types/result.ts +0 -29
  335. package/typescript/core/types/statement.ts +0 -47
  336. package/typescript/core/types/value.ts +0 -29
  337. package/typescript/index.ts +0 -8
  338. package/typescript/pkg/devalang_core.d.ts +0 -4
  339. package/typescript/pkg/devalang_core.ts +0 -65
  340. package/typescript/scripts/copy-wasm-dts.ts +0 -41
  341. package/typescript/scripts/postinstall.ts +0 -85
  342. package/typescript/scripts/version/bump.ts +0 -44
  343. package/typescript/scripts/version/copy-to-binary.ts +0 -82
  344. package/typescript/scripts/version/fetch.ts +0 -18
  345. package/typescript/scripts/version/index.ts +0 -25
  346. package/typescript/scripts/version/sync.ts +0 -24
@@ -1,275 +0,0 @@
1
- use crate::cli::discover::config::add_addons_to_config;
2
- use crate::cli::discover::install::install_selected_addons;
3
- use devalang_types::DiscoveredAddon;
4
- use devalang_utils::spinner::start_spinner;
5
- use devalang_utils::{
6
- logger::{LogLevel, Logger},
7
- path as path_utils,
8
- };
9
-
10
- pub async fn handle_discover_command(no_clear_tmp: bool) -> Result<(), String> {
11
- let deva_dir = path_utils::ensure_deva_dir()?;
12
-
13
- // Search for compiled addon archives in the .deva directory
14
- // New norm: archives are packaged as `.tar.gz`. We recursively find all
15
- // files ending with `.tar.gz` and propose them for installation. The
16
- // install flow will inspect the extracted content to determine the exact
17
- // addon type (bank/plugin/preset/template) when possible.
18
-
19
- let mut addons_found = Vec::new();
20
-
21
- fn walk_dir_collect_tar_gz(base: &std::path::Path, out: &mut Vec<DiscoveredAddon>) {
22
- if let Ok(entries) = std::fs::read_dir(base) {
23
- for entry in entries.filter_map(|e| e.ok()) {
24
- let p = entry.path();
25
- if p.is_dir() {
26
- walk_dir_collect_tar_gz(&p, out);
27
- } else if p.is_file() {
28
- let name = p.file_name().and_then(|s| s.to_str()).unwrap_or("");
29
- if name.ends_with(".tar.gz") || name.ends_with(".tgz") {
30
- // derive a friendly name (strip extensions)
31
- let stem = if name.ends_with(".tar.gz") {
32
- name.trim_end_matches(".tar.gz").to_string()
33
- } else {
34
- name.trim_end_matches(".tgz").to_string()
35
- };
36
-
37
- let publisher = p
38
- .parent()
39
- .and_then(|parent| parent.file_name())
40
- .and_then(|s| s.to_str())
41
- .unwrap_or("unknown")
42
- .to_string();
43
-
44
- out.push(DiscoveredAddon {
45
- name: stem,
46
- path: p.clone(),
47
- publisher: publisher.clone(),
48
- extension: "tar.gz".to_string(),
49
- addon_type: "unknown".to_string(),
50
- });
51
- }
52
- }
53
- }
54
- }
55
- }
56
-
57
- walk_dir_collect_tar_gz(&deva_dir, &mut addons_found);
58
-
59
- // Pre-classify discovered archives by inspecting their contents for metadata
60
- for addon in addons_found.iter_mut() {
61
- if let Ok(t) = devalang_utils::file::detect_addon_type_in_archive(&addon.path) {
62
- if t != "unknown" {
63
- addon.addon_type = t;
64
- }
65
- }
66
- }
67
-
68
- let logger = Logger::new();
69
-
70
- let banks_found = addons_found
71
- .iter()
72
- .filter(|addon| addon.addon_type == "bank")
73
- .cloned()
74
- .collect::<Vec<_>>();
75
-
76
- let plugins_found = addons_found
77
- .iter()
78
- .filter(|addon| addon.addon_type == "plugin")
79
- .cloned()
80
- .collect::<Vec<_>>();
81
-
82
- let presets_found = addons_found
83
- .iter()
84
- .filter(|addon| addon.addon_type == "preset")
85
- .cloned()
86
- .collect::<Vec<_>>();
87
-
88
- let templates_found = addons_found
89
- .iter()
90
- .filter(|addon| addon.addon_type == "template")
91
- .cloned()
92
- .collect::<Vec<_>>();
93
-
94
- // Combine discovered known-type addons. If nothing was classified (all
95
- // entries have `addon_type == "unknown"`), fall back to the raw
96
- // `addons_found` so users can still install archives discovered in
97
- // `.deva`.
98
- let mut all_addons = Vec::with_capacity(
99
- banks_found.len() + plugins_found.len() + presets_found.len() + templates_found.len(),
100
- );
101
- all_addons.extend(banks_found.iter().cloned());
102
- all_addons.extend(plugins_found.iter().cloned());
103
- all_addons.extend(presets_found.iter().cloned());
104
- all_addons.extend(templates_found.iter().cloned());
105
-
106
- if all_addons.is_empty() {
107
- // No known types detected — include everything we discovered.
108
- all_addons = addons_found.clone();
109
- }
110
-
111
- println!();
112
-
113
- if all_addons.is_empty() {
114
- logger.log_message(LogLevel::Error, "No addons found in the '.deva' folder");
115
- return Ok(());
116
- }
117
-
118
- if !banks_found.is_empty() {
119
- let mut bank_traces: Vec<String> = Vec::new();
120
-
121
- for addon in &banks_found {
122
- bank_traces.push(addon.name.to_string());
123
- }
124
-
125
- let trace_refs: Vec<&str> = bank_traces.iter().map(|s| s.as_str()).collect();
126
-
127
- logger.log_message_with_trace(
128
- LogLevel::Info,
129
- format!("Found {} compiled banks in workspace", banks_found.len()).as_str(),
130
- trace_refs,
131
- );
132
- }
133
-
134
- if !plugins_found.is_empty() {
135
- let mut plugin_traces: Vec<String> = Vec::new();
136
-
137
- for addon in &plugins_found {
138
- plugin_traces.push(addon.name.to_string());
139
- }
140
-
141
- let trace_refs: Vec<&str> = plugin_traces.iter().map(|s| s.as_str()).collect();
142
-
143
- logger.log_message_with_trace(
144
- LogLevel::Info,
145
- format!(
146
- "Found {} compiled plugins in workspace",
147
- plugins_found.len()
148
- )
149
- .as_str(),
150
- trace_refs,
151
- );
152
- }
153
-
154
- if !presets_found.is_empty() {
155
- let mut preset_traces: Vec<String> = Vec::new();
156
-
157
- for addon in &presets_found {
158
- preset_traces.push(addon.name.to_string());
159
- }
160
-
161
- let trace_refs: Vec<&str> = preset_traces.iter().map(|s| s.as_str()).collect();
162
-
163
- logger.log_message_with_trace(
164
- LogLevel::Info,
165
- format!(
166
- "Found {} compiled presets in workspace",
167
- presets_found.len()
168
- )
169
- .as_str(),
170
- trace_refs,
171
- );
172
- }
173
-
174
- if !templates_found.is_empty() {
175
- let mut template_traces: Vec<String> = Vec::new();
176
-
177
- for addon in &templates_found {
178
- template_traces.push(addon.name.to_string());
179
- }
180
-
181
- let trace_refs: Vec<&str> = template_traces.iter().map(|s| s.as_str()).collect();
182
-
183
- logger.log_message_with_trace(
184
- LogLevel::Info,
185
- format!(
186
- "Found {} compiled templates in workspace",
187
- templates_found.len()
188
- )
189
- .as_str(),
190
- trace_refs,
191
- );
192
- }
193
-
194
- println!();
195
-
196
- // Build user-friendly, unique labels tied to each addon by including the path
197
- let choice_labels: Vec<String> = all_addons
198
- .iter()
199
- .map(|addon| {
200
- format!(
201
- "{}: {} ({})",
202
- addon.addon_type,
203
- addon.name,
204
- addon.path.display()
205
- )
206
- })
207
- .collect();
208
-
209
- let selected_addons = match inquire::MultiSelect::new(
210
- "Select addons to install:",
211
- choice_labels.clone(),
212
- )
213
- .prompt()
214
- {
215
- Ok(selected_addons) => selected_addons,
216
- Err(err) => {
217
- logger.log_message(
218
- LogLevel::Error,
219
- format!("Error selecting addons: {}", err).as_str(),
220
- );
221
-
222
- return Err(format!("Error selecting addons: {}", err));
223
- }
224
- };
225
-
226
- let spinner = start_spinner("Installing addons...");
227
-
228
- let addons_to_install = selected_addons
229
- .iter()
230
- .filter_map(|label| {
231
- all_addons.iter().find(|addon| {
232
- let candidate = format!(
233
- "{}: {} ({})",
234
- addon.addon_type,
235
- addon.name,
236
- addon.path.display()
237
- );
238
- &candidate == label
239
- })
240
- })
241
- .cloned()
242
- .collect::<Vec<_>>();
243
-
244
- let install_selected_addons_result =
245
- install_selected_addons(addons_to_install, no_clear_tmp).await;
246
- match install_selected_addons_result {
247
- Ok(addons_enriched) => {
248
- if let Err(e) = add_addons_to_config(addons_enriched).await {
249
- spinner.finish_and_clear();
250
- logger.log_message(
251
- LogLevel::Error,
252
- format!("Failed to add addons to config: {}", e).as_str(),
253
- );
254
- return Err(format!("Failed to add addons to config: {}", e));
255
- }
256
-
257
- spinner.finish_and_clear();
258
- println!();
259
- logger.log_message(
260
- LogLevel::Success,
261
- "Successfully installed addons !".to_string().as_str(),
262
- );
263
- }
264
- Err(e) => {
265
- spinner.finish_and_clear();
266
- logger.log_message(
267
- LogLevel::Error,
268
- format!("Failed to install addons: {}", e).as_str(),
269
- );
270
- return Err(format!("Failed to install addons: {}", e));
271
- }
272
- }
273
-
274
- Ok(())
275
- }
@@ -1,109 +0,0 @@
1
- use devalang_core::config::driver::ProjectConfigExt;
2
- use devalang_types::{AddonWithMetadata, ProjectConfigBankEntry, ProjectConfigPluginEntry};
3
- use devalang_utils::path as path_utils;
4
-
5
- pub async fn add_addons_to_config(addons: Vec<AddonWithMetadata>) -> Result<(), String> {
6
- let config_path = path_utils::get_devalang_config_path()?;
7
- let mut config = crate::config::ops::load_config(Some(&config_path))
8
- .ok_or_else(|| format!("Failed to load config from '{}'", config_path.display()))?;
9
-
10
- for addon in addons {
11
- let addon_path_as_devalang_protocol = format!(
12
- "devalang://{}/{}/{}",
13
- addon.addon_type, addon.metadata.publisher, addon.metadata.name
14
- );
15
-
16
- match addon.addon_type.as_str() {
17
- "bank" => {
18
- if config.banks.is_none() {
19
- config.banks = Some(Vec::new());
20
- }
21
-
22
- let banks = config.banks.as_mut().unwrap();
23
-
24
- let exists = banks
25
- .iter()
26
- .any(|b| b.path == addon_path_as_devalang_protocol);
27
- if exists {
28
- println!("Bank '{}' already in config", addon.name);
29
- continue;
30
- }
31
-
32
- banks.push(ProjectConfigBankEntry {
33
- path: addon_path_as_devalang_protocol,
34
- });
35
- }
36
-
37
- "plugin" => {
38
- if config.plugins.is_none() {
39
- config.plugins = Some(Vec::new());
40
- }
41
-
42
- let plugins = config.plugins.as_mut().unwrap();
43
-
44
- let exists = plugins
45
- .iter()
46
- .any(|p| p.path == addon_path_as_devalang_protocol);
47
- if exists {
48
- println!("Plugin '{}' already in config", addon.name);
49
- continue;
50
- }
51
-
52
- plugins.push(ProjectConfigPluginEntry {
53
- path: addon_path_as_devalang_protocol,
54
- });
55
- }
56
-
57
- // "preset" => {
58
- // if config.presets.is_none() {
59
- // config.presets = Some(Vec::new());
60
- // }
61
-
62
- // let presets = config.presets.as_mut().unwrap();
63
-
64
- // let exists = presets.iter().any(|p| p.path == addon_path_as_deva_protocol);
65
- // if exists {
66
- // println!("Preset '{}' already in config", addon.name);
67
- // continue;
68
- // }
69
-
70
- // presets.push(ProjectConfigPresetEntry {
71
- // path: addon_path_as_deva_protocol,
72
- // version: Some(addon.metadata.version.clone()),
73
- // });
74
- // }
75
-
76
- // "template" => {
77
- // if config.templates.is_none() {
78
- // config.templates = Some(Vec::new());
79
- // }
80
-
81
- // let templates = config.templates.as_mut().unwrap();
82
-
83
- // let exists = templates.iter().any(|t| t.path == addon_path_as_deva_protocol);
84
- // if exists {
85
- // println!("Template '{}' already in config", addon.name);
86
- // continue;
87
- // }
88
-
89
- // templates.push(ProjectConfigTemplateEntry {
90
- // path: addon_path_as_deva_protocol,
91
- // version: Some(addon.metadata.version.clone()),
92
- // });
93
- // }
94
- _ => {
95
- println!(
96
- "Unknown addon type '{}' for addon '{}'",
97
- addon.addon_type, addon.name
98
- );
99
- }
100
- }
101
- }
102
-
103
- // Update config with new addons
104
- if let Err(e) = config.write_config(&config) {
105
- return Err(format!("Failed to write config: {}", e));
106
- }
107
-
108
- Ok(())
109
- }
@@ -1,19 +0,0 @@
1
- use std::{fs, io, path::Path};
2
-
3
- pub fn copy_dir_all(src: &Path, dst: &Path) -> Result<(), io::Error> {
4
- if !dst.exists() {
5
- fs::create_dir_all(dst)?;
6
- }
7
- for entry in fs::read_dir(src)? {
8
- let entry = entry?;
9
- let ty = entry.file_type()?;
10
- let from = entry.path();
11
- let to = dst.join(entry.file_name());
12
- if ty.is_dir() {
13
- copy_dir_all(&from, &to)?;
14
- } else {
15
- fs::copy(&from, &to)?;
16
- }
17
- }
18
- Ok(())
19
- }
@@ -1,214 +0,0 @@
1
- use devalang_types::{AddonMetadata, AddonWithMetadata, DiscoveredAddon};
2
- use devalang_utils::path as path_utils;
3
-
4
- pub async fn install_selected_addons(
5
- addons: Vec<DiscoveredAddon>,
6
- no_clear_tmp: bool,
7
- ) -> Result<Vec<AddonWithMetadata>, String> {
8
- let mut addons_enriched = Vec::new();
9
-
10
- let tmp_dir = path_utils::ensure_deva_dir()?.join("tmp");
11
-
12
- for addon in addons {
13
- std::fs::create_dir_all(tmp_dir.join(&addon.name))
14
- .map_err(|e| format!("Failed to create directory for addon {}: {}", addon.name, e))?;
15
-
16
- let addon_path = tmp_dir.join(&addon.name);
17
- devalang_utils::file::extract_zip_safely(&addon.path, &addon_path)
18
- .map_err(|e| format!("Failed to extract addon {}: {}", addon.name, e))?;
19
-
20
- // Read metadata from the extracted addon first so we can layout as <publisher>/<name>
21
- // If the addon type is unknown (we found a .tar.gz), try to detect the
22
- // metadata file inside the extracted folder to discover the real type.
23
- let mut detected_addon_type = addon.addon_type.clone();
24
- let mut parsed_meta_tmp = None;
25
-
26
- if detected_addon_type == "unknown" {
27
- // try detection by checking common metadata filenames
28
- let candidates = ["bank.toml", "plugin.toml", "preset.toml", "template.toml"];
29
- for candidate in &candidates {
30
- let path = addon_path.join(candidate);
31
- if path.exists() {
32
- detected_addon_type = match *candidate {
33
- "bank.toml" => "bank".to_string(),
34
- "plugin.toml" => "plugin".to_string(),
35
- "preset.toml" => "preset".to_string(),
36
- "template.toml" => "template".to_string(),
37
- _ => "unknown".to_string(),
38
- };
39
- if let Ok(content) = std::fs::read_to_string(&path) {
40
- parsed_meta_tmp = crate::cli::discover::metadata::parse_metadata_file(
41
- &detected_addon_type,
42
- &content,
43
- );
44
- }
45
- break;
46
- }
47
- }
48
- } else {
49
- let addon_metadata_filename = match addon.addon_type.as_str() {
50
- "bank" => "bank.toml",
51
- "plugin" => "plugin.toml",
52
- "preset" => "preset.toml",
53
- "template" => "template.toml",
54
- _ => "",
55
- };
56
- if !addon_metadata_filename.is_empty() {
57
- let addon_metadata_path_tmp = addon_path.join(addon_metadata_filename);
58
- let addon_metadata_content_tmp =
59
- std::fs::read_to_string(&addon_metadata_path_tmp).ok();
60
- if let Some(content) = addon_metadata_content_tmp {
61
- parsed_meta_tmp = crate::cli::discover::metadata::parse_metadata_file(
62
- &addon.addon_type,
63
- &content,
64
- );
65
- }
66
- }
67
- }
68
-
69
- let base = path_utils::ensure_deva_dir()?;
70
- // Use detected_addon_type (may have been found from metadata)
71
- // final_addon_type is what we will report and use for metadata lookup
72
- let final_addon_type = if detected_addon_type == "unknown" {
73
- addon.addon_type.clone()
74
- } else {
75
- detected_addon_type.clone()
76
- };
77
-
78
- let target_addon_dir = match final_addon_type.as_str() {
79
- "bank" => base.join("banks"),
80
- "plugin" => base.join("plugins"),
81
- "preset" => base.join("presets"),
82
- "template" => base.join("templates"),
83
- _ => {
84
- // Fallback: place unknown archives into plugins by default
85
- base.join("plugins")
86
- }
87
- };
88
-
89
- std::fs::create_dir_all(&target_addon_dir).map_err(|e| {
90
- format!(
91
- "Failed to create target directory for addon {}: {}",
92
- addon.name, e
93
- )
94
- })?;
95
-
96
- // prefer parsed metadata publisher/name, fall back to discovered publisher/name
97
- let publisher_folder = parsed_meta_tmp
98
- .as_ref()
99
- .and_then(|m| {
100
- if !m.publisher.is_empty() {
101
- Some(m.publisher.clone())
102
- } else {
103
- None
104
- }
105
- })
106
- .unwrap_or_else(|| addon.publisher.clone());
107
-
108
- let name_folder = parsed_meta_tmp
109
- .as_ref()
110
- .and_then(|m| {
111
- if !m.name.is_empty() {
112
- Some(m.name.clone())
113
- } else {
114
- None
115
- }
116
- })
117
- .unwrap_or_else(|| addon.name.clone());
118
-
119
- let target_addon_path_dir = target_addon_dir.join(&publisher_folder).join(&name_folder);
120
- if target_addon_path_dir.exists() {
121
- println!(
122
- "Target addon directory {} already exists",
123
- target_addon_path_dir.display()
124
- );
125
- continue;
126
- }
127
-
128
- if let Err(e) = std::fs::rename(&addon_path, &target_addon_path_dir) {
129
- crate::cli::discover::fs::copy_dir_all(&addon_path, &target_addon_path_dir).map_err(
130
- |err| {
131
- format!(
132
- "Failed to move addon {}: {} (rename error: {})",
133
- addon.name, err, e
134
- )
135
- },
136
- )?;
137
- let _ = std::fs::remove_dir_all(&addon_path);
138
- }
139
- // Attempt to read final metadata file (use parsed_tmp as fallback)
140
- let addon_metadata_filename = match final_addon_type.as_str() {
141
- "bank" => "bank.toml",
142
- "plugin" => "plugin.toml",
143
- "preset" => "preset.toml",
144
- "template" => "template.toml",
145
- _ => "",
146
- };
147
-
148
- let parsed_meta = if addon_metadata_filename.is_empty() {
149
- parsed_meta_tmp.unwrap_or(AddonMetadata {
150
- name: "".to_string(),
151
- publisher: "".to_string(),
152
- version: "".to_string(),
153
- description: "".to_string(),
154
- access: "".to_string(),
155
- })
156
- } else {
157
- let addon_metadata_path = target_addon_path_dir.join(addon_metadata_filename);
158
- if let Ok(content) = std::fs::read_to_string(&addon_metadata_path) {
159
- crate::cli::discover::metadata::parse_metadata_file(&final_addon_type, &content)
160
- .unwrap_or(parsed_meta_tmp.unwrap_or(AddonMetadata {
161
- name: "".to_string(),
162
- publisher: "".to_string(),
163
- version: "".to_string(),
164
- description: "".to_string(),
165
- access: "".to_string(),
166
- }))
167
- } else {
168
- parsed_meta_tmp.unwrap_or(AddonMetadata {
169
- name: "".to_string(),
170
- publisher: "".to_string(),
171
- version: "".to_string(),
172
- description: "".to_string(),
173
- access: "".to_string(),
174
- })
175
- }
176
- };
177
-
178
- // Record location as the final moved directory path
179
- addons_enriched.push(AddonWithMetadata {
180
- name: name_folder.clone(),
181
- publisher: publisher_folder.clone(),
182
- path: target_addon_path_dir.clone().to_string_lossy().to_string(),
183
- addon_type: final_addon_type.clone(),
184
- metadata: parsed_meta,
185
- });
186
-
187
- if let Err(e) = std::fs::remove_file(&addon.path) {
188
- eprintln!(
189
- "Failed to remove zipped file for addon {}: {}",
190
- addon.name, e
191
- );
192
- }
193
- }
194
-
195
- // Best-effort cleanup of temporary extraction directory: remove `.deva/tmp`
196
- // only if it's empty after installing the selected addons and when the
197
- // user did not pass --no-clear-tmp.
198
- if !no_clear_tmp {
199
- if tmp_dir.exists() {
200
- match std::fs::read_dir(&tmp_dir) {
201
- Ok(mut rd) => {
202
- if rd.next().is_none() {
203
- let _ = std::fs::remove_dir_all(&tmp_dir);
204
- }
205
- }
206
- Err(_) => {
207
- // ignore errors here - best-effort
208
- }
209
- }
210
- }
211
- }
212
-
213
- Ok(addons_enriched)
214
- }
@@ -1,48 +0,0 @@
1
- use devalang_types::AddonMetadata;
2
- use toml::Value;
3
-
4
- pub fn parse_metadata_file(addon_type: &str, metadata_content: &str) -> Option<AddonMetadata> {
5
- let parsed = metadata_content.parse::<Value>().ok()?;
6
-
7
- let table = (match addon_type {
8
- "bank" => parsed.get("bank"),
9
- "plugin" => parsed.get("plugin"),
10
- "preset" => parsed.get("preset"),
11
- "template" => parsed.get("template"),
12
- _ => None,
13
- })?;
14
-
15
- let name = table
16
- .get("name")
17
- .and_then(|v| v.as_str())
18
- .unwrap_or("")
19
- .to_string();
20
- let version = table
21
- .get("version")
22
- .and_then(|v| v.as_str())
23
- .unwrap_or("")
24
- .to_string();
25
- let description = table
26
- .get("description")
27
- .and_then(|v| v.as_str())
28
- .unwrap_or("")
29
- .to_string();
30
- let publisher = table
31
- .get("publisher")
32
- .and_then(|v| v.as_str())
33
- .unwrap_or("unknown")
34
- .to_string();
35
- let access = table
36
- .get("access")
37
- .and_then(|v| v.as_str())
38
- .unwrap_or("")
39
- .to_string();
40
-
41
- Some(AddonMetadata {
42
- name,
43
- publisher,
44
- version,
45
- description,
46
- access,
47
- })
48
- }
@@ -1,5 +0,0 @@
1
- pub mod commands;
2
- pub mod config;
3
- pub mod fs;
4
- pub mod install;
5
- pub mod metadata;