@archznn/xavva 2.4.0 → 2.6.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/README.md +25 -4
- package/package.json +4 -2
- package/src/commands/DeployCommand.ts +31 -18
- package/src/commands/DoctorCommand.ts +129 -76
- package/src/commands/LogsCommand.ts +1 -1
- package/src/commands/RunCommand.ts +21 -11
- package/src/index.ts +1 -1
- package/src/services/BrowserService.ts +12 -9
- package/src/services/BuildService.ts +134 -5
- package/src/services/EmbeddedTomcatService.ts +45 -36
- package/src/services/LogAnalyzer.ts +4 -4
- package/src/services/TomcatService.ts +86 -13
- package/src/services/WatcherService.ts +41 -3
- package/src/types/config.ts +1 -0
- package/src/utils/constants.ts +2 -2
- package/src/utils/platform.ts +323 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Utilities - Helpers para detecção e adaptação multiplataforma
|
|
3
|
+
*
|
|
4
|
+
* Centraliza toda a lógica de diferenciação entre Windows, Linux e macOS.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import os from "os";
|
|
8
|
+
import path from "path";
|
|
9
|
+
|
|
10
|
+
export type Platform = "win32" | "linux" | "darwin";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Retorna a plataforma atual normalizada
|
|
14
|
+
*/
|
|
15
|
+
export function getPlatform(): Platform {
|
|
16
|
+
const platform = process.platform;
|
|
17
|
+
if (platform === "win32") return "win32";
|
|
18
|
+
if (platform === "darwin") return "darwin";
|
|
19
|
+
return "linux";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Verifica se está rodando no Windows
|
|
24
|
+
*/
|
|
25
|
+
export function isWindows(): boolean {
|
|
26
|
+
return getPlatform() === "win32";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Verifica se está rodando no Linux
|
|
31
|
+
*/
|
|
32
|
+
export function isLinux(): boolean {
|
|
33
|
+
return getPlatform() === "linux";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Verifica se está rodando no macOS
|
|
38
|
+
*/
|
|
39
|
+
export function isMacOS(): boolean {
|
|
40
|
+
return getPlatform() === "darwin";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Retorna a extensão de script apropriada (.bat para Windows, .sh para Unix)
|
|
45
|
+
*/
|
|
46
|
+
export function getScriptExt(): string {
|
|
47
|
+
return isWindows() ? ".bat" : ".sh";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Retorna o nome do binário Java apropriado (java.exe para Windows, java para Unix)
|
|
52
|
+
*/
|
|
53
|
+
export function getJavaBinary(): string {
|
|
54
|
+
return isWindows() ? "java.exe" : "java";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Retorna o caminho completo para o binário Java se JAVA_HOME estiver definido
|
|
59
|
+
*/
|
|
60
|
+
export function getJavaPath(): string {
|
|
61
|
+
if (process.env.JAVA_HOME) {
|
|
62
|
+
const javaBin = path.join(process.env.JAVA_HOME, "bin", getJavaBinary());
|
|
63
|
+
return javaBin;
|
|
64
|
+
}
|
|
65
|
+
return getJavaBinary();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Retorna o script catalina apropriado (catalina.bat ou catalina.sh)
|
|
70
|
+
*/
|
|
71
|
+
export function getCatalinaScript(): string {
|
|
72
|
+
return `catalina${getScriptExt()}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Retorna o script startup apropriado
|
|
77
|
+
*/
|
|
78
|
+
export function getStartupScript(): string {
|
|
79
|
+
return `startup${getScriptExt()}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Retorna o script shutdown apropriado
|
|
84
|
+
*/
|
|
85
|
+
export function getShutdownScript(): string {
|
|
86
|
+
return `shutdown${getScriptExt()}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Retorna o comando Maven apropriado
|
|
91
|
+
*/
|
|
92
|
+
export function getMavenCommand(): string {
|
|
93
|
+
return isWindows() ? "mvn.cmd" : "mvn";
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Retorna o comando Gradle apropriado
|
|
98
|
+
*/
|
|
99
|
+
export function getGradleCommand(): string {
|
|
100
|
+
return isWindows() ? "gradle.bat" : "gradle";
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Retorna a extensão de arquivo de download do Tomcat (.zip para Windows, .tar.gz para Unix)
|
|
105
|
+
*/
|
|
106
|
+
export function getTomcatArchiveExt(): string {
|
|
107
|
+
return isWindows() ? ".zip" : ".tar.gz";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Retorna o nome do arquivo do Tomcat para download
|
|
112
|
+
*/
|
|
113
|
+
export function getTomcatArchiveName(version: string): string {
|
|
114
|
+
const baseName = `apache-tomcat-${version}`;
|
|
115
|
+
if (isWindows()) {
|
|
116
|
+
return `${baseName}-windows-x64.zip`;
|
|
117
|
+
}
|
|
118
|
+
if (isMacOS()) {
|
|
119
|
+
// macOS usa a mesma versão do Linux (tar.gz)
|
|
120
|
+
return `${baseName}.tar.gz`;
|
|
121
|
+
}
|
|
122
|
+
return `${baseName}.tar.gz`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Retorna a URL de download do Tomcat baseada na versão e plataforma
|
|
127
|
+
*/
|
|
128
|
+
export function getTomcatDownloadUrl(version: string): string {
|
|
129
|
+
const majorVersion = version.split(".")[0];
|
|
130
|
+
const archiveName = getTomcatArchiveName(version);
|
|
131
|
+
|
|
132
|
+
// URL primária (CDN Apache)
|
|
133
|
+
return `https://dlcdn.apache.org/tomcat/tomcat-${majorVersion}/v${version}/bin/${archiveName}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Retorna a URL alternativa (archive) caso a primária falhe
|
|
138
|
+
*/
|
|
139
|
+
export function getTomcatArchiveUrl(version: string): string {
|
|
140
|
+
const majorVersion = version.split(".")[0];
|
|
141
|
+
const archiveName = getTomcatArchiveName(version);
|
|
142
|
+
|
|
143
|
+
// URL alternativa (archive Apache)
|
|
144
|
+
return `https://archive.apache.org/dist/tomcat/tomcat-${majorVersion}/v${version}/bin/${archiveName}`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Retorna o comando para extrair um arquivo
|
|
149
|
+
* Retorna null se não for possível determinar
|
|
150
|
+
*/
|
|
151
|
+
export function getExtractCommand(archivePath: string, destDir: string): string[] | null {
|
|
152
|
+
if (isWindows()) {
|
|
153
|
+
// Windows: usa PowerShell para extrair
|
|
154
|
+
if (archivePath.endsWith(".zip")) {
|
|
155
|
+
return [
|
|
156
|
+
"powershell",
|
|
157
|
+
"-command",
|
|
158
|
+
`Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`,
|
|
159
|
+
];
|
|
160
|
+
}
|
|
161
|
+
// Para .tar.gz no Windows (PowerShell 5.1+)
|
|
162
|
+
if (archivePath.endsWith(".tar.gz") || archivePath.endsWith(".tgz")) {
|
|
163
|
+
return [
|
|
164
|
+
"powershell",
|
|
165
|
+
"-command",
|
|
166
|
+
`tar -xzf '${archivePath}' -C '${destDir}'`,
|
|
167
|
+
];
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
// Linux/Mac: usa tar
|
|
171
|
+
if (archivePath.endsWith(".tar.gz") || archivePath.endsWith(".tgz")) {
|
|
172
|
+
return ["tar", "-xzf", archivePath, "-C", destDir];
|
|
173
|
+
}
|
|
174
|
+
// Para .zip no Linux/Mac
|
|
175
|
+
if (archivePath.endsWith(".zip")) {
|
|
176
|
+
// Tenta unzip primeiro, depois tar
|
|
177
|
+
return ["unzip", "-q", "-o", archivePath, "-d", destDir];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Retorna o comando para verificar se uma porta está em uso
|
|
185
|
+
*/
|
|
186
|
+
export function getPortCheckCommand(port: number): string[] {
|
|
187
|
+
if (isWindows()) {
|
|
188
|
+
return ["cmd", "/c", `netstat -ano | findstr :${port}`];
|
|
189
|
+
}
|
|
190
|
+
// Linux/Mac: tenta lsof, ss, ou netstat
|
|
191
|
+
// Preferência por lsof (mais comum)
|
|
192
|
+
return ["sh", "-c", `lsof -i :${port} 2>/dev/null || ss -tlnp 2>/dev/null | grep ':${port}' || netstat -tlnp 2>/dev/null | grep ':${port}'`];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Retorna o comando para matar um processo pelo PID
|
|
197
|
+
*/
|
|
198
|
+
export function getKillCommand(pid: number | string): string[] {
|
|
199
|
+
if (isWindows()) {
|
|
200
|
+
return ["taskkill", "/F", "/PID", String(pid)];
|
|
201
|
+
}
|
|
202
|
+
return ["kill", "-9", String(pid)];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Retorna o comando para obter uso de memória de um processo
|
|
207
|
+
*/
|
|
208
|
+
export function getMemoryCommand(pid: number): string[] | null {
|
|
209
|
+
if (isWindows()) {
|
|
210
|
+
return [
|
|
211
|
+
"powershell",
|
|
212
|
+
"-command",
|
|
213
|
+
`(Get-Process -Id ${pid}).WorkingSet64 / 1MB`,
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
// Linux: /proc/<pid>/status tem VmRSS em kB
|
|
217
|
+
if (isLinux()) {
|
|
218
|
+
return ["sh", "-c", `cat /proc/${pid}/status 2>/dev/null | grep VmRSS | awk '{print int($2/1024)}'`];
|
|
219
|
+
}
|
|
220
|
+
// macOS: usa ps
|
|
221
|
+
if (isMacOS()) {
|
|
222
|
+
return ["ps", "-o", "rss=", "-p", String(pid)];
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Retorna o comando para abrir uma URL no navegador padrão
|
|
229
|
+
*/
|
|
230
|
+
export function getOpenBrowserCommand(): string {
|
|
231
|
+
if (isWindows()) {
|
|
232
|
+
return "start";
|
|
233
|
+
}
|
|
234
|
+
if (isMacOS()) {
|
|
235
|
+
return "open";
|
|
236
|
+
}
|
|
237
|
+
return "xdg-open";
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Retorna o comando para abrir uma URL no navegador (array para spawn)
|
|
242
|
+
*/
|
|
243
|
+
export function getOpenBrowserArgs(url: string): string[] {
|
|
244
|
+
const cmd = getOpenBrowserCommand();
|
|
245
|
+
if (isWindows()) {
|
|
246
|
+
// Windows: start "" "url" (o "" é necessário para títulos de janela)
|
|
247
|
+
return [cmd, "", url];
|
|
248
|
+
}
|
|
249
|
+
return [cmd, url];
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Retorna o comando para encontrar um binário no PATH
|
|
254
|
+
*/
|
|
255
|
+
export function getWhichCommand(binary: string): string[] {
|
|
256
|
+
if (isWindows()) {
|
|
257
|
+
return ["where", binary];
|
|
258
|
+
}
|
|
259
|
+
return ["which", binary];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Retorna o separador de classpath apropriado
|
|
264
|
+
*/
|
|
265
|
+
export function getClasspathSeparator(): string {
|
|
266
|
+
return path.delimiter;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Normaliza um caminho para uso em classpath (converte backslash para forward slash)
|
|
271
|
+
*/
|
|
272
|
+
export function normalizeClasspathPath(p: string): string {
|
|
273
|
+
return p.replace(/\\/g, "/");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Retorna o comando para extrair um WAR/JAR (usando jar ou unzip)
|
|
278
|
+
*/
|
|
279
|
+
export function getWarExtractCommand(warPath: string, destDir: string): string[] {
|
|
280
|
+
// Tenta usar jar (disponível em qualquer JDK)
|
|
281
|
+
return ["jar", "xf", warPath];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Retorna a URL de download do JetBrains Runtime (JBR) com DCEVM
|
|
286
|
+
*/
|
|
287
|
+
export function getJbrDownloadUrl(version: string = "21"): string {
|
|
288
|
+
// JBR 21 é a versão recomendada
|
|
289
|
+
if (isWindows()) {
|
|
290
|
+
return `https://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-${version}.0.6-windows-x64-b895.97.tar.gz`;
|
|
291
|
+
}
|
|
292
|
+
if (isMacOS()) {
|
|
293
|
+
return `https://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-${version}.0.6-osx-x64-b895.97.tar.gz`;
|
|
294
|
+
}
|
|
295
|
+
// Linux x64
|
|
296
|
+
return `https://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-${version}.0.6-linux-x64-b895.97.tar.gz`;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Retorna o comando para extrair um .tar.gz
|
|
301
|
+
*/
|
|
302
|
+
export function getTarExtractCommand(tarPath: string, destDir: string): string[] {
|
|
303
|
+
if (isWindows()) {
|
|
304
|
+
// Windows 10+ tem tar nativo via PowerShell
|
|
305
|
+
return ["powershell", "-command", `tar -xzf '${tarPath}' -C '${destDir}'`];
|
|
306
|
+
}
|
|
307
|
+
return ["tar", "-xzf", tarPath, "-C", destDir];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Constrói o caminho completo para o script catalina
|
|
312
|
+
*/
|
|
313
|
+
export function getCatalinaPath(tomcatHome: string): string {
|
|
314
|
+
return path.join(tomcatHome, "bin", getCatalinaScript());
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Verifica se o script catalina existe no diretório do Tomcat
|
|
319
|
+
*/
|
|
320
|
+
export function hasCatalinaScript(tomcatHome: string): boolean {
|
|
321
|
+
const { existsSync } = require("fs");
|
|
322
|
+
return existsSync(getCatalinaPath(tomcatHome));
|
|
323
|
+
}
|