@ionyx-apps/cli 0.4.8 → 0.4.9
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/bin/ionyx.exe +0 -0
- package/ionyx-cli/src/templates/angular/src-ionyx/Cargo.toml +30 -0
- package/ionyx-cli/src/templates/angular/src-ionyx/build.rs +5 -0
- package/ionyx-cli/src/templates/angular/src-ionyx/main.rs +48 -0
- package/ionyx-cli/src/templates/angular/src-ionyx/src/lib.rs +267 -0
- package/ionyx-cli/src/templates/basic/ionyx.config.json +3 -0
- package/ionyx-cli/src/templates/basic/package.json +6 -1
- package/ionyx-cli/src/templates/basic/src-ionyx/Cargo.toml +14 -12
- package/ionyx-cli/src/templates/basic/src-ionyx/main.rs +46 -3
- package/ionyx-cli/src/templates/leptos/package.json +6 -1
- package/ionyx-cli/src/templates/leptos/src-ionyx/Cargo.toml +14 -8
- package/ionyx-cli/src/templates/leptos/src-ionyx/main.rs +46 -3
- package/ionyx-cli/src/templates/mod.rs +1 -5
- package/ionyx-cli/src/templates/react/ionyx.config.json +4 -1
- package/ionyx-cli/src/templates/react/package.json +6 -1
- package/ionyx-cli/src/templates/react/src-ionyx/Cargo.toml +14 -12
- package/ionyx-cli/src/templates/react/src-ionyx/main.rs +46 -3
- package/ionyx-cli/src/templates/src-ionyx/Cargo.toml +15 -5
- package/ionyx-cli/src/templates/src-ionyx/bridge.rs +380 -0
- package/ionyx-cli/src/templates/src-ionyx/fusion.rs +47 -0
- package/ionyx-cli/src/templates/src-ionyx/ionyx.js +100 -0
- package/ionyx-cli/src/templates/src-ionyx/ipc_bridge.rs +206 -0
- package/ionyx-cli/src/templates/src-ionyx/lib.rs +204 -114
- package/ionyx-cli/src/templates/src-ionyx/main.rs +268 -3
- package/ionyx-cli/src/templates/src-ionyx/protocol.rs +98 -0
- package/ionyx-cli/src/templates/src-ionyx/window.rs +13 -0
- package/ionyx-cli/src/templates/svelte/package.json +6 -1
- package/ionyx-cli/src/templates/svelte/src-ionyx/Cargo.toml +14 -12
- package/ionyx-cli/src/templates/svelte/src-ionyx/main.rs +46 -3
- package/ionyx-cli/src/templates/vanilla/ionyx.config.json +3 -0
- package/ionyx-cli/src/templates/vanilla/package.json +6 -1
- package/ionyx-cli/src/templates/vanilla/src-ionyx/Cargo.toml +14 -12
- package/ionyx-cli/src/templates/vanilla/src-ionyx/main.rs +46 -3
- package/ionyx-cli/src/templates/vue/ionyx.config.json +4 -1
- package/ionyx-cli/src/templates/vue/package.json +6 -1
- package/ionyx-cli/src/templates/vue/src-ionyx/Cargo.toml +14 -12
- package/ionyx-cli/src/templates/vue/src-ionyx/main.rs +46 -3
- package/package.json +1 -1
package/bin/ionyx.exe
CHANGED
|
Binary file
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
build = "build.rs"
|
|
3
|
+
name = "my-ionyx-app"
|
|
4
|
+
version = "0.4.2"
|
|
5
|
+
edition = "2021"
|
|
6
|
+
|
|
7
|
+
[dependencies]
|
|
8
|
+
include_dir = "0.7"
|
|
9
|
+
# Web framework dependencies
|
|
10
|
+
wry = "0.54"
|
|
11
|
+
tao = "0.34"
|
|
12
|
+
tokio = { version = "1.50", features = ["full"] }
|
|
13
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
14
|
+
serde_json = "1.0"
|
|
15
|
+
anyhow = "1.0"
|
|
16
|
+
toml = "0.8"
|
|
17
|
+
tracing = "0.1"
|
|
18
|
+
tracing-subscriber = "0.3"
|
|
19
|
+
os_info = "3"
|
|
20
|
+
gethostname = "0.4"
|
|
21
|
+
|
|
22
|
+
[[bin]]
|
|
23
|
+
name = "my-ionyx-app"
|
|
24
|
+
path = "main.rs"
|
|
25
|
+
|
|
26
|
+
[profile.release]
|
|
27
|
+
opt-level = 3
|
|
28
|
+
lto = true
|
|
29
|
+
codegen-units = 1
|
|
30
|
+
panic = "abort"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
use ionyx::{config, security, protocol};
|
|
2
|
+
|
|
3
|
+
#[tokio::main]
|
|
4
|
+
async fn main() {
|
|
5
|
+
println!("🚀 Ionyx Application starting...");
|
|
6
|
+
|
|
7
|
+
// Load application configuration
|
|
8
|
+
let app_config = match config::Config::load().await {
|
|
9
|
+
Ok(config) => {
|
|
10
|
+
println!("✅ Configuration loaded successfully");
|
|
11
|
+
config
|
|
12
|
+
}
|
|
13
|
+
Err(e) => {
|
|
14
|
+
eprintln!("⚠️ Failed to load config, using defaults: {}", e);
|
|
15
|
+
config::Config::default()
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Initialize security manager for demonstration
|
|
20
|
+
let security_manager: crate::security::SecurityManager = security::SecurityManager::new(app_config.clone());
|
|
21
|
+
|
|
22
|
+
// Demonstrate comprehensive security manager functionality
|
|
23
|
+
let test_paths = ["./app-data", "/system", "../outside"];
|
|
24
|
+
for &test_path in &test_paths {
|
|
25
|
+
let is_secure = security_manager.is_path_allowed(test_path);
|
|
26
|
+
println!("🔒 Security check: '{}' -> {}",
|
|
27
|
+
test_path,
|
|
28
|
+
if is_secure { "ALLOWED" } else { "DENIED" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Demonstrate security validation
|
|
32
|
+
if let Ok(()) = security_manager.validate_path_operation("./app-data", "read") {
|
|
33
|
+
println!("🔒 Security validation: Path operation approved");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Initialize protocol handler for demonstration
|
|
37
|
+
let _protocol_handler = protocol::CustomProtocolHandler::new();
|
|
38
|
+
println!("🌐 Protocol handler initialized");
|
|
39
|
+
|
|
40
|
+
// Create and run the Ionyx application with automatic Vite server startup
|
|
41
|
+
println!("🚀 Launching Ionyx application...");
|
|
42
|
+
let builder = ionyx::Builder::new().config(app_config);
|
|
43
|
+
|
|
44
|
+
if let Err(e) = builder.run() {
|
|
45
|
+
eprintln!("❌ Application failed to start: {}", e);
|
|
46
|
+
std::process::exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// Ionyx Angular Template Library
|
|
2
|
+
|
|
3
|
+
use serde::{Deserialize, Serialize};
|
|
4
|
+
use std::collections::HashMap;
|
|
5
|
+
|
|
6
|
+
pub mod config;
|
|
7
|
+
pub mod ipc_bridge;
|
|
8
|
+
pub mod protocol;
|
|
9
|
+
pub mod security;
|
|
10
|
+
pub mod window;
|
|
11
|
+
pub mod fusion;
|
|
12
|
+
|
|
13
|
+
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
14
|
+
pub struct DevConfig {
|
|
15
|
+
pub port: u16,
|
|
16
|
+
pub host: String,
|
|
17
|
+
pub before_dev_command: Option<String>,
|
|
18
|
+
pub dev_url: String,
|
|
19
|
+
pub hot: bool,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
23
|
+
pub struct AppConfig {
|
|
24
|
+
pub name: String,
|
|
25
|
+
pub version: String,
|
|
26
|
+
pub description: String,
|
|
27
|
+
pub dev: DevConfig,
|
|
28
|
+
pub window: HashMap<String, serde_json::Value>,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#[derive(Debug, Clone)]
|
|
32
|
+
pub struct Builder {
|
|
33
|
+
config: Option<AppConfig>,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
impl Default for Builder {
|
|
37
|
+
fn default() -> Self {
|
|
38
|
+
Self::new()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
impl Builder {
|
|
43
|
+
pub fn new() -> Self {
|
|
44
|
+
Self { config: None }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
pub fn config(mut self, config: AppConfig) -> Self {
|
|
48
|
+
self.config = Some(config);
|
|
49
|
+
self
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
pub fn run(self) -> anyhow::Result<()> {
|
|
53
|
+
let rt = tokio::runtime::Runtime::new()?;
|
|
54
|
+
rt.block_on(async {
|
|
55
|
+
self.run_async().await
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async fn run_async(self) -> anyhow::Result<()> {
|
|
60
|
+
// Load configuration if not provided
|
|
61
|
+
let config = if let Some(cfg) = self.config {
|
|
62
|
+
cfg
|
|
63
|
+
} else {
|
|
64
|
+
config::Config::load().await
|
|
65
|
+
.map_err(|e| anyhow::anyhow!("Failed to load config: {}", e))?
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
println!("🚀 Ionyx Framework starting...");
|
|
69
|
+
println!("📱 App: {} v{}", config.name, config.version);
|
|
70
|
+
println!("🔧 Debug mode: true");
|
|
71
|
+
|
|
72
|
+
// Initialize security manager for demonstration
|
|
73
|
+
let security_manager: crate::security::SecurityManager = security::SecurityManager::new(config.clone());
|
|
74
|
+
|
|
75
|
+
// Demonstrate comprehensive security manager functionality
|
|
76
|
+
let test_paths = ["./app-data", "/system", "../outside"];
|
|
77
|
+
for &test_path in &test_paths {
|
|
78
|
+
let is_secure = security_manager.is_path_allowed(test_path);
|
|
79
|
+
println!("🔒 Security check: '{}' -> {}",
|
|
80
|
+
test_path,
|
|
81
|
+
if is_secure { "ALLOWED" } else { "DENIED" });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Demonstrate security validation
|
|
85
|
+
if let Ok(()) = security_manager.validate_path_operation("./app-data", "read") {
|
|
86
|
+
println!("🔒 Security validation: Path operation approved");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Initialize protocol handler for demonstration
|
|
90
|
+
let _protocol_handler = protocol::CustomProtocolHandler::new();
|
|
91
|
+
println!("🌐 Protocol handler initialized");
|
|
92
|
+
|
|
93
|
+
// Handle dev server based on configuration (Tauri-like approach)
|
|
94
|
+
if let Some(before_dev_command) = &config.dev.before_dev_command {
|
|
95
|
+
println!("🔧 Starting dev server with command: {}", before_dev_command);
|
|
96
|
+
let vite_child = start_vite_dev_server(before_dev_command)?;
|
|
97
|
+
monitor_vite_server(vite_child)?;
|
|
98
|
+
|
|
99
|
+
// Wait for Vite to be ready
|
|
100
|
+
println!("⏳ Waiting for Vite dev server to be ready...");
|
|
101
|
+
thread::sleep(Duration::from_secs(5));
|
|
102
|
+
} else {
|
|
103
|
+
println!("⚠️ No beforeDevCommand configured, skipping dev server startup");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Create event loop
|
|
107
|
+
let event_loop: EventLoop<String> = EventLoopBuilder::with_user_event().build();
|
|
108
|
+
let _web_context = WebContext::new(Some(Default::default()));
|
|
109
|
+
|
|
110
|
+
// Create window
|
|
111
|
+
let window = tao::window::WindowBuilder::new()
|
|
112
|
+
.with_title(&config.name)
|
|
113
|
+
.with_inner_size(tao::dpi::LogicalSize::new(1200.0, 800.0))
|
|
114
|
+
.with_resizable(true)
|
|
115
|
+
.build(&event_loop)?;
|
|
116
|
+
|
|
117
|
+
// Use configured dev URL
|
|
118
|
+
println!("🌐 Connecting to Vite dev server at {}", config.dev.dev_url);
|
|
119
|
+
|
|
120
|
+
// Create IPC dispatcher
|
|
121
|
+
let ipc_dispatcher = Arc::new(IpcDispatcher::new(event_loop.create_proxy()));
|
|
122
|
+
let webview = Arc::new(Mutex::new(
|
|
123
|
+
WebViewBuilder::new()
|
|
124
|
+
.with_initialization_script(include_str!("ionyx.js"))
|
|
125
|
+
.with_ipc_handler(move |request| {
|
|
126
|
+
let dispatcher = ipc_dispatcher.clone();
|
|
127
|
+
let request_body = request.body().clone();
|
|
128
|
+
tokio::spawn(async move {
|
|
129
|
+
if let Ok(request_str) = String::from_utf8(request_body) {
|
|
130
|
+
if let Ok(ipc_request) = serde_json::from_str::<serde_json::Value>(&request_str) {
|
|
131
|
+
if let Some(command) = ipc_request.get("command").and_then(|c| c.as_str()) {
|
|
132
|
+
if let Some(id) = ipc_request.get("id").and_then(|i| i.as_str()) {
|
|
133
|
+
match command {
|
|
134
|
+
"app.getVersion" => {
|
|
135
|
+
let data = json!({
|
|
136
|
+
"name": config.name,
|
|
137
|
+
"version": config.version,
|
|
138
|
+
"platform": std::env::consts::OS
|
|
139
|
+
});
|
|
140
|
+
dispatcher.resolve_promise(id, true, Some(data), None);
|
|
141
|
+
info!("✅ IPC response sent for: {}", command);
|
|
142
|
+
}
|
|
143
|
+
"os.info" => {
|
|
144
|
+
let data = json!({
|
|
145
|
+
"platform": std::env::consts::OS,
|
|
146
|
+
"arch": std::env::consts::ARCH,
|
|
147
|
+
"version": "1.0.0",
|
|
148
|
+
"hostname": "localhost"
|
|
149
|
+
});
|
|
150
|
+
dispatcher.resolve_promise(id, true, Some(data), None);
|
|
151
|
+
info!("✅ IPC response sent for: {}", command);
|
|
152
|
+
}
|
|
153
|
+
_ => {
|
|
154
|
+
let error = format!("Unknown command: {}", command);
|
|
155
|
+
dispatcher.resolve_promise(id, false, None, Some(error));
|
|
156
|
+
error!("Unknown IPC command: {}", command);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
})
|
|
165
|
+
.with_navigation_handler(|url| {
|
|
166
|
+
url.starts_with("http://127.0.0.1:") ||
|
|
167
|
+
url.starts_with("https://127.0.0.1:") ||
|
|
168
|
+
url.starts_with("file://") ||
|
|
169
|
+
url.starts_with("ionyx://")
|
|
170
|
+
})
|
|
171
|
+
.with_url(&config.dev.dev_url)
|
|
172
|
+
.with_devtools(true)
|
|
173
|
+
.build(&window)?
|
|
174
|
+
));
|
|
175
|
+
|
|
176
|
+
println!("✅ Ionyx application initialized successfully!");
|
|
177
|
+
println!("🎉 Both Vite dev server and Ionyx application are running!");
|
|
178
|
+
println!("🌐 Open {} to access your application", config.dev.dev_url);
|
|
179
|
+
|
|
180
|
+
// Run event loop
|
|
181
|
+
event_loop.run(move |event, _, control_flow| {
|
|
182
|
+
*control_flow = ControlFlow::Wait;
|
|
183
|
+
|
|
184
|
+
match event {
|
|
185
|
+
tao::event::Event::UserEvent(js_code) => {
|
|
186
|
+
info!("Executing JavaScript code: {}", js_code);
|
|
187
|
+
if let Ok(webview_guard) = webview.lock() {
|
|
188
|
+
if let Err(e) = webview_guard.evaluate_script(&js_code) {
|
|
189
|
+
error!("Failed to execute JavaScript code: {}", e);
|
|
190
|
+
} else {
|
|
191
|
+
info!("JavaScript code executed successfully");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
tao::event::Event::WindowEvent {
|
|
196
|
+
event: tao::event::WindowEvent::CloseRequested,
|
|
197
|
+
..
|
|
198
|
+
} => {
|
|
199
|
+
println!("👋 Application closing...");
|
|
200
|
+
*control_flow = ControlFlow::Exit;
|
|
201
|
+
}
|
|
202
|
+
_ => (),
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
fn start_vite_dev_server(command: &str) -> anyhow::Result<std::process::Child> {
|
|
209
|
+
info!("🚀 Starting Vite dev server with command: {}", command);
|
|
210
|
+
|
|
211
|
+
// Parse the command (e.g., "npm run dev" -> ["npm", "run", "dev"])
|
|
212
|
+
let parts: Vec<&str> = command.split_whitespace().collect();
|
|
213
|
+
if parts.is_empty() {
|
|
214
|
+
return Err(anyhow::anyhow!("Invalid beforeDevCommand"));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let mut child = Command::new(parts[0])
|
|
218
|
+
.args(&parts[1..])
|
|
219
|
+
.stdout(Stdio::piped())
|
|
220
|
+
.stderr(Stdio::piped())
|
|
221
|
+
.spawn()
|
|
222
|
+
.map_err(|e| anyhow::anyhow!("Failed to start Vite dev server: {}", e))?;
|
|
223
|
+
|
|
224
|
+
Ok(child)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
fn monitor_vite_server(mut child: std::process::Child) -> anyhow::Result<()> {
|
|
228
|
+
info!("👀 Monitoring Vite dev server output...");
|
|
229
|
+
|
|
230
|
+
if let Some(stdout) = child.stdout.take() {
|
|
231
|
+
let reader = BufReader::new(stdout);
|
|
232
|
+
thread::spawn(move || {
|
|
233
|
+
for line in reader.lines() {
|
|
234
|
+
match line {
|
|
235
|
+
Ok(line) => {
|
|
236
|
+
println!("📝 Vite: {}", line);
|
|
237
|
+
// Check for ready indicators
|
|
238
|
+
if line.contains("ready") || line.contains("Ready") ||
|
|
239
|
+
line.contains("Local:") || line.contains("http://") {
|
|
240
|
+
info!("✅ Vite dev server is ready!");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
Err(e) => error!("Error reading Vite output: {}", e),
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Also monitor stderr
|
|
250
|
+
if let Some(stderr) = child.stderr.take() {
|
|
251
|
+
let reader = BufReader::new(stderr);
|
|
252
|
+
thread::spawn(move || {
|
|
253
|
+
for line in reader.lines() {
|
|
254
|
+
match line {
|
|
255
|
+
Ok(line) => {
|
|
256
|
+
if !line.contains("webpack") && !line.contains("built in") {
|
|
257
|
+
eprintln!("⚠️ Vite stderr: {}", line);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
Err(e) => error!("Error reading Vite stderr: {}", e),
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
Ok(())
|
|
267
|
+
}
|
|
@@ -10,7 +10,12 @@
|
|
|
10
10
|
"preview": "vite preview",
|
|
11
11
|
"start": "vite preview --port 5173",
|
|
12
12
|
"ionyx:dev": "cd src-ionyx && cargo run --bin my-ionyx-app",
|
|
13
|
-
"ionyx:build": "cd src-ionyx && cargo build --release",
|
|
13
|
+
"ionyx:build": "cd src-ionyx && cargo build --release && npm run bundle:create",
|
|
14
|
+
"bundle:create": "node -e \"const fs=require('fs');const path=require('path');const dist=path.join(__dirname,'dist');if(!fs.existsSync(dist))fs.mkdirSync(dist);const target=path.join(__dirname,'src-ionyx','target','release','my-ionyx-app.exe');if(fs.existsSync(target)){const bundle=path.join(dist,'my-ionyx-app-v1.0.0.exe');fs.copyFileSync(target,bundle);console.log('✅ Bundle created:',bundle);}else{console.log('❌ Executable not found');}\"",
|
|
15
|
+
"bundle": "npm run bundle:create",
|
|
16
|
+
"bundle:windows": "npm run bundle:create",
|
|
17
|
+
"bundle:macos": "npm run bundle:create",
|
|
18
|
+
"bundle:linux": "npm run bundle:create",
|
|
14
19
|
"ionyx": "npx ionyx",
|
|
15
20
|
"ionyx:dev2": "npx ionyx dev",
|
|
16
21
|
"ionyx:build2": "npx ionyx build",
|
|
@@ -4,22 +4,24 @@ name = "my-ionyx-app"
|
|
|
4
4
|
version = "0.4.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
|
|
7
|
-
[workspace]
|
|
8
|
-
|
|
9
|
-
[lib]
|
|
10
|
-
name = "my_ionyx_app"
|
|
11
|
-
path = "src/lib.rs"
|
|
12
|
-
|
|
13
|
-
[[bin]]
|
|
14
|
-
name = "my-ionyx-app"
|
|
15
|
-
path = "main.rs"
|
|
16
|
-
|
|
17
7
|
[dependencies]
|
|
18
8
|
include_dir = "0.7"
|
|
19
|
-
|
|
20
|
-
anyhow = "1.0"
|
|
9
|
+
# Web framework dependencies
|
|
21
10
|
wry = "0.54"
|
|
22
11
|
tao = "0.34"
|
|
12
|
+
tokio = { version = "1.50", features = ["full"] }
|
|
13
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
14
|
+
serde_json = "1.0"
|
|
15
|
+
anyhow = "1.0"
|
|
16
|
+
toml = "0.8"
|
|
17
|
+
tracing = "0.1"
|
|
18
|
+
tracing-subscriber = "0.3"
|
|
19
|
+
os_info = "3"
|
|
20
|
+
gethostname = "0.4"
|
|
21
|
+
|
|
22
|
+
[[bin]]
|
|
23
|
+
name = "my-ionyx-app"
|
|
24
|
+
path = "main.rs"
|
|
23
25
|
|
|
24
26
|
[profile.release]
|
|
25
27
|
opt-level = 3
|
|
@@ -1,5 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
use ionyx::{config, security, protocol};
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
#[tokio::main]
|
|
4
|
+
async fn main() {
|
|
5
|
+
println!("🚀 Ionyx Application starting...");
|
|
6
|
+
|
|
7
|
+
// Load application configuration
|
|
8
|
+
let app_config = match config::Config::load().await {
|
|
9
|
+
Ok(config) => {
|
|
10
|
+
println!("✅ Configuration loaded successfully");
|
|
11
|
+
config
|
|
12
|
+
}
|
|
13
|
+
Err(e) => {
|
|
14
|
+
eprintln!("⚠️ Failed to load config, using defaults: {}", e);
|
|
15
|
+
config::Config::default()
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Initialize security manager for demonstration
|
|
20
|
+
let security_manager: crate::security::SecurityManager = security::SecurityManager::new(app_config.clone());
|
|
21
|
+
|
|
22
|
+
// Demonstrate comprehensive security manager functionality
|
|
23
|
+
let test_paths = ["./app-data", "/system", "../outside"];
|
|
24
|
+
for &test_path in &test_paths {
|
|
25
|
+
let is_secure = security_manager.is_path_allowed(test_path);
|
|
26
|
+
println!("🔒 Security check: '{}' -> {}",
|
|
27
|
+
test_path,
|
|
28
|
+
if is_secure { "ALLOWED" } else { "DENIED" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Demonstrate security validation
|
|
32
|
+
if let Ok(()) = security_manager.validate_path_operation("./app-data", "read") {
|
|
33
|
+
println!("🔒 Security validation: Path operation approved");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Initialize protocol handler for demonstration
|
|
37
|
+
let _protocol_handler = protocol::CustomProtocolHandler::new();
|
|
38
|
+
println!("🌐 Protocol handler initialized");
|
|
39
|
+
|
|
40
|
+
// Create and run the Ionyx application with automatic Vite server startup
|
|
41
|
+
println!("🚀 Launching Ionyx application...");
|
|
42
|
+
let builder = ionyx::Builder::new().config(app_config);
|
|
43
|
+
|
|
44
|
+
if let Err(e) = builder.run() {
|
|
45
|
+
eprintln!("❌ Application failed to start: {}", e);
|
|
46
|
+
std::process::exit(1);
|
|
47
|
+
}
|
|
5
48
|
}
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
"build": "vite build",
|
|
9
9
|
"preview": "vite preview",
|
|
10
10
|
"ionyx:dev": "cd src-ionyx && cargo run --bin my-ionyx-app",
|
|
11
|
-
"ionyx:build": "cd src-ionyx && cargo build --release",
|
|
11
|
+
"ionyx:build": "cd src-ionyx && cargo build --release && npm run bundle:create",
|
|
12
|
+
"bundle:create": "node -e \"const fs=require('fs');const path=require('path');const dist=path.join(__dirname,'dist');if(!fs.existsSync(dist))fs.mkdirSync(dist);const target=path.join(__dirname,'src-ionyx','target','release','my-ionyx-app.exe');if(fs.existsSync(target)){const bundle=path.join(dist,'my-ionyx-app-v1.0.0.exe');fs.copyFileSync(target,bundle);console.log('✅ Bundle created:',bundle);}else{console.log('❌ Executable not found');}\"",
|
|
13
|
+
"bundle": "npm run bundle:create",
|
|
14
|
+
"bundle:windows": "npm run bundle:create",
|
|
15
|
+
"bundle:macos": "npm run bundle:create",
|
|
16
|
+
"bundle:linux": "npm run bundle:create",
|
|
12
17
|
"ionyx": "npx ionyx",
|
|
13
18
|
"ionyx:dev2": "npx ionyx dev",
|
|
14
19
|
"ionyx:build2": "npx ionyx build",
|
|
@@ -4,18 +4,24 @@ name = "my-ionyx-app"
|
|
|
4
4
|
version = "0.4.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
|
|
7
|
-
[workspace]
|
|
8
|
-
|
|
9
|
-
[[bin]]
|
|
10
|
-
name = "my-ionyx-app"
|
|
11
|
-
path = "main.rs"
|
|
12
|
-
|
|
13
7
|
[dependencies]
|
|
14
8
|
include_dir = "0.7"
|
|
15
|
-
|
|
16
|
-
anyhow = "1.0"
|
|
9
|
+
# Web framework dependencies
|
|
17
10
|
wry = "0.54"
|
|
18
11
|
tao = "0.34"
|
|
12
|
+
tokio = { version = "1.50", features = ["full"] }
|
|
13
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
14
|
+
serde_json = "1.0"
|
|
15
|
+
anyhow = "1.0"
|
|
16
|
+
toml = "0.8"
|
|
17
|
+
tracing = "0.1"
|
|
18
|
+
tracing-subscriber = "0.3"
|
|
19
|
+
os_info = "3"
|
|
20
|
+
gethostname = "0.4"
|
|
21
|
+
|
|
22
|
+
[[bin]]
|
|
23
|
+
name = "my-ionyx-app"
|
|
24
|
+
path = "main.rs"
|
|
19
25
|
|
|
20
26
|
[profile.release]
|
|
21
27
|
opt-level = 3
|
|
@@ -1,5 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
use ionyx::{config, security, protocol};
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
#[tokio::main]
|
|
4
|
+
async fn main() {
|
|
5
|
+
println!("🚀 Ionyx Application starting...");
|
|
6
|
+
|
|
7
|
+
// Load application configuration
|
|
8
|
+
let app_config = match config::Config::load().await {
|
|
9
|
+
Ok(config) => {
|
|
10
|
+
println!("✅ Configuration loaded successfully");
|
|
11
|
+
config
|
|
12
|
+
}
|
|
13
|
+
Err(e) => {
|
|
14
|
+
eprintln!("⚠️ Failed to load config, using defaults: {}", e);
|
|
15
|
+
config::Config::default()
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Initialize security manager for demonstration
|
|
20
|
+
let security_manager: crate::security::SecurityManager = security::SecurityManager::new(app_config.clone());
|
|
21
|
+
|
|
22
|
+
// Demonstrate comprehensive security manager functionality
|
|
23
|
+
let test_paths = ["./app-data", "/system", "../outside"];
|
|
24
|
+
for &test_path in &test_paths {
|
|
25
|
+
let is_secure = security_manager.is_path_allowed(test_path);
|
|
26
|
+
println!("🔒 Security check: '{}' -> {}",
|
|
27
|
+
test_path,
|
|
28
|
+
if is_secure { "ALLOWED" } else { "DENIED" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Demonstrate security validation
|
|
32
|
+
if let Ok(()) = security_manager.validate_path_operation("./app-data", "read") {
|
|
33
|
+
println!("🔒 Security validation: Path operation approved");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Initialize protocol handler for demonstration
|
|
37
|
+
let _protocol_handler = protocol::CustomProtocolHandler::new();
|
|
38
|
+
println!("🌐 Protocol handler initialized");
|
|
39
|
+
|
|
40
|
+
// Create and run the Ionyx application with automatic Vite server startup
|
|
41
|
+
println!("🚀 Launching Ionyx application...");
|
|
42
|
+
let builder = ionyx::Builder::new().config(app_config);
|
|
43
|
+
|
|
44
|
+
if let Err(e) = builder.run() {
|
|
45
|
+
eprintln!("❌ Application failed to start: {}", e);
|
|
46
|
+
std::process::exit(1);
|
|
47
|
+
}
|
|
5
48
|
}
|
|
@@ -51,11 +51,7 @@ pub async fn copy_template(project_name: &str, dest_path: &str, template: &str)
|
|
|
51
51
|
if Path::new(&backend_cargo_path).exists() {
|
|
52
52
|
let mut content = fs::read_to_string(&backend_cargo_path)?;
|
|
53
53
|
content = content.replace("my-ionyx-app", project_name);
|
|
54
|
-
//
|
|
55
|
-
content = content.replace(
|
|
56
|
-
"ionyx = { path = \"../../../../../../src-ionyx\" }",
|
|
57
|
-
"ionyx = { git = \"https://github.com/ionyx-apps/ionyx\", branch = \"quantum\" }"
|
|
58
|
-
);
|
|
54
|
+
// Keep the native framework implementation instead of forcing git dependency
|
|
59
55
|
fs::write(&backend_cargo_path, content)?;
|
|
60
56
|
}
|
|
61
57
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "{{PROJECT_NAME}}",
|
|
3
3
|
"version": "1.0.0",
|
|
4
|
-
"description": "Ionyx Framework
|
|
4
|
+
"description": "React + TypeScript + Vite application with Ionyx Framework",
|
|
5
5
|
"type": "app",
|
|
6
6
|
"src": "src",
|
|
7
7
|
"dist": "dist",
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dev": {
|
|
15
15
|
"port": 5173,
|
|
16
|
+
"host": "127.0.0.1",
|
|
17
|
+
"beforeDevCommand": "npm run dev",
|
|
18
|
+
"devUrl": "http://127.0.0.1:5173",
|
|
16
19
|
"hot": true
|
|
17
20
|
},
|
|
18
21
|
"build": {
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
"build": "tsc && vite build",
|
|
9
9
|
"preview": "vite preview",
|
|
10
10
|
"ionyx:dev": "cd src-ionyx && cargo run --bin my-ionyx-app",
|
|
11
|
-
"ionyx:build": "cd src-ionyx && cargo build --release",
|
|
11
|
+
"ionyx:build": "cd src-ionyx && cargo build --release && npm run bundle:create",
|
|
12
|
+
"bundle:create": "node -e \"const fs=require('fs');const path=require('path');const dist=path.join(__dirname,'dist');if(!fs.existsSync(dist))fs.mkdirSync(dist);const target=path.join(__dirname,'src-ionyx','target','release','my-ionyx-app.exe');if(fs.existsSync(target)){const bundle=path.join(dist,'my-ionyx-app-v1.0.0.exe');fs.copyFileSync(target,bundle);console.log('✅ Bundle created:',bundle);}else{console.log('❌ Executable not found');}\"",
|
|
13
|
+
"bundle": "npm run bundle:create",
|
|
14
|
+
"bundle:windows": "npm run bundle:create",
|
|
15
|
+
"bundle:macos": "npm run bundle:create",
|
|
16
|
+
"bundle:linux": "npm run bundle:create",
|
|
12
17
|
"ionyx": "npx ionyx",
|
|
13
18
|
"ionyx:dev2": "npx ionyx dev",
|
|
14
19
|
"ionyx:build2": "npx ionyx build",
|
|
@@ -4,22 +4,24 @@ name = "my-ionyx-app"
|
|
|
4
4
|
version = "0.4.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
|
|
7
|
-
[workspace]
|
|
8
|
-
|
|
9
|
-
[lib]
|
|
10
|
-
name = "my_ionyx_app"
|
|
11
|
-
path = "src/lib.rs"
|
|
12
|
-
|
|
13
|
-
[[bin]]
|
|
14
|
-
name = "my-ionyx-app"
|
|
15
|
-
path = "main.rs"
|
|
16
|
-
|
|
17
7
|
[dependencies]
|
|
18
8
|
include_dir = "0.7"
|
|
19
|
-
|
|
20
|
-
anyhow = "1.0"
|
|
9
|
+
# Web framework dependencies
|
|
21
10
|
wry = "0.54"
|
|
22
11
|
tao = "0.34"
|
|
12
|
+
tokio = { version = "1.50", features = ["full"] }
|
|
13
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
14
|
+
serde_json = "1.0"
|
|
15
|
+
anyhow = "1.0"
|
|
16
|
+
toml = "0.8"
|
|
17
|
+
tracing = "0.1"
|
|
18
|
+
tracing-subscriber = "0.3"
|
|
19
|
+
os_info = "3"
|
|
20
|
+
gethostname = "0.4"
|
|
21
|
+
|
|
22
|
+
[[bin]]
|
|
23
|
+
name = "my-ionyx-app"
|
|
24
|
+
path = "main.rs"
|
|
23
25
|
|
|
24
26
|
[profile.release]
|
|
25
27
|
opt-level = 3
|