create-droid 1.0.4 → 1.0.5
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/templates/base/scripts/adb.js +133 -24
package/package.json
CHANGED
|
@@ -1,47 +1,156 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { spawn } = require('child_process');
|
|
3
|
+
const { spawn, execSync } = require('child_process');
|
|
4
|
+
const readline = require('readline');
|
|
4
5
|
const os = require('os');
|
|
5
6
|
|
|
6
|
-
//
|
|
7
|
+
// --- Configuration ---
|
|
7
8
|
const projectRoot = path.resolve(__dirname, '..');
|
|
8
9
|
const localPropertiesPath = path.join(projectRoot, 'local.properties');
|
|
9
10
|
let sdkPath = process.env.ANDROID_HOME;
|
|
10
11
|
|
|
12
|
+
// --- 1. Resolve ADB Path ---
|
|
11
13
|
if (fs.existsSync(localPropertiesPath)) {
|
|
12
14
|
const content = fs.readFileSync(localPropertiesPath, 'utf8');
|
|
13
15
|
const match = content.match(/^sdk\.dir=(.*)$/m);
|
|
14
16
|
if (match) {
|
|
15
|
-
sdkPath = match[1].trim().replace(/\\\\/g, '\\');
|
|
17
|
+
sdkPath = match[1].trim().replace(/\\\\/g, '\\');
|
|
16
18
|
}
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
if (!sdkPath) {
|
|
20
|
-
console.error('❌ Could not find SDK location. Set ANDROID_HOME or create local.properties.');
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// 2. Resolve ADB binary
|
|
25
21
|
const isWin = os.platform() === 'win32';
|
|
26
22
|
const adbBinary = isWin ? 'adb.exe' : 'adb';
|
|
27
|
-
const
|
|
23
|
+
const localAdbPath = sdkPath ? path.join(sdkPath, 'platform-tools', adbBinary) : null;
|
|
24
|
+
const finalAdbPath = (localAdbPath && fs.existsSync(localAdbPath)) ? localAdbPath : 'adb';
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
// --- 2. Helper Functions ---
|
|
27
|
+
function runCommand(args, inherit = true) {
|
|
28
|
+
if (inherit) {
|
|
29
|
+
const child = spawn(finalAdbPath, args, { stdio: 'inherit' });
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
child.on('close', (code) => resolve(code));
|
|
32
|
+
});
|
|
33
|
+
} else {
|
|
34
|
+
try {
|
|
35
|
+
return execSync(`"${finalAdbPath}" ${args.join(' ')}`, { encoding: 'utf8' }).trim();
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
32
40
|
}
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
function clearScreen() {
|
|
43
|
+
process.stdout.write('\x1Bc');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// --- 3. Interactive Menu ---
|
|
47
|
+
async function showMenu() {
|
|
48
|
+
clearScreen();
|
|
49
|
+
console.log('\x1b[36m%s\x1b[0m', '🤖 Android Debug Bridge (ADB) Manager');
|
|
50
|
+
console.log('-----------------------------------');
|
|
51
|
+
console.log('1. 📱 List Connected Devices');
|
|
52
|
+
console.log('2. 📡 Connect to Device (Wi-Fi)');
|
|
53
|
+
console.log('3. 🔗 Pair Device (Android 11+)');
|
|
54
|
+
console.log('4. 🔄 Reverse Port 8081 (React Native/Metro)');
|
|
55
|
+
console.log('5. 📜 Stream Logcat');
|
|
56
|
+
console.log('6. 💀 Kill ADB Server');
|
|
57
|
+
console.log('0. 🚪 Exit');
|
|
58
|
+
console.log('-----------------------------------');
|
|
59
|
+
|
|
60
|
+
const rl = readline.createInterface({
|
|
61
|
+
input: process.stdin,
|
|
62
|
+
output: process.stdout
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
rl.question('Select option: ', async (answer) => {
|
|
66
|
+
rl.close();
|
|
67
|
+
switch (answer.trim()) {
|
|
68
|
+
case '1':
|
|
69
|
+
await runCommand(['devices', '-l']);
|
|
70
|
+
await pause();
|
|
71
|
+
showMenu();
|
|
72
|
+
break;
|
|
73
|
+
case '2':
|
|
74
|
+
await handleConnect();
|
|
75
|
+
break;
|
|
76
|
+
case '3':
|
|
77
|
+
await handlePair();
|
|
78
|
+
break;
|
|
79
|
+
case '4':
|
|
80
|
+
console.log('Reversing tcp:8081...');
|
|
81
|
+
await runCommand(['reverse', 'tcp:8081', 'tcp:8081']);
|
|
82
|
+
await pause();
|
|
83
|
+
showMenu();
|
|
84
|
+
break;
|
|
85
|
+
case '5':
|
|
86
|
+
console.log('Starting Logcat (Ctrl+C to stop)...');
|
|
87
|
+
await runCommand(['logcat']);
|
|
88
|
+
// Logcat blocks, so we won't return easily loop unless killed
|
|
89
|
+
break;
|
|
90
|
+
case '6':
|
|
91
|
+
await runCommand(['kill-server']);
|
|
92
|
+
console.log('Server killed.');
|
|
93
|
+
await pause();
|
|
94
|
+
showMenu();
|
|
95
|
+
break;
|
|
96
|
+
case '0':
|
|
97
|
+
process.exit(0);
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
showMenu();
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function handleConnect() {
|
|
106
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
107
|
+
rl.question('Enter Device IP:Port (e.g., 192.168.1.5:5555): ', async (ip) => {
|
|
108
|
+
rl.close();
|
|
109
|
+
if (ip) {
|
|
110
|
+
console.log(`Connecting to ${ip}...`);
|
|
111
|
+
await runCommand(['connect', ip]);
|
|
112
|
+
}
|
|
113
|
+
await pause();
|
|
114
|
+
showMenu();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function handlePair() {
|
|
119
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
120
|
+
rl.question('Enter Device IP:Port (from "Wireless debugging"): ', (ip) => {
|
|
121
|
+
rl.question('Enter Pairing Code: ', async (code) => {
|
|
122
|
+
rl.close();
|
|
123
|
+
if (ip && code) {
|
|
124
|
+
console.log(`Pairing with ${ip}...`);
|
|
125
|
+
await runCommand(['pair', ip, code]);
|
|
126
|
+
}
|
|
127
|
+
await pause();
|
|
128
|
+
showMenu();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
37
132
|
|
|
38
|
-
|
|
133
|
+
function pause() {
|
|
134
|
+
return new Promise((resolve) => {
|
|
135
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
136
|
+
rl.question('\nPress Enter to continue...', () => {
|
|
137
|
+
rl.close();
|
|
138
|
+
resolve();
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
39
142
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
process.exit(1);
|
|
43
|
-
});
|
|
143
|
+
// --- 4. Main Execution ---
|
|
144
|
+
const args = process.argv.slice(2);
|
|
44
145
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
});
|
|
146
|
+
if (args.length > 0) {
|
|
147
|
+
// Pass-through mode (e.g., npm run adb connect ...)
|
|
148
|
+
const child = spawn(finalAdbPath, args, { stdio: 'inherit' });
|
|
149
|
+
child.on('close', (code) => process.exit(code));
|
|
150
|
+
} else {
|
|
151
|
+
// Interactive mode
|
|
152
|
+
if (!sdkPath && !process.env.ANDROID_HOME) {
|
|
153
|
+
console.warn('⚠️ ANDROID_HOME not set. Trying global ADB...');
|
|
154
|
+
}
|
|
155
|
+
showMenu();
|
|
156
|
+
}
|