@ionyx-apps/cli 0.2.0 → 0.3.0

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 (35) hide show
  1. package/bin/ionyx.exe +0 -0
  2. package/ionyx-cli/Cargo.toml +40 -0
  3. package/ionyx-cli/src/commands/build.rs +53 -0
  4. package/ionyx-cli/src/commands/bundle.rs +349 -0
  5. package/ionyx-cli/src/commands/config.rs +36 -0
  6. package/ionyx-cli/src/commands/dev.rs +142 -0
  7. package/ionyx-cli/src/commands/doctor.rs +158 -0
  8. package/ionyx-cli/src/commands/info.rs +79 -0
  9. package/ionyx-cli/src/commands/init.rs +64 -0
  10. package/ionyx-cli/src/commands/mod.rs +9 -0
  11. package/ionyx-cli/src/commands/plugin.rs +34 -0
  12. package/ionyx-cli/src/commands/run.rs +54 -0
  13. package/ionyx-cli/src/config/mod.rs +155 -0
  14. package/ionyx-cli/src/main.rs +161 -0
  15. package/ionyx-cli/src/templates/basic/src-ionyx/Cargo.toml +6 -0
  16. package/ionyx-cli/src/templates/basic/src-ionyx/src/lib.rs +6 -0
  17. package/ionyx-cli/src/templates/basic/src-ionyx/src/protocol.rs +20 -2
  18. package/ionyx-cli/src/templates/leptos/src-ionyx/src/protocol.rs +20 -2
  19. package/ionyx-cli/src/templates/mod.rs +2 -2
  20. package/ionyx-cli/src/templates/react/src-ionyx/Cargo.toml +6 -0
  21. package/ionyx-cli/src/templates/react/src-ionyx/src/lib.rs +6 -0
  22. package/ionyx-cli/src/templates/react/src-ionyx/src/protocol.rs +20 -2
  23. package/ionyx-cli/src/templates/svelte/src-ionyx/Cargo.toml +6 -0
  24. package/ionyx-cli/src/templates/svelte/src-ionyx/src/lib.rs +6 -0
  25. package/ionyx-cli/src/templates/svelte/src-ionyx/src/protocol.rs +20 -2
  26. package/ionyx-cli/src/templates/vanilla/src-ionyx/Cargo.toml +6 -0
  27. package/ionyx-cli/src/templates/vanilla/src-ionyx/src/lib.rs +6 -0
  28. package/ionyx-cli/src/templates/vanilla/src-ionyx/src/protocol.rs +20 -2
  29. package/ionyx-cli/src/templates/vue/src-ionyx/Cargo.toml +6 -0
  30. package/ionyx-cli/src/templates/vue/src-ionyx/src/lib.rs +6 -0
  31. package/ionyx-cli/src/templates/vue/src-ionyx/src/protocol.rs +2 -2
  32. package/package.json +11 -4
  33. package/bin/cargo-ionyx-win.exe +0 -0
  34. package/bin/cargo-ionyx.exe +0 -0
  35. package/ionyx-cli/src/templates/react/src-ionyx/Cargo.lock +0 -5536
@@ -0,0 +1,158 @@
1
+ use anyhow::Result;
2
+ use colored::*;
3
+ use std::process::Command;
4
+ use std::path::Path;
5
+
6
+ pub async fn execute() -> Result<()> {
7
+ println!("\n{}", "⚕️ Ionyx Doctor - Diagnostic Report".bold().bright_blue());
8
+ println!("{}", "=====================================".bright_blue());
9
+
10
+ let mut issues = 0;
11
+ let mut warnings = 0;
12
+
13
+ // 1. Operating System
14
+ print_check("Operating System", true, "");
15
+ let info = os_info::get();
16
+ println!(" {} {} {} {}", info.os_type(), info.version(), info.bitness(), info.architecture().unwrap_or(""));
17
+
18
+ // 2. Rust Environment
19
+ println!("\n{}", "🦀 Rust Environment".bold());
20
+ let rustc = check_version("rustc", &["--version"]);
21
+ let cargo = check_version("cargo", &["--version"]);
22
+
23
+ match (rustc.as_ref(), cargo.as_ref()) {
24
+ (Some(r), Some(c)) => {
25
+ print_check("Rust/Cargo", true, "Detected");
26
+ println!(" rustc: {}", r);
27
+ println!(" cargo: {}", c);
28
+ }
29
+ _ => {
30
+ if rustc.is_none() { print_check("rustc", false, "Not found"); }
31
+ if cargo.is_none() { print_check("cargo", false, "Not found"); }
32
+ println!(" {} Please install Rust from https://rustup.rs", "!".yellow());
33
+ issues += 1;
34
+ }
35
+ }
36
+
37
+ // 3. Node Environment
38
+ println!("\n{}", "🟢 Node.js Environment".bold());
39
+ let node = check_version("node", &["--version"]);
40
+ let npm = check_version("npm", &["--version"]);
41
+
42
+ match (node.as_ref(), npm.as_ref()) {
43
+ (Some(n), Some(m)) => {
44
+ print_check("Node/NPM", true, "Detected");
45
+ println!(" node: {}", n);
46
+ println!(" npm: {}", m);
47
+ }
48
+ _ => {
49
+ if node.is_none() { print_check("node", false, "Not found"); }
50
+ if npm.is_none() { print_check("npm", false, "Not found (Ensure it's in your PATH)"); }
51
+ println!(" {} Please install Node.js from https://nodejs.org", "!".yellow());
52
+ issues += 1;
53
+ }
54
+ }
55
+
56
+ // 4. Bundling Tools
57
+ println!("\n{}", "📦 Bundling Tools".bold());
58
+
59
+ #[cfg(target_os = "windows")]
60
+ {
61
+ // NSIS
62
+ if let Some(v) = check_version("makensis", &["/VERSION"]) {
63
+ print_check("NSIS (for EXE)", true, &format!("Version {}", v));
64
+ } else {
65
+ print_warning("NSIS (for EXE)", "Not found. Required for building .exe installers. Install from https://nsis.sourceforge.io");
66
+ warnings += 1;
67
+ }
68
+
69
+ // WiX
70
+ if let Some(_) = check_version("candle", &["-?"]) {
71
+ print_check("WiX Toolset (for MSI)", true, "Detected");
72
+ } else {
73
+ print_warning("WiX Toolset (for MSI)", "Not found. Required for building .msi installers. Install from https://wixtoolset.org");
74
+ warnings += 1;
75
+ }
76
+ }
77
+
78
+ #[cfg(target_os = "macos")]
79
+ {
80
+ if let Some(_) = check_version("hdiutil", &["help"]) {
81
+ print_check("hdiutil (for DMG)", true, "Detected");
82
+ } else {
83
+ print_warning("hdiutil (for DMG)", "Not found. Required for building .dmg installers.");
84
+ warnings += 1;
85
+ }
86
+ }
87
+
88
+ #[cfg(target_os = "linux")]
89
+ {
90
+ if let Some(_) = check_version("appimagetool", &["--version"]) {
91
+ print_check("appimagetool (for AppImage)", true, "Detected");
92
+ } else {
93
+ print_warning("appimagetool (for AppImage)", "Not found. Required for building .AppImage. Install from https://appimage.org");
94
+ warnings += 1;
95
+ }
96
+ }
97
+
98
+ // 5. Project Context
99
+ println!("\n{}", "🏠 Project Context".bold());
100
+ if Path::new("ionyx.config.json").exists() || Path::new("ionyx.config.toml").exists() {
101
+ print_check("Ionyx Project", true, "You are inside an Ionyx project directory.");
102
+ } else {
103
+ println!(" {} {}", "!".yellow(), "You are NOT in an Ionyx project directory. Some commands like 'build' or 'dev' will not work.");
104
+ }
105
+
106
+ // Summary
107
+ println!("\n{}", "Summary".bold());
108
+ if issues == 0 && warnings == 0 {
109
+ println!(" {} No issues found! Your environment is perfectly configured for Ionyx. 🚀", "✓".green());
110
+ } else {
111
+ if issues > 0 {
112
+ println!(" {} Found {} critical issue(s). Review the report above for fixes.", "✗".red(), issues);
113
+ }
114
+ if warnings > 0 {
115
+ println!(" {} Found {} warning(s). You can still develop, but some features (like bundling) might be limited.", "!".yellow(), warnings);
116
+ }
117
+ }
118
+
119
+ println!();
120
+ Ok(())
121
+ }
122
+
123
+ fn print_check(title: &str, success: bool, msg: &str) {
124
+ if success {
125
+ println!(" {} {}: {}", "✓".green(), title.bold(), msg.dimmed());
126
+ } else {
127
+ println!(" {} {}: {}", "✗".red(), title.bold(), msg.bright_red());
128
+ }
129
+ }
130
+
131
+ fn print_warning(title: &str, msg: &str) {
132
+ println!(" {} {}: {}", "!".yellow(), title.bold(), msg.yellow());
133
+ }
134
+
135
+ fn check_version(cmd: &str, args: &[&str]) -> Option<String> {
136
+ // Platform specific variations
137
+ let cmd_variations = if cfg!(target_os = "windows") {
138
+ match cmd {
139
+ "npm" => vec!["npm.cmd", "npm"],
140
+ "makensis" => vec!["makensis.exe", "makensis"],
141
+ "candle" => vec!["candle.exe", "candle"],
142
+ _ => vec![cmd],
143
+ }
144
+ } else {
145
+ vec![cmd]
146
+ };
147
+
148
+ for c in cmd_variations {
149
+ match Command::new(c).args(args).output() {
150
+ Ok(output) if output.status.success() => {
151
+ let out = String::from_utf8_lossy(&output.stdout).trim().to_string();
152
+ return Some(out.lines().next().unwrap_or("").trim().to_string());
153
+ }
154
+ _ => continue,
155
+ }
156
+ }
157
+ None
158
+ }
@@ -0,0 +1,79 @@
1
+ use anyhow::Result;
2
+ use colored::*;
3
+ use std::process::Command;
4
+
5
+ pub async fn execute() -> Result<()> {
6
+ println!("\n{}", "Ionyx Environment".bold().bright_blue());
7
+
8
+ println!("\n{}", "Operating System".bold());
9
+ let info = os_info::get();
10
+ println!(" {}: {} {} {}",
11
+ "OS".green(),
12
+ info.os_type(),
13
+ info.version(),
14
+ info.bitness()
15
+ );
16
+
17
+ // Get Rust version
18
+ println!("\n{}", "Rust Environment".bold());
19
+ let mut rustc_cmd = Command::new("rustc");
20
+ rustc_cmd.arg("--version");
21
+
22
+ match rustc_cmd.output() {
23
+ Ok(output) if output.status.success() => {
24
+ let version = String::from_utf8_lossy(&output.stdout);
25
+ println!(" {}: {}", "rustc".green(), version.trim());
26
+ }
27
+ _ => {
28
+ println!(" {}: {}", "rustc".red(), "Not installed or not in PATH");
29
+ }
30
+ }
31
+
32
+ let mut cargo_cmd = Command::new("cargo");
33
+ cargo_cmd.arg("--version");
34
+
35
+ match cargo_cmd.output() {
36
+ Ok(output) if output.status.success() => {
37
+ let version = String::from_utf8_lossy(&output.stdout);
38
+ println!(" {}: {}", "cargo".green(), version.trim());
39
+ }
40
+ _ => {
41
+ println!(" {}: {}", "cargo".red(), "Not installed or not in PATH");
42
+ }
43
+ }
44
+
45
+ // Node environment
46
+ println!("\n{}", "Node Environment".bold());
47
+ let mut node_cmd = Command::new("node");
48
+ node_cmd.arg("--version");
49
+
50
+ match node_cmd.output() {
51
+ Ok(output) if output.status.success() => {
52
+ let version = String::from_utf8_lossy(&output.stdout);
53
+ println!(" {}: {}", "node".green(), version.trim());
54
+ }
55
+ _ => {
56
+ println!(" {}: {}", "node".red(), "Not installed or not in PATH");
57
+ }
58
+ }
59
+
60
+ let mut npm_cmd = Command::new("npm");
61
+ npm_cmd.arg("--version");
62
+
63
+ match npm_cmd.output() {
64
+ Ok(output) if output.status.success() => {
65
+ let version = String::from_utf8_lossy(&output.stdout);
66
+ println!(" {}: {}", "npm".green(), version.trim());
67
+ }
68
+ _ => {
69
+ println!(" {}: {}", "npm".red(), "Not installed or not in PATH");
70
+ }
71
+ }
72
+
73
+ // CLI version
74
+ println!("\n{}", "Ionyx Framework".bold());
75
+ println!(" {}: {}", "ionyx-cli".green(), env!("CARGO_PKG_VERSION"));
76
+
77
+ println!();
78
+ Ok(())
79
+ }
@@ -0,0 +1,64 @@
1
+ use anyhow::Result;
2
+ use colored::*;
3
+ use crate::templates;
4
+ use std::fs;
5
+ use std::path::Path;
6
+
7
+ pub async fn execute(mut name: String, template: &str) -> Result<()> {
8
+ let mut dest_path = name.clone();
9
+
10
+ // Handle current directory initialization
11
+ if name == "." || name == "./" {
12
+ name = std::env::current_dir()?
13
+ .file_name()
14
+ .and_then(|n| n.to_str())
15
+ .unwrap_or("my-ionyx-app")
16
+ .to_string();
17
+ dest_path = ".".to_string();
18
+ println!("🚀 Initializing in current directory: {}", name.green());
19
+ } else {
20
+ println!("🚀 Creating new Ionyx project: {}", name.green());
21
+
22
+ // Check if directory already exists
23
+ if Path::new(&dest_path).exists() {
24
+ return Err(anyhow::anyhow!("Directory '{}' already exists", dest_path));
25
+ }
26
+
27
+ // Create project directory
28
+ fs::create_dir_all(&dest_path)?;
29
+ println!("✅ Created directory: {}", dest_path);
30
+ }
31
+
32
+ // Show template info
33
+ println!("📋 Template: {}", template.cyan());
34
+
35
+ // Copy template files
36
+ templates::copy_template(&name, &dest_path, template).await?;
37
+
38
+ // Show next steps
39
+ println!("\n✅ Project '{}' created successfully!", name.green());
40
+ println!("\n📋 Next steps:");
41
+ println!(" cd {}", name);
42
+ println!(" npm run ionyx:dev");
43
+
44
+ // Show framework-specific info
45
+ match template {
46
+ "react" => println!("\n🎯 React + TypeScript + Vite setup ready!"),
47
+ "svelte" => println!("\n🎯 Svelte + TypeScript + Vite setup ready!"),
48
+ "vue" => println!("\n🎯 Vue + TypeScript + Vite setup ready!"),
49
+ "leptos" => println!("\n🎯 Rust + Leptos (WASM) setup ready!"),
50
+ "angular" => println!("\n🎯 Angular + TypeScript + Vite setup ready!"),
51
+ "vanilla" => println!("\n🎯 Vanilla JavaScript + Vite setup ready!"),
52
+ _ => println!("\n🎯 Basic Ionyx setup ready!"),
53
+ }
54
+
55
+ println!("\n🚀 Available commands:");
56
+ println!(" npm run ionyx:dev # Start Ionyx application");
57
+ println!(" npm run ionyx:build # Build for production");
58
+ println!(" npm run dev # Frontend only");
59
+ println!(" npm run build # Frontend build only");
60
+
61
+ println!("\n🎉 Happy coding with Ionyx Framework!");
62
+
63
+ Ok(())
64
+ }
@@ -0,0 +1,9 @@
1
+ pub mod build;
2
+ pub mod bundle;
3
+ pub mod config;
4
+ pub mod dev;
5
+ pub mod doctor;
6
+ pub mod info;
7
+ pub mod init;
8
+ pub mod plugin;
9
+ pub mod run;
@@ -0,0 +1,34 @@
1
+ use anyhow::Result;
2
+ use colored::*;
3
+ use std::fs;
4
+ use std::path::Path;
5
+
6
+ pub async fn execute(action: crate::PluginAction) -> Result<()> {
7
+ match action {
8
+ crate::PluginAction::Install { name } => {
9
+ println!("📦 Installing plugin: {}", name.cyan());
10
+
11
+ // Here you would implement plugin installation logic
12
+ // For now, just show a message
13
+ println!("⚠️ Plugin installation not implemented yet");
14
+ }
15
+ crate::PluginAction::Uninstall { name } => {
16
+ println!("🗑️ Uninstalling plugin: {}", name.cyan());
17
+
18
+ // Here you would implement plugin uninstallation logic
19
+ println!("⚠️ Plugin uninstallation not implemented yet");
20
+ }
21
+ crate::PluginAction::List => {
22
+ println!("📦 Installed plugins:");
23
+ println!("⚠️ Plugin system not implemented yet");
24
+ }
25
+ crate::PluginAction::Update { name } => {
26
+ println!("🔄 Updating plugin: {}", name.cyan());
27
+
28
+ // Here you would implement plugin update logic
29
+ println!("⚠️ Plugin update not implemented yet");
30
+ }
31
+ }
32
+
33
+ Ok(())
34
+ }
@@ -0,0 +1,54 @@
1
+ use anyhow::Result;
2
+ use colored::*;
3
+ use std::process::Command;
4
+ use std::path::Path;
5
+
6
+ pub async fn execute(port: u16) -> Result<()> {
7
+ println!("🚀 Running Ionyx application on port {}", port.to_string().cyan());
8
+
9
+ if !Path::new("package.json").exists() {
10
+ return Err(anyhow::anyhow!("No package.json found. Please run this command in an Ionyx project directory."));
11
+ }
12
+
13
+ // Check if node_modules exists, if not, install dependencies
14
+ if !Path::new("node_modules").exists() {
15
+ println!("📦 Installing dependencies...");
16
+ let output = Command::new("npm")
17
+ .arg("install")
18
+ .output()
19
+ .expect("Failed to run npm install");
20
+
21
+ println!("{}", String::from_utf8_lossy(&output.stdout));
22
+ }
23
+
24
+ // Check if build exists, if not, build first
25
+ if !Path::new("dist").exists() {
26
+ println!("📦 No build found, building first...");
27
+ let output = Command::new("npm")
28
+ .arg("run")
29
+ .arg("build")
30
+ .output()
31
+ .expect("Failed to run build command");
32
+
33
+ println!("{}", String::from_utf8_lossy(&output.stdout));
34
+ }
35
+
36
+ // Run application
37
+ let mut cmd = Command::new("npm");
38
+ cmd.arg("run").arg("start");
39
+
40
+ // Set port if different from default
41
+ if port != 5173 {
42
+ cmd.env("PORT", port.to_string());
43
+ }
44
+
45
+ println!("🌐 Application started at: http://localhost:{}", port);
46
+
47
+ let status = cmd.status()?;
48
+
49
+ if !status.success() {
50
+ return Err(anyhow::anyhow!("Application failed to start"));
51
+ }
52
+
53
+ Ok(())
54
+ }
@@ -0,0 +1,155 @@
1
+ use serde::{Deserialize, Serialize};
2
+ use std::fs;
3
+ use std::path::Path;
4
+
5
+ #[derive(Debug, Clone, Serialize, Deserialize)]
6
+ pub struct ProjectConfig {
7
+ pub name: String,
8
+ pub version: String,
9
+ pub description: String,
10
+ pub r#type: String,
11
+ pub src: String,
12
+ pub dist: String,
13
+ pub dev: DevConfig,
14
+ pub build: BuildConfig,
15
+ pub ionyx: IonyxConfig,
16
+ }
17
+
18
+ #[derive(Debug, Clone, Serialize, Deserialize)]
19
+ pub struct DevConfig {
20
+ pub port: u16,
21
+ pub hot: bool,
22
+ }
23
+
24
+ #[derive(Debug, Clone, Serialize, Deserialize)]
25
+ pub struct BuildConfig {
26
+ pub target: String,
27
+ pub assets: String,
28
+ pub minify: bool,
29
+ }
30
+
31
+ #[derive(Debug, Clone, Serialize, Deserialize)]
32
+ pub struct IonyxConfig {
33
+ pub permissions: Vec<String>,
34
+ pub security: SecurityConfig,
35
+ }
36
+
37
+ #[derive(Debug, Clone, Serialize, Deserialize)]
38
+ pub struct SecurityConfig {
39
+ pub allowed_paths: Vec<String>,
40
+ }
41
+
42
+ impl ProjectConfig {
43
+ pub fn load() -> Result<Self, anyhow::Error> {
44
+ let config_path = "ionyx.config.json";
45
+
46
+ if !Path::new(config_path).exists() {
47
+ return Ok(ProjectConfig::default());
48
+ }
49
+
50
+ let content = fs::read_to_string(config_path)?;
51
+ let config: ProjectConfig = serde_json::from_str(&content)?;
52
+ Ok(config)
53
+ }
54
+
55
+ pub fn save(&self) -> Result<(), anyhow::Error> {
56
+ let content = serde_json::to_string_pretty(self)?;
57
+ fs::write("ionyx.config.json", content)?;
58
+ Ok(())
59
+ }
60
+
61
+ pub fn reset() -> Result<(), anyhow::Error> {
62
+ let default_config = ProjectConfig::default();
63
+ default_config.save()
64
+ }
65
+
66
+ pub fn get(&self, key: &str) -> Option<String> {
67
+ match key {
68
+ "name" => Some(self.name.clone()),
69
+ "version" => Some(self.version.clone()),
70
+ "description" => Some(self.description.clone()),
71
+ "type" => Some(self.r#type.clone()),
72
+ "src" => Some(self.src.clone()),
73
+ "dist" => Some(self.dist.clone()),
74
+ "dev.port" => Some(self.dev.port.to_string()),
75
+ "dev.hot" => Some(self.dev.hot.to_string()),
76
+ "build.target" => Some(self.build.target.clone()),
77
+ "build.assets" => Some(self.build.assets.clone()),
78
+ "build.minify" => Some(self.build.minify.to_string()),
79
+ _ => None,
80
+ }
81
+ }
82
+
83
+ pub fn set(&mut self, key: &str, value: &str) {
84
+ match key {
85
+ "name" => self.name = value.to_string(),
86
+ "version" => self.version = value.to_string(),
87
+ "description" => self.description = value.to_string(),
88
+ "type" => self.r#type = value.to_string(),
89
+ "src" => self.src = value.to_string(),
90
+ "dist" => self.dist = value.to_string(),
91
+ "dev.port" => {
92
+ if let Ok(port) = value.parse() {
93
+ self.dev.port = port;
94
+ }
95
+ }
96
+ "dev.hot" => {
97
+ if let Ok(hot) = value.parse() {
98
+ self.dev.hot = hot;
99
+ }
100
+ }
101
+ "build.target" => self.build.target = value.to_string(),
102
+ "build.assets" => self.build.assets = value.to_string(),
103
+ "build.minify" => {
104
+ if let Ok(minify) = value.parse() {
105
+ self.build.minify = minify;
106
+ }
107
+ }
108
+ _ => {}
109
+ }
110
+ }
111
+
112
+ pub fn get_all(&self) -> Vec<(String, String)> {
113
+ vec![
114
+ ("name".to_string(), self.name.clone()),
115
+ ("version".to_string(), self.version.clone()),
116
+ ("description".to_string(), self.description.clone()),
117
+ ("type".to_string(), self.r#type.clone()),
118
+ ("src".to_string(), self.src.clone()),
119
+ ("dist".to_string(), self.dist.clone()),
120
+ ("dev.port".to_string(), self.dev.port.to_string()),
121
+ ("dev.hot".to_string(), self.dev.hot.to_string()),
122
+ ("build.target".to_string(), self.build.target.clone()),
123
+ ("build.assets".to_string(), self.build.assets.clone()),
124
+ ("build.minify".to_string(), self.build.minify.to_string()),
125
+ ]
126
+ }
127
+ }
128
+
129
+ impl Default for ProjectConfig {
130
+ fn default() -> Self {
131
+ Self {
132
+ name: "my-ionyx-app".to_string(),
133
+ version: "1.0.0".to_string(),
134
+ description: "Ionyx Framework Application".to_string(),
135
+ r#type: "app".to_string(),
136
+ src: "src".to_string(),
137
+ dist: "dist".to_string(),
138
+ dev: DevConfig {
139
+ port: 5173,
140
+ hot: true,
141
+ },
142
+ build: BuildConfig {
143
+ target: "web".to_string(),
144
+ assets: "dist".to_string(),
145
+ minify: false,
146
+ },
147
+ ionyx: IonyxConfig {
148
+ permissions: vec!["fs".to_string(), "network".to_string(), "os_info".to_string()],
149
+ security: SecurityConfig {
150
+ allowed_paths: vec!["./app-data".to_string()],
151
+ },
152
+ },
153
+ }
154
+ }
155
+ }