@archznn/xavva 2.6.0 → 2.8.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 +55 -0
- package/package.json +4 -2
- package/src/commands/CompletionCommand.ts +212 -0
- package/src/commands/ConfigCommand.ts +184 -0
- package/src/commands/DeployCommand.ts +2 -1
- package/src/commands/EncodingCommand.ts +351 -0
- package/src/commands/HealthCommand.ts +302 -0
- package/src/commands/HelpCommand.ts +42 -0
- package/src/commands/HistoryCommand.ts +49 -0
- package/src/commands/InitCommand.ts +148 -0
- package/src/commands/RedoCommand.ts +36 -0
- package/src/config/versions.ts +63 -0
- package/src/di/container.ts +249 -0
- package/src/errors/ErrorHandler.ts +249 -0
- package/src/errors/XavvaError.ts +273 -0
- package/src/index.ts +136 -96
- package/src/services/AuditService.ts +3 -2
- package/src/services/BrowserService.ts +127 -16
- package/src/services/DeployWatcher.ts +183 -0
- package/src/services/EmbeddedTomcatService.ts +67 -37
- package/src/services/EncodingService.ts +548 -0
- package/src/services/FileWatcher.ts +243 -0
- package/src/services/HistoryService.ts +73 -0
- package/src/services/NotificationService.ts +145 -0
- package/src/services/TomcatService.ts +59 -26
- package/src/types/args.ts +151 -0
- package/src/types/config.ts +6 -0
- package/src/types/index.ts +7 -0
- package/src/utils/PathUtils.ts +221 -0
- package/src/utils/ProgressBar.ts +182 -0
- package/src/utils/config.ts +6 -0
- package/src/utils/parsers/JavaParser.ts +413 -0
- package/src/utils/platform.ts +2 -2
- package/src/services/WatcherService.ts +0 -117
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Logger } from "../utils/ui";
|
|
2
|
+
import { ProgressBar, ThemedSpinner } from "../utils/ProgressBar";
|
|
3
|
+
import { VERSIONS, getAvailableTomcatVersions, isSupportedTomcatVersion } from "../config/versions";
|
|
2
4
|
import {
|
|
3
5
|
existsSync,
|
|
4
6
|
mkdirSync,
|
|
@@ -45,25 +47,10 @@ export class EmbeddedTomcatService {
|
|
|
45
47
|
private downloadUrl: string;
|
|
46
48
|
private isInstalled: boolean = false;
|
|
47
49
|
|
|
48
|
-
// Versões
|
|
49
|
-
// URLs são construídas dinamicamente baseadas na plataforma
|
|
50
|
-
private static readonly VERSIONS: Record<
|
|
51
|
-
string,
|
|
52
|
-
{ sha512: string }
|
|
53
|
-
> = {
|
|
54
|
-
"10.1.52": {
|
|
55
|
-
sha512: "",
|
|
56
|
-
},
|
|
57
|
-
"9.0.115": {
|
|
58
|
-
sha512: "",
|
|
59
|
-
},
|
|
60
|
-
"11.0.18": {
|
|
61
|
-
sha512: "",
|
|
62
|
-
},
|
|
63
|
-
};
|
|
50
|
+
// Versões agora centralizadas em src/config/versions.ts
|
|
64
51
|
|
|
65
52
|
constructor(options: EmbeddedTomcatOptions) {
|
|
66
|
-
this.version = options.version ||
|
|
53
|
+
this.version = options.version || VERSIONS.TOMCAT.DEFAULT;
|
|
67
54
|
this.port = options.port || 8080;
|
|
68
55
|
this.webappPath = path.resolve(options.webappPath);
|
|
69
56
|
this.contextPath = options.contextPath || "/";
|
|
@@ -71,7 +58,7 @@ export class EmbeddedTomcatService {
|
|
|
71
58
|
this.tomcatHome = path.join(this.baseDir, this.version);
|
|
72
59
|
|
|
73
60
|
// Constrói URL de download baseada na plataforma
|
|
74
|
-
const versionInfo =
|
|
61
|
+
const versionInfo = isSupportedTomcatVersion(this.version) ? { sha512: "" } : null;
|
|
75
62
|
if (versionInfo) {
|
|
76
63
|
// Usa URL primária (CDN Apache)
|
|
77
64
|
this.downloadUrl = getTomcatDownloadUrl(this.version);
|
|
@@ -354,34 +341,76 @@ export class EmbeddedTomcatService {
|
|
|
354
341
|
* Lista versões disponíveis
|
|
355
342
|
*/
|
|
356
343
|
static getAvailableVersions(): string[] {
|
|
357
|
-
return
|
|
344
|
+
return getAvailableTomcatVersions();
|
|
358
345
|
}
|
|
359
346
|
|
|
360
347
|
/**
|
|
361
348
|
* Download com progresso
|
|
362
349
|
*/
|
|
363
350
|
private async downloadFile(url: string, destPath: string): Promise<void> {
|
|
364
|
-
const
|
|
351
|
+
const response = await fetch(url);
|
|
365
352
|
|
|
366
|
-
|
|
367
|
-
|
|
353
|
+
if (!response.ok) {
|
|
354
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
355
|
+
}
|
|
368
356
|
|
|
369
|
-
|
|
370
|
-
|
|
357
|
+
const totalSize = parseInt(response.headers.get("content-length") || "0");
|
|
358
|
+
|
|
359
|
+
// Se temos content-length, usar progress bar
|
|
360
|
+
if (totalSize > 0) {
|
|
361
|
+
const progress = new ProgressBar({
|
|
362
|
+
title: `Baixando Tomcat ${this.version}`,
|
|
363
|
+
total: totalSize,
|
|
364
|
+
width: 25
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
const reader = response.body?.getReader();
|
|
368
|
+
if (!reader) {
|
|
369
|
+
throw new Error("Response body não disponível");
|
|
371
370
|
}
|
|
372
371
|
|
|
373
|
-
const
|
|
374
|
-
|
|
372
|
+
const chunks: Uint8Array[] = [];
|
|
373
|
+
let received = 0;
|
|
374
|
+
|
|
375
|
+
while (true) {
|
|
376
|
+
const { done, value } = await reader.read();
|
|
377
|
+
if (done) break;
|
|
378
|
+
|
|
379
|
+
chunks.push(value);
|
|
380
|
+
received += value.length;
|
|
381
|
+
progress.update(received);
|
|
382
|
+
}
|
|
375
383
|
|
|
376
|
-
|
|
384
|
+
progress.complete();
|
|
377
385
|
|
|
378
|
-
|
|
386
|
+
// Concatena chunks e salva
|
|
387
|
+
const allChunks = new Uint8Array(received);
|
|
388
|
+
let position = 0;
|
|
389
|
+
for (const chunk of chunks) {
|
|
390
|
+
allChunks.set(chunk, position);
|
|
391
|
+
position += chunk.length;
|
|
392
|
+
}
|
|
379
393
|
|
|
380
|
-
|
|
394
|
+
await fsPromises.writeFile(destPath, allChunks);
|
|
395
|
+
|
|
396
|
+
const sizeMB = (received / 1024 / 1024).toFixed(1);
|
|
381
397
|
Logger.info("Download", `${sizeMB} MB baixados`);
|
|
382
|
-
}
|
|
383
|
-
spinner
|
|
384
|
-
|
|
398
|
+
} else {
|
|
399
|
+
// Sem content-length, usar spinner temático
|
|
400
|
+
const spinner = new ThemedSpinner();
|
|
401
|
+
const stop = spinner.start(`Baixando Tomcat ${this.version}`, "dots", "download");
|
|
402
|
+
|
|
403
|
+
try {
|
|
404
|
+
const buffer = await response.arrayBuffer();
|
|
405
|
+
await fsPromises.writeFile(destPath, Buffer.from(buffer));
|
|
406
|
+
stop(true);
|
|
407
|
+
|
|
408
|
+
const sizeMB = (buffer.byteLength / 1024 / 1024).toFixed(1);
|
|
409
|
+
Logger.info("Download", `${sizeMB} MB baixados`);
|
|
410
|
+
} catch (error) {
|
|
411
|
+
stop(false);
|
|
412
|
+
throw error;
|
|
413
|
+
}
|
|
385
414
|
}
|
|
386
415
|
}
|
|
387
416
|
|
|
@@ -389,13 +418,14 @@ export class EmbeddedTomcatService {
|
|
|
389
418
|
* Extrai arquivo de arquivos (ZIP ou tar.gz)
|
|
390
419
|
*/
|
|
391
420
|
private async extractZip(zipPath: string, destDir: string): Promise<void> {
|
|
392
|
-
const spinner =
|
|
421
|
+
const spinner = new ThemedSpinner();
|
|
422
|
+
const stop = spinner.start("Extraindo arquivos", "pulse", "build");
|
|
393
423
|
|
|
394
424
|
return new Promise((resolve, reject) => {
|
|
395
425
|
const cmd = getExtractCommand(zipPath, destDir);
|
|
396
426
|
|
|
397
427
|
if (!cmd) {
|
|
398
|
-
|
|
428
|
+
stop(false);
|
|
399
429
|
reject(new Error(`Formato de arquivo não suportado: ${path.extname(zipPath)}`));
|
|
400
430
|
return;
|
|
401
431
|
}
|
|
@@ -404,16 +434,16 @@ export class EmbeddedTomcatService {
|
|
|
404
434
|
|
|
405
435
|
extractProcess.on("close", (code) => {
|
|
406
436
|
if (code === 0) {
|
|
407
|
-
|
|
437
|
+
stop(true);
|
|
408
438
|
resolve();
|
|
409
439
|
} else {
|
|
410
|
-
|
|
440
|
+
stop(false);
|
|
411
441
|
reject(new Error(`Falha ao extrair (código ${code})`));
|
|
412
442
|
}
|
|
413
443
|
});
|
|
414
444
|
|
|
415
445
|
extractProcess.on("error", (err) => {
|
|
416
|
-
|
|
446
|
+
stop(false);
|
|
417
447
|
reject(err);
|
|
418
448
|
});
|
|
419
449
|
});
|