quapp 1.0.0 → 1.0.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.
- package/package.json +1 -1
- package/server.js +72 -72
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
1
3
|
import { spawn } from "child_process";
|
|
2
4
|
import os from "os";
|
|
3
5
|
import qrcode from "qrcode-terminal";
|
|
4
|
-
import fs from "fs";
|
|
6
|
+
import fs from "fs/promises";
|
|
7
|
+
import { existsSync } from "fs";
|
|
5
8
|
import path from "path";
|
|
6
9
|
import open from "open";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
import { spawnSync } from "child_process";
|
|
12
|
+
|
|
13
|
+
// __dirname replacement in ES modules
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = path.dirname(__filename);
|
|
7
16
|
|
|
8
|
-
//
|
|
17
|
+
// Default config
|
|
9
18
|
let config = {
|
|
10
19
|
server: {
|
|
11
20
|
qr: true,
|
|
@@ -15,30 +24,35 @@ let config = {
|
|
|
15
24
|
https: false,
|
|
16
25
|
openBrowser: false,
|
|
17
26
|
autoRetry: true,
|
|
18
|
-
strictPort: false
|
|
19
|
-
}
|
|
27
|
+
strictPort: false,
|
|
28
|
+
},
|
|
20
29
|
};
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
// Load user config
|
|
32
|
+
const loadUserConfig = async () => {
|
|
33
|
+
try {
|
|
34
|
+
const configPath = path.resolve("quapp.config.json");
|
|
35
|
+
if (existsSync(configPath)) {
|
|
36
|
+
const data = await fs.readFile(configPath, "utf-8");
|
|
37
|
+
const userConfig = JSON.parse(data);
|
|
38
|
+
config = {
|
|
39
|
+
...config,
|
|
40
|
+
...userConfig,
|
|
41
|
+
server: { ...config.server, ...userConfig.server },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.warn("⚠️ Failed to read quapp.config.json. Using default config.");
|
|
46
|
+
console.warn(err.message);
|
|
31
47
|
}
|
|
32
|
-
}
|
|
33
|
-
console.warn("⚠️ Failed to read quapp.config.json. Using default config.");
|
|
34
|
-
}
|
|
48
|
+
};
|
|
35
49
|
|
|
36
|
-
// Get
|
|
37
|
-
|
|
50
|
+
// Get IP address
|
|
51
|
+
const getIP = (networkType = "local") => {
|
|
38
52
|
if (networkType === "private") {
|
|
39
53
|
const interfaces = os.networkInterfaces();
|
|
40
54
|
for (const key in interfaces) {
|
|
41
|
-
for (const iface of interfaces[key]
|
|
55
|
+
for (const iface of interfaces[key] ?? []) {
|
|
42
56
|
if (!iface.internal && iface.family === "IPv4") {
|
|
43
57
|
return iface.address;
|
|
44
58
|
}
|
|
@@ -46,83 +60,69 @@ function getIP(networkType = "local") {
|
|
|
46
60
|
}
|
|
47
61
|
}
|
|
48
62
|
return "localhost";
|
|
49
|
-
}
|
|
63
|
+
};
|
|
50
64
|
|
|
51
|
-
// Start Vite
|
|
52
|
-
|
|
65
|
+
// Start Vite server
|
|
66
|
+
const startVite = (port, attempt = 0) => {
|
|
53
67
|
const host = config.server.network === "private" ? getIP("private") : "localhost";
|
|
54
|
-
const
|
|
68
|
+
const protocol = config.server.https ? "https" : "http";
|
|
69
|
+
const url = `${protocol}://${host}:${port}`;
|
|
55
70
|
|
|
56
71
|
const viteArgs = [
|
|
57
72
|
"--host",
|
|
58
73
|
host,
|
|
59
74
|
"--port",
|
|
60
75
|
port,
|
|
61
|
-
// 🛠 Automatically enable strictPort if autoRetry is false
|
|
62
76
|
...(config.server.strictPort || !config.server.autoRetry ? ["--strictPort"] : []),
|
|
63
|
-
...(config.server.https ? ["--https"] : [])
|
|
77
|
+
...(config.server.https ? ["--https"] : []),
|
|
64
78
|
];
|
|
65
79
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
80
|
+
const viteBinary = path.resolve(
|
|
81
|
+
"node_modules",
|
|
82
|
+
".bin",
|
|
83
|
+
process.platform === "win32" ? "vite.cmd" : "vite"
|
|
84
|
+
);
|
|
69
85
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (portMatch && !shown) {
|
|
75
|
-
const usedPort = parseInt(portMatch[1]);
|
|
76
|
-
const finalUrl = `${config.server.https ? "https" : "http"}://${host}:${usedPort}`;
|
|
86
|
+
if (!existsSync(viteBinary)) {
|
|
87
|
+
console.error("❌ vite binary not found. Try running `npm install vite`.");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
if (config.server.qr) {
|
|
80
|
-
console.log(`\n📱 Scan the QR code below to open on any device:\n`);
|
|
81
|
-
qrcode.generate(finalUrl, { small: true });
|
|
82
|
-
}
|
|
91
|
+
const vite = spawn(viteBinary, viteArgs, { shell: true });
|
|
83
92
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
93
|
+
vite.stdout.on("data", (data) => process.stdout.write(data));
|
|
94
|
+
vite.stderr.on("data", (data) => process.stderr.write(data));
|
|
87
95
|
|
|
88
|
-
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
console.log(`\n🌍 Access your app from LAN at: ${url}`);
|
|
98
|
+
if (config.server.qr) {
|
|
99
|
+
console.log(`\n📱 Scan the QR code below:\n`);
|
|
100
|
+
qrcode.generate(url, { small: true });
|
|
89
101
|
}
|
|
102
|
+
if (config.server.openBrowser) {
|
|
103
|
+
open(url);
|
|
104
|
+
}
|
|
105
|
+
}, 1500);
|
|
90
106
|
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
viteProcess.stderr.on("data", (data) => {
|
|
95
|
-
process.stderr.write(data);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
viteProcess.on("exit", (code) => {
|
|
107
|
+
vite.on("exit", (code) => {
|
|
99
108
|
if (
|
|
100
109
|
code !== 0 &&
|
|
101
110
|
config.server.fallbackPort &&
|
|
102
111
|
config.server.autoRetry &&
|
|
103
112
|
attempt < 10
|
|
104
113
|
) {
|
|
105
|
-
console.log(`⚠️ Port ${port}
|
|
114
|
+
console.log(`⚠️ Port ${port} in use. Trying port ${port + 1}...`);
|
|
106
115
|
startVite(port + 1, attempt + 1);
|
|
107
|
-
} else {
|
|
108
|
-
console.
|
|
116
|
+
} else if (code !== 0) {
|
|
117
|
+
console.error(`❌ Vite exited with code ${code}`);
|
|
109
118
|
}
|
|
110
119
|
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
// Check if Vite is installed
|
|
122
|
-
if (checkViteInstalled()) {
|
|
123
|
-
console.error("❌ Vite is not installed. Please install it globally or in your project.");
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// Main
|
|
123
|
+
const main = async () => {
|
|
124
|
+
await loadUserConfig();
|
|
125
|
+
startVite(config.server.port);
|
|
126
|
+
};
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
startVite(config.server.port);
|
|
128
|
+
main();
|