@jetstart/cli 1.2.0 → 1.4.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.
- package/dist/cli.js +18 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/android-emulator.d.ts +8 -0
- package/dist/commands/android-emulator.d.ts.map +1 -0
- package/dist/commands/android-emulator.js +280 -0
- package/dist/commands/android-emulator.js.map +1 -0
- package/dist/commands/create.d.ts +1 -6
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +119 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/dev.d.ts +1 -7
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +69 -10
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +5 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/install-audit.d.ts +9 -0
- package/dist/commands/install-audit.d.ts.map +1 -0
- package/dist/commands/install-audit.js +185 -0
- package/dist/commands/install-audit.js.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/android-sdk.d.ts +81 -0
- package/dist/utils/android-sdk.d.ts.map +1 -0
- package/dist/utils/android-sdk.js +432 -0
- package/dist/utils/android-sdk.js.map +1 -0
- package/dist/utils/downloader.d.ts +35 -0
- package/dist/utils/downloader.d.ts.map +1 -0
- package/dist/utils/downloader.js +214 -0
- package/dist/utils/downloader.js.map +1 -0
- package/dist/utils/emulator-deployer.d.ts +29 -0
- package/dist/utils/emulator-deployer.d.ts.map +1 -0
- package/dist/utils/emulator-deployer.js +224 -0
- package/dist/utils/emulator-deployer.js.map +1 -0
- package/dist/utils/emulator.d.ts +101 -0
- package/dist/utils/emulator.d.ts.map +1 -0
- package/dist/utils/emulator.js +410 -0
- package/dist/utils/emulator.js.map +1 -0
- package/dist/utils/java.d.ts +25 -0
- package/dist/utils/java.d.ts.map +1 -0
- package/dist/utils/java.js +363 -0
- package/dist/utils/java.js.map +1 -0
- package/dist/utils/system-tools.d.ts +93 -0
- package/dist/utils/system-tools.d.ts.map +1 -0
- package/dist/utils/system-tools.js +599 -0
- package/dist/utils/system-tools.js.map +1 -0
- package/dist/utils/template.d.ts.map +1 -1
- package/dist/utils/template.js +777 -748
- package/dist/utils/template.js.map +1 -1
- package/package.json +7 -3
- package/src/cli.ts +20 -2
- package/src/commands/android-emulator.ts +304 -0
- package/src/commands/create.ts +128 -5
- package/src/commands/dev.ts +71 -18
- package/src/commands/index.ts +3 -1
- package/src/commands/install-audit.ts +227 -0
- package/src/types/index.ts +30 -0
- package/src/utils/android-sdk.ts +478 -0
- package/src/utils/downloader.ts +201 -0
- package/src/utils/emulator-deployer.ts +210 -0
- package/src/utils/emulator.ts +463 -0
- package/src/utils/java.ts +369 -0
- package/src/utils/system-tools.ts +648 -0
- package/src/utils/template.ts +875 -867
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Java/JDK detection and installation utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { exec } from 'child_process';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import * as fs from 'fs-extra';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
import { downloadWithRetry } from './downloader';
|
|
11
|
+
import { startSpinner, stopSpinner } from './spinner';
|
|
12
|
+
import { success, error as logError, warning, info } from './logger';
|
|
13
|
+
|
|
14
|
+
const execAsync = promisify(exec);
|
|
15
|
+
|
|
16
|
+
export interface JavaInfo {
|
|
17
|
+
version: string;
|
|
18
|
+
path: string;
|
|
19
|
+
vendor: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Parse Java version from command output
|
|
24
|
+
*/
|
|
25
|
+
function parseJavaVersion(output: string): { version: string; vendor: string } | null {
|
|
26
|
+
// Example outputs:
|
|
27
|
+
// openjdk version "17.0.9" 2023-10-17
|
|
28
|
+
// java version "1.8.0_291"
|
|
29
|
+
// openjdk 11.0.12 2021-07-20
|
|
30
|
+
|
|
31
|
+
const versionMatch = output.match(/version\s+"?(\d+)\.(\d+)\.(\d+)/i) ||
|
|
32
|
+
output.match(/openjdk\s+(\d+)\.(\d+)\.(\d+)/i);
|
|
33
|
+
|
|
34
|
+
if (!versionMatch) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Handle old Java versioning (1.8 = Java 8)
|
|
39
|
+
let major = versionMatch[1];
|
|
40
|
+
if (major === '1') {
|
|
41
|
+
major = versionMatch[2]; // Use 8 from 1.8
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const version = `${major}.${versionMatch[2]}.${versionMatch[3]}`;
|
|
45
|
+
|
|
46
|
+
// Detect vendor
|
|
47
|
+
let vendor = 'Unknown';
|
|
48
|
+
if (output.includes('OpenJDK') || output.includes('openjdk')) {
|
|
49
|
+
vendor = 'OpenJDK';
|
|
50
|
+
} else if (output.includes('Oracle')) {
|
|
51
|
+
vendor = 'Oracle';
|
|
52
|
+
} else if (output.includes('Eclipse Adoptium') || output.includes('Temurin')) {
|
|
53
|
+
vendor = 'Eclipse Adoptium';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return { version, vendor };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Detect Java/JDK installation
|
|
61
|
+
*/
|
|
62
|
+
export async function detectJava(): Promise<JavaInfo | null> {
|
|
63
|
+
try {
|
|
64
|
+
const { stdout } = await execAsync('java -version 2>&1');
|
|
65
|
+
const parsed = parseJavaVersion(stdout);
|
|
66
|
+
|
|
67
|
+
if (!parsed) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const javaPath = process.env.JAVA_HOME || '';
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
version: parsed.version,
|
|
75
|
+
path: javaPath,
|
|
76
|
+
vendor: parsed.vendor,
|
|
77
|
+
};
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Check if Java version is compatible (>= 17)
|
|
85
|
+
*/
|
|
86
|
+
export async function isJavaCompatible(version: string): Promise<boolean> {
|
|
87
|
+
const major = parseInt(version.split('.')[0], 10);
|
|
88
|
+
return major >= 17;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Download URLs for Eclipse Adoptium Temurin JDK 17
|
|
93
|
+
*/
|
|
94
|
+
const JDK_DOWNLOAD_URLS = {
|
|
95
|
+
win32: {
|
|
96
|
+
x64: 'https://api.adoptium.net/v3/binary/latest/17/ga/windows/x64/jdk/hotspot/normal/eclipse',
|
|
97
|
+
},
|
|
98
|
+
darwin: {
|
|
99
|
+
x64: 'https://api.adoptium.net/v3/binary/latest/17/ga/mac/x64/jdk/hotspot/normal/eclipse',
|
|
100
|
+
arm64: 'https://api.adoptium.net/v3/binary/latest/17/ga/mac/aarch64/jdk/hotspot/normal/eclipse',
|
|
101
|
+
},
|
|
102
|
+
linux: {
|
|
103
|
+
x64: 'https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jdk/hotspot/normal/eclipse',
|
|
104
|
+
arm64: 'https://api.adoptium.net/v3/binary/latest/17/ga/linux/aarch64/jdk/hotspot/normal/eclipse',
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get JDK download URL for current platform
|
|
110
|
+
*/
|
|
111
|
+
function getJDKDownloadURL(): string | null {
|
|
112
|
+
const platform = os.platform();
|
|
113
|
+
const arch = os.arch();
|
|
114
|
+
|
|
115
|
+
if (platform === 'win32') {
|
|
116
|
+
return JDK_DOWNLOAD_URLS.win32.x64;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (platform === 'darwin') {
|
|
120
|
+
return arch === 'arm64' ? JDK_DOWNLOAD_URLS.darwin.arm64 : JDK_DOWNLOAD_URLS.darwin.x64;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (platform === 'linux') {
|
|
124
|
+
return arch === 'arm64' ? JDK_DOWNLOAD_URLS.linux.arm64 : JDK_DOWNLOAD_URLS.linux.x64;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get default JDK installation path
|
|
132
|
+
*/
|
|
133
|
+
function getDefaultJDKPath(): string {
|
|
134
|
+
const homeDir = os.homedir();
|
|
135
|
+
const platform = os.platform();
|
|
136
|
+
|
|
137
|
+
if (platform === 'win32') {
|
|
138
|
+
return path.join(homeDir, 'AppData', 'Local', 'Programs', 'Eclipse Adoptium');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (platform === 'darwin') {
|
|
142
|
+
return '/Library/Java/JavaVirtualMachines';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Linux
|
|
146
|
+
return path.join(homeDir, '.jdks');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Set JAVA_HOME environment variable (Windows only, via registry)
|
|
151
|
+
*/
|
|
152
|
+
async function setJavaHomeWindows(javaPath: string): Promise<void> {
|
|
153
|
+
try {
|
|
154
|
+
const command = `setx JAVA_HOME "${javaPath}" /M`;
|
|
155
|
+
await execAsync(command);
|
|
156
|
+
info('JAVA_HOME environment variable set');
|
|
157
|
+
} catch (error) {
|
|
158
|
+
warning('Failed to set JAVA_HOME. You may need to set it manually.');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Install Java/JDK
|
|
164
|
+
*/
|
|
165
|
+
export async function installJava(): Promise<void> {
|
|
166
|
+
const platform = os.platform();
|
|
167
|
+
|
|
168
|
+
info('Installing Java/JDK 17...');
|
|
169
|
+
console.log();
|
|
170
|
+
|
|
171
|
+
// Check if already installed
|
|
172
|
+
const existing = await detectJava();
|
|
173
|
+
if (existing && await isJavaCompatible(existing.version)) {
|
|
174
|
+
success(`Java ${existing.version} is already installed`);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (platform === 'win32') {
|
|
179
|
+
await installJavaWindows();
|
|
180
|
+
} else if (platform === 'darwin') {
|
|
181
|
+
await installJavaMacOS();
|
|
182
|
+
} else if (platform === 'linux') {
|
|
183
|
+
await installJavaLinux();
|
|
184
|
+
} else {
|
|
185
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
success('Java/JDK 17 installed successfully');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Install Java on Windows
|
|
193
|
+
*/
|
|
194
|
+
async function installJavaWindows(): Promise<void> {
|
|
195
|
+
const url = getJDKDownloadURL();
|
|
196
|
+
if (!url) {
|
|
197
|
+
throw new Error('Could not determine JDK download URL');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
info('Downloading Eclipse Adoptium Temurin JDK 17...');
|
|
201
|
+
info('Note: On Windows, you may need to install manually from:');
|
|
202
|
+
info('https://adoptium.net/temurin/releases/?version=17');
|
|
203
|
+
console.log();
|
|
204
|
+
|
|
205
|
+
const tempDir = os.tmpdir();
|
|
206
|
+
const installerPath = path.join(tempDir, 'temurin-17-installer.msi');
|
|
207
|
+
|
|
208
|
+
// Download installer
|
|
209
|
+
await downloadWithRetry({
|
|
210
|
+
url,
|
|
211
|
+
destination: installerPath,
|
|
212
|
+
progressLabel: 'Downloading JDK installer',
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Run installer
|
|
216
|
+
info('Please complete the Java installation wizard...');
|
|
217
|
+
try {
|
|
218
|
+
await execAsync(`msiexec /i "${installerPath}" /passive`);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
warning('Automated installation failed. Please install manually.');
|
|
221
|
+
info(`Installer saved to: ${installerPath}`);
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Clean up
|
|
226
|
+
await fs.remove(installerPath);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Install Java on macOS
|
|
231
|
+
*/
|
|
232
|
+
async function installJavaMacOS(): Promise<void> {
|
|
233
|
+
// Check if Homebrew is available
|
|
234
|
+
try {
|
|
235
|
+
await execAsync('which brew');
|
|
236
|
+
info('Installing Java via Homebrew...');
|
|
237
|
+
|
|
238
|
+
const spinner = startSpinner('Installing openjdk@17...');
|
|
239
|
+
try {
|
|
240
|
+
await execAsync('brew install openjdk@17');
|
|
241
|
+
stopSpinner(spinner, true, 'Java installed via Homebrew');
|
|
242
|
+
|
|
243
|
+
// Link Java
|
|
244
|
+
info('Linking Java...');
|
|
245
|
+
await execAsync('sudo ln -sfn $(brew --prefix)/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk');
|
|
246
|
+
|
|
247
|
+
info('Add to your shell profile:');
|
|
248
|
+
info('export JAVA_HOME=$(/usr/libexec/java_home -v 17)');
|
|
249
|
+
} catch (error) {
|
|
250
|
+
stopSpinner(spinner, false, 'Failed to install via Homebrew');
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
} catch {
|
|
254
|
+
// Homebrew not available, download manually
|
|
255
|
+
info('Homebrew not found. Downloading JDK manually...');
|
|
256
|
+
info('Alternatively, install with: brew install openjdk@17');
|
|
257
|
+
console.log();
|
|
258
|
+
|
|
259
|
+
const url = getJDKDownloadURL();
|
|
260
|
+
if (!url) {
|
|
261
|
+
throw new Error('Could not determine JDK download URL');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const tempDir = os.tmpdir();
|
|
265
|
+
const pkgPath = path.join(tempDir, 'temurin-17.pkg');
|
|
266
|
+
|
|
267
|
+
await downloadWithRetry({
|
|
268
|
+
url,
|
|
269
|
+
destination: pkgPath,
|
|
270
|
+
progressLabel: 'Downloading JDK package',
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
info('Please install the downloaded package:');
|
|
274
|
+
info(`open "${pkgPath}"`);
|
|
275
|
+
|
|
276
|
+
// Try to open installer
|
|
277
|
+
try {
|
|
278
|
+
await execAsync(`open "${pkgPath}"`);
|
|
279
|
+
} catch {
|
|
280
|
+
warning('Could not open installer automatically');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Install Java on Linux
|
|
287
|
+
*/
|
|
288
|
+
async function installJavaLinux(): Promise<void> {
|
|
289
|
+
// Detect package manager
|
|
290
|
+
let packageManager: 'apt' | 'dnf' | 'yum' | 'pacman' | null = null;
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
await execAsync('which apt');
|
|
294
|
+
packageManager = 'apt';
|
|
295
|
+
} catch {
|
|
296
|
+
try {
|
|
297
|
+
await execAsync('which dnf');
|
|
298
|
+
packageManager = 'dnf';
|
|
299
|
+
} catch {
|
|
300
|
+
try {
|
|
301
|
+
await execAsync('which yum');
|
|
302
|
+
packageManager = 'yum';
|
|
303
|
+
} catch {
|
|
304
|
+
try {
|
|
305
|
+
await execAsync('which pacman');
|
|
306
|
+
packageManager = 'pacman';
|
|
307
|
+
} catch {
|
|
308
|
+
// No package manager found
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (!packageManager) {
|
|
315
|
+
info('Could not detect package manager. Please install Java 17+ manually:');
|
|
316
|
+
info('https://adoptium.net/temurin/releases/?version=17');
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
info(`Installing Java via ${packageManager}...`);
|
|
321
|
+
const spinner = startSpinner('Installing openjdk-17-jdk...');
|
|
322
|
+
|
|
323
|
+
try {
|
|
324
|
+
switch (packageManager) {
|
|
325
|
+
case 'apt':
|
|
326
|
+
await execAsync('sudo apt update && sudo apt install -y openjdk-17-jdk');
|
|
327
|
+
break;
|
|
328
|
+
case 'dnf':
|
|
329
|
+
await execAsync('sudo dnf install -y java-17-openjdk-devel');
|
|
330
|
+
break;
|
|
331
|
+
case 'yum':
|
|
332
|
+
await execAsync('sudo yum install -y java-17-openjdk-devel');
|
|
333
|
+
break;
|
|
334
|
+
case 'pacman':
|
|
335
|
+
await execAsync('sudo pacman -S --noconfirm jdk17-openjdk');
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
stopSpinner(spinner, true, 'Java installed successfully');
|
|
340
|
+
|
|
341
|
+
// Try to set JAVA_HOME
|
|
342
|
+
info('Add to your shell profile (~/.bashrc or ~/.zshrc):');
|
|
343
|
+
info('export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64');
|
|
344
|
+
info('export PATH=$JAVA_HOME/bin:$PATH');
|
|
345
|
+
} catch (error) {
|
|
346
|
+
stopSpinner(spinner, false, 'Installation failed');
|
|
347
|
+
warning('You may need to run the install command manually with sudo');
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Verify Java installation
|
|
354
|
+
*/
|
|
355
|
+
export async function verifyJavaInstallation(): Promise<boolean> {
|
|
356
|
+
const java = await detectJava();
|
|
357
|
+
|
|
358
|
+
if (!java) {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const compatible = await isJavaCompatible(java.version);
|
|
363
|
+
if (!compatible) {
|
|
364
|
+
warning(`Java ${java.version} is installed but version 17+ is required`);
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return true;
|
|
369
|
+
}
|