@archznn/xavva 3.1.2 → 3.2.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.
Files changed (80) hide show
  1. package/README.md +221 -12
  2. package/package.json +3 -2
  3. package/src/commands/AuditCommand.ts +12 -10
  4. package/src/commands/BuildCommand.ts +9 -7
  5. package/src/commands/ChangelogCommand.ts +5 -5
  6. package/src/commands/CleanCommand.ts +242 -0
  7. package/src/commands/CompletionCommand.ts +7 -7
  8. package/src/commands/DbCommand.ts +43 -14
  9. package/src/commands/DeployCommand.ts +252 -229
  10. package/src/commands/DepsCommand.ts +174 -174
  11. package/src/commands/DockerCommand.ts +35 -4
  12. package/src/commands/DoctorCommand.ts +252 -239
  13. package/src/commands/EncodingCommand.ts +26 -19
  14. package/src/commands/HealthCommand.ts +7 -7
  15. package/src/commands/HelpCommand.ts +34 -14
  16. package/src/commands/HistoryCommand.ts +5 -5
  17. package/src/commands/HttpCommand.ts +27 -1
  18. package/src/commands/IdeCommand.ts +313 -0
  19. package/src/commands/InitCommand.ts +26 -25
  20. package/src/commands/LogsCommand.ts +8 -6
  21. package/src/commands/ProfilesCommand.ts +6 -6
  22. package/src/commands/RedoCommand.ts +2 -2
  23. package/src/commands/RunCommand.ts +64 -24
  24. package/src/commands/StartCommand.ts +9 -7
  25. package/src/commands/TestCommand.ts +25 -1
  26. package/src/commands/TomcatCommand.ts +232 -88
  27. package/src/config/versions.ts +111 -9
  28. package/src/di/container.ts +239 -105
  29. package/src/errors/ErrorHandler.ts +23 -19
  30. package/src/errors/errorMessages.ts +235 -0
  31. package/src/index.ts +20 -6
  32. package/src/logging/FileLogger.ts +235 -0
  33. package/src/logging/Logger.ts +545 -0
  34. package/src/logging/OperationLogger.ts +296 -0
  35. package/src/logging/ProgressLogger.ts +187 -0
  36. package/src/logging/TableLogger.ts +246 -0
  37. package/src/logging/colors.ts +167 -0
  38. package/src/logging/constants.ts +176 -0
  39. package/src/logging/formatters.ts +337 -0
  40. package/src/logging/index.ts +93 -0
  41. package/src/logging/types.ts +64 -0
  42. package/src/plugins/PluginManager.ts +325 -0
  43. package/src/plugins/types.ts +82 -0
  44. package/src/services/AuditService.ts +5 -3
  45. package/src/services/BuildService.ts +15 -17
  46. package/src/services/DashboardService.ts +14 -3
  47. package/src/services/DbService.ts +35 -34
  48. package/src/services/DependencyAnalyzerService.ts +18 -18
  49. package/src/services/DependencyCacheService.ts +303 -0
  50. package/src/services/DeployWatcher.ts +127 -23
  51. package/src/services/DockerService.ts +3 -3
  52. package/src/services/EmbeddedTomcatService.ts +13 -12
  53. package/src/services/FileWatcher.ts +15 -7
  54. package/src/services/HttpService.ts +5 -5
  55. package/src/services/LogAnalyzer.ts +26 -22
  56. package/src/services/PerformanceProfiler.ts +267 -0
  57. package/src/services/ProjectService.ts +3 -0
  58. package/src/services/TestService.ts +3 -3
  59. package/src/services/TomcatService.ts +46 -25
  60. package/src/services/tomcat/TomcatBackupManager.ts +330 -0
  61. package/src/services/tomcat/TomcatChecksumVerifier.ts +211 -0
  62. package/src/services/tomcat/TomcatCompatibilityChecker.ts +298 -0
  63. package/src/services/tomcat/TomcatDownloadCache.ts +250 -0
  64. package/src/services/tomcat/TomcatDownloadService.ts +335 -0
  65. package/src/services/tomcat/TomcatInstallerService.ts +474 -0
  66. package/src/services/tomcat/TomcatMirrorManager.ts +181 -0
  67. package/src/services/tomcat/index.ts +36 -0
  68. package/src/services/tomcat/types.ts +120 -0
  69. package/src/types/args.ts +68 -1
  70. package/src/types/configSchema.ts +174 -0
  71. package/src/utils/ChangelogGenerator.ts +11 -11
  72. package/src/utils/LoggerLevel.ts +44 -20
  73. package/src/utils/ProgressBar.ts +87 -46
  74. package/src/utils/argsParser.ts +260 -0
  75. package/src/utils/config.ts +340 -189
  76. package/src/utils/constants.ts +87 -9
  77. package/src/utils/dryRun.ts +192 -0
  78. package/src/utils/processManager.ts +23 -7
  79. package/src/utils/security.ts +293 -0
  80. package/src/utils/ui.ts +299 -428
@@ -3,182 +3,182 @@ import type { AppConfig, CLIArguments } from "../types/config";
3
3
  import type { DependencyAnalysisResult } from "../services/DependencyAnalyzerService";
4
4
  import { DependencyAnalyzerService } from "../services/DependencyAnalyzerService";
5
5
  import { AuditService } from "../services/AuditService";
6
- import { Logger } from "../utils/ui";
6
+ import { Logger } from "../logging";
7
7
  import { ProcessManager } from "../utils/processManager";
8
8
  import fs from "fs";
9
+ import path from "path";
9
10
 
10
11
  export class DepsCommand implements Command {
11
- private config!: AppConfig;
12
-
13
- async execute(config: AppConfig, args?: CLIArguments): Promise<void> {
14
- this.config = config;
15
- const analyzer = new DependencyAnalyzerService(config.project);
16
- analyzer.setVerbose(!!args?.verbose);
17
-
18
- Logger.section("Análise de Dependências");
19
- Logger.info("Ferramenta", config.project.buildTool.toUpperCase());
20
- Logger.info("Diretório", process.cwd());
21
-
22
- const spinner = Logger.spinner("Analisando dependências...");
23
-
24
- try {
25
- const result = await analyzer.analyze();
26
- spinner();
27
-
28
- // Se não encontrou dependências, mostrar ajuda
29
- if (result.dependencies.length === 0) {
30
- Logger.warn("Nenhuma dependência encontrada!");
31
- Logger.info("Possíveis causas:", "");
32
- Logger.log(" Projeto não foi compilado ainda (execute: mvn compile)");
33
- Logger.log(" • Maven não está no PATH");
34
- Logger.log(" • Arquivo pom.xml/build.gradle não encontrado");
35
- Logger.log(" • Erro de parsing no arquivo de configuração");
36
- Logger.newline();
37
- Logger.log(`${Logger.C.primary}Dica:${Logger.C.reset} Execute com --verbose para mais detalhes`);
38
- return;
39
- }
40
-
41
- // Verificar vulnerabilidades se solicitado
42
- if (args?.["scan"] !== false) {
43
- Logger.step("Verificando vulnerabilidades");
44
- // Integração com AuditService para check de vulnerabilidades
45
- // nas dependências do projeto
46
- }
47
-
48
- // Exibir relatório
49
- const report = analyzer.generateReport(result);
50
- console.log(report);
51
-
52
- // Ações adicionais baseadas em flags
53
- if (args?.["update-safe"] || args?.["updateSafe"]) {
54
- await this.performUpdateSafe(analyzer, result, config.project.buildTool);
55
- }
56
-
57
- if (args?.["fix"]) {
58
- await this.suggestFixes(result, config.project.buildTool);
59
- }
60
-
61
- // Exportar resultado se solicitado
62
- if (args?.["output"]) {
63
- this.exportReport(result, args["output"] as string);
64
- }
65
-
66
- // Sair com erro se houver conflitos críticos
67
- const hasErrors = result.conflicts.some(c => c.severity === "error");
68
- if (hasErrors && args?.["strict"]) {
69
- await ProcessManager.getInstance().shutdown(1);
70
- }
71
-
72
- } catch (error) {
73
- spinner(false);
74
- const message = error instanceof Error ? error.message : String(error);
75
- Logger.error(`Falha na análise: ${message}`);
76
- throw error;
77
- }
78
- }
79
-
80
- private async suggestFixes(result: DependencyAnalysisResult, buildTool: string): Promise<void> {
81
- if (result.conflicts.length === 0) {
82
- Logger.success("Nenhum conflito para resolver!");
83
- return;
84
- }
85
-
86
- Logger.newline();
87
- Logger.section("Sugestões de Correção");
88
-
89
- for (const conflict of result.conflicts) {
90
- Logger.log(`\n${Logger.C.primary}${conflict.groupId}:${conflict.artifactId}${Logger.C.reset}`);
91
-
92
- if (buildTool === "maven") {
93
- Logger.log(" Adicione ao pom.xml:");
94
- Logger.log(` ${Logger.C.dim}<dependencyManagement>${Logger.C.reset}`);
95
- Logger.log(` ${Logger.C.dim} <dependencies>${Logger.C.reset}`);
96
- Logger.log(` ${Logger.C.dim} <dependency>${Logger.C.reset}`);
97
- Logger.log(` ${Logger.C.dim} <groupId>${conflict.groupId}</groupId>${Logger.C.reset}`);
98
- Logger.log(` ${Logger.C.dim} <artifactId>${conflict.artifactId}</artifactId>${Logger.C.reset}`);
99
- Logger.log(` ${Logger.C.dim} <version>${conflict.versions[conflict.versions.length - 1]}</version>${Logger.C.reset}`);
100
- Logger.log(` ${Logger.C.dim} </dependency>${Logger.C.reset}`);
101
- Logger.log(` ${Logger.C.dim} </dependencies>${Logger.C.reset}`);
102
- Logger.log(` ${Logger.C.dim}</dependencyManagement>${Logger.C.reset}`);
103
- } else {
104
- Logger.log(" Adicione ao build.gradle:");
105
- Logger.log(` ${Logger.C.dim}implementation("${conflict.groupId}:${conflict.artifactId}:${conflict.versions[conflict.versions.length - 1]}")${Logger.C.reset}`);
106
- }
107
- }
108
- }
109
-
110
- private async performUpdateSafe(
111
- analyzer: DependencyAnalyzerService,
112
- result: DependencyAnalysisResult,
113
- buildTool: string
114
- ): Promise<void> {
115
- const safeUpdates = result.updates.filter(u => !u.isMajor);
116
-
117
- if (safeUpdates.length === 0) {
118
- Logger.info("", "Nenhuma atualização segura disponível");
119
- return;
120
- }
121
-
122
- Logger.newline();
123
- Logger.section("Atualizando Dependências (Safe Mode)");
124
- Logger.info("Atualizações a aplicar", String(safeUpdates.length));
125
-
126
- const spinner = Logger.spinner("Atualizando arquivos de configuração...");
127
-
128
- try {
129
- const updateResult = await analyzer.updateSafe(safeUpdates);
130
- spinner();
131
-
132
- if (updateResult.updated > 0) {
133
- Logger.success(`${updateResult.updated} dependências atualizadas`);
134
- Logger.info("", `Backup criado: ${buildTool === "maven" ? "pom.xml.backup" : "build.gradle.backup"}`);
135
-
136
- // Listar o que foi atualizado
137
- for (const update of safeUpdates.slice(0, 5)) {
138
- Logger.log(` ${Logger.C.success}↑${Logger.C.reset} ${update.groupId}:${update.artifactId} ${update.currentVersion} ${Logger.C.success}${update.latestVersion}${Logger.C.reset}`);
139
- }
140
- if (safeUpdates.length > 5) {
141
- Logger.log(` ${Logger.C.dim}... e mais ${safeUpdates.length - 5}${Logger.C.reset}`);
142
- }
143
-
144
- Logger.newline();
145
- Logger.log(`${Logger.C.warning}⚠️ Execute 'xavva build' para compilar e aplicar as mudanças${Logger.C.reset}`);
146
- Logger.log(`${Logger.C.primary}💡 Dica:${Logger.C.reset} Execute 'xavva audit' para verificar vulnerabilidades nas novas versões`);
147
- } else {
148
- Logger.warn("Nenhuma dependência foi atualizada");
149
- }
150
-
151
- if (updateResult.skipped > 0) {
152
- Logger.info("Dependências ignoradas", `${updateResult.skipped} (definidas via propriedades)`);
153
- }
154
-
155
- if (updateResult.errors.length > 0) {
156
- for (const error of updateResult.errors) {
157
- Logger.warn(error);
158
- }
159
- }
160
- } catch (error) {
161
- spinner(false);
162
- const message = error instanceof Error ? error.message : String(error);
163
- Logger.error(`Falha na atualização: ${message}`);
164
- }
165
- }
166
-
167
- private exportReport(
168
- result: DependencyAnalysisResult,
169
- outputPath: string
170
- ): void {
171
- const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../../package.json"), "utf-8"));
172
- const data = {
173
- timestamp: new Date().toISOString(),
174
- tool: "xavva",
175
- version: pkg.version,
176
- result
177
- };
178
-
179
- fs.writeFileSync(outputPath, JSON.stringify(data, null, 2));
180
- Logger.success(`Relatório exportado para: ${outputPath}`);
181
- }
12
+ private logger = Logger.getInstance();
13
+ private config!: AppConfig;
14
+
15
+ async execute(config: AppConfig, args?: CLIArguments): Promise<void> {
16
+ this.config = config;
17
+ const analyzer = new DependencyAnalyzerService(config.project);
18
+ analyzer.setVerbose(!!args?.verbose);
19
+
20
+ this.logger.section("Análise de Dependências");
21
+ this.logger.config("Ferramenta", config.project.buildTool.toUpperCase());
22
+ this.logger.config("Diretório", process.cwd());
23
+
24
+ const spinner = this.logger.spinner("Analisando dependências...");
25
+
26
+ try {
27
+ const result = await analyzer.analyze();
28
+ spinner.stop();
29
+
30
+ // Se não encontrou dependências, mostrar ajuda
31
+ if (result.dependencies.length === 0) {
32
+ this.logger.warn("Nenhuma dependência encontrada!");
33
+ this.logger.info("Possíveis causas:");
34
+ console.log(" • Projeto não foi compilado ainda (execute: mvn compile)");
35
+ console.log(" • Maven não está no PATH");
36
+ console.log(" • Arquivo pom.xml/build.gradle não encontrado");
37
+ console.log(" • Erro de parsing no arquivo de configuração");
38
+ this.logger.newline();
39
+ console.log(`Dica: Execute com --verbose para mais detalhes`);
40
+ return;
41
+ }
42
+
43
+ // Verificar vulnerabilidades se solicitado
44
+ if (args?.["scan"] !== false) {
45
+ this.logger.step("Verificando vulnerabilidades");
46
+ // Integração com AuditService para check de vulnerabilidades
47
+ // nas dependências do projeto
48
+ }
49
+
50
+ // Exibir relatório
51
+ const report = analyzer.generateReport(result);
52
+ console.log(report);
53
+
54
+ // Ações adicionais baseadas em flags
55
+ if (args?.["update-safe"] || args?.["updateSafe"]) {
56
+ await this.performUpdateSafe(analyzer, result, config.project.buildTool);
57
+ }
58
+
59
+ if (args?.["fix"]) {
60
+ await this.suggestFixes(result, config.project.buildTool);
61
+ }
62
+
63
+ // Exportar resultado se solicitado
64
+ if (args?.["output"]) {
65
+ this.exportReport(result, args["output"] as string);
66
+ }
67
+
68
+ // Sair com erro se houver conflitos críticos
69
+ const hasErrors = result.conflicts.some(c => c.severity === "error");
70
+ if (hasErrors && args?.["strict"]) {
71
+ await ProcessManager.getInstance().shutdown(1);
72
+ }
73
+
74
+ } catch (error) {
75
+ spinner.stop(false);
76
+ const message = error instanceof Error ? error.message : String(error);
77
+ this.logger.error(`Falha na análise: ${message}`);
78
+ throw error;
79
+ }
80
+ }
81
+
82
+ private async suggestFixes(result: DependencyAnalysisResult, buildTool: string): Promise<void> {
83
+ if (result.conflicts.length === 0) {
84
+ this.logger.success("Nenhum conflito para resolver!");
85
+ return;
86
+ }
87
+
88
+ this.logger.newline();
89
+ this.logger.section("Sugestões de Correção");
90
+
91
+ for (const conflict of result.conflicts) {
92
+ console.log(`\n${conflict.groupId}:${conflict.artifactId}`);
93
+
94
+ if (buildTool === "maven") {
95
+ console.log(" Adicione ao pom.xml:");
96
+ console.log(` <dependencyManagement>`);
97
+ console.log(` <dependencies>`);
98
+ console.log(` <dependency>`);
99
+ console.log(` <groupId>${conflict.groupId}</groupId>`);
100
+ console.log(` <artifactId>${conflict.artifactId}</artifactId>`);
101
+ console.log(` <version>${conflict.versions[conflict.versions.length - 1]}</version>`);
102
+ console.log(` </dependency>`);
103
+ console.log(` </dependencies>`);
104
+ console.log(` </dependencyManagement>`);
105
+ } else {
106
+ console.log(" Adicione ao build.gradle:");
107
+ console.log(` implementation("${conflict.groupId}:${conflict.artifactId}:${conflict.versions[conflict.versions.length - 1]}")`);
108
+ }
109
+ }
110
+ }
111
+
112
+ private async performUpdateSafe(
113
+ analyzer: DependencyAnalyzerService,
114
+ result: DependencyAnalysisResult,
115
+ buildTool: string
116
+ ): Promise<void> {
117
+ const safeUpdates = result.updates.filter(u => !u.isMajor);
118
+
119
+ if (safeUpdates.length === 0) {
120
+ this.logger.info("Nenhuma atualização segura disponível");
121
+ return;
122
+ }
123
+
124
+ this.logger.newline();
125
+ this.logger.section("Atualizando Dependências (Safe Mode)");
126
+ this.logger.config("Atualizações a aplicar", String(safeUpdates.length));
127
+
128
+ const spinner = this.logger.spinner("Atualizando arquivos de configuração...");
129
+
130
+ try {
131
+ const updateResult = await analyzer.updateSafe(safeUpdates);
132
+ spinner.stop();
133
+
134
+ if (updateResult.updated > 0) {
135
+ this.logger.success(`${updateResult.updated} dependências atualizadas`);
136
+ this.logger.info(`Backup criado: ${buildTool === "maven" ? "pom.xml.backup" : "build.gradle.backup"}`);
137
+
138
+ // Listar o que foi atualizado
139
+ for (const update of safeUpdates.slice(0, 5)) {
140
+ console.log(` ↑ ${update.groupId}:${update.artifactId} ${update.currentVersion} → ${update.latestVersion}`);
141
+ }
142
+ if (safeUpdates.length > 5) {
143
+ console.log(` ... e mais ${safeUpdates.length - 5}`);
144
+ }
145
+
146
+ this.logger.newline();
147
+ console.log(`! Execute 'xavva build' para compilar e aplicar as mudancas`);
148
+ console.log(`* Dica: Execute 'xavva audit' para verificar vulnerabilidades nas novas versoes`);
149
+ } else {
150
+ this.logger.warn("Nenhuma dependência foi atualizada");
151
+ }
152
+
153
+ if (updateResult.skipped > 0) {
154
+ this.logger.config("Dependências ignoradas", `${updateResult.skipped} (definidas via propriedades)`);
155
+ }
156
+
157
+ if (updateResult.errors.length > 0) {
158
+ for (const error of updateResult.errors) {
159
+ this.logger.warn(error);
160
+ }
161
+ }
162
+ } catch (error) {
163
+ spinner.stop(false);
164
+ const message = error instanceof Error ? error.message : String(error);
165
+ this.logger.error(`Falha na atualização: ${message}`);
166
+ }
167
+ }
168
+
169
+ private exportReport(
170
+ result: DependencyAnalysisResult,
171
+ outputPath: string
172
+ ): void {
173
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../../package.json"), "utf-8"));
174
+ const data = {
175
+ timestamp: new Date().toISOString(),
176
+ tool: "xavva",
177
+ version: pkg.version,
178
+ result
179
+ };
180
+
181
+ fs.writeFileSync(outputPath, JSON.stringify(data, null, 2));
182
+ this.logger.success(`Relatório exportado para: ${outputPath}`);
183
+ }
182
184
  }
183
-
184
- import path from "path";
@@ -6,12 +6,43 @@
6
6
  import type { Command } from "./Command";
7
7
  import type { AppConfig, CLIArguments } from "../types/config";
8
8
  import { DockerService, type DockerConfig } from "../services/DockerService";
9
- import { Logger } from "../utils/ui";
9
+ import { Logger, C } from "../utils/ui";
10
10
  import { ProcessManager } from "../utils/processManager";
11
11
 
12
12
  export class DockerCommand implements Command {
13
+ private showHelp(): void {
14
+ Logger.section("Docker Command");
15
+ Logger.log(`${C.bold}Usage:${C.reset} xavva docker <action> [options]`);
16
+ Logger.newline();
17
+ Logger.log(`${C.bold}Actions:${C.reset}`);
18
+ Logger.log(` ${C.primary}init${C.reset} Generate Dockerfile & docker-compose.yml`);
19
+ Logger.log(` ${C.primary}build${C.reset} Build Docker image`);
20
+ Logger.log(` ${C.primary}run${C.reset} Run development container`);
21
+ Logger.log(` ${C.primary}up${C.reset} Start with docker-compose`);
22
+ Logger.log(` ${C.primary}down${C.reset} Stop containers`);
23
+ Logger.log(` ${C.primary}status${C.reset} Show container status`);
24
+ Logger.newline();
25
+ Logger.log(`${C.bold}Options:${C.reset}`);
26
+ Logger.log(` --name <n> Image name`);
27
+ Logger.log(` --tag <t> Image tag`);
28
+ Logger.log(` --port <p> Port mapping`);
29
+ Logger.log(` -d, --detached Run in background`);
30
+ Logger.newline();
31
+ Logger.log(`${C.bold}Examples:${C.reset}`);
32
+ Logger.log(` xavva docker init`);
33
+ Logger.log(` xavva docker build --tag myapp:1.0`);
34
+ Logger.log(` xavva docker up -d`);
35
+ }
36
+
13
37
  async execute(config: AppConfig, args?: CLIArguments, positionals?: string[]): Promise<void> {
14
38
  const processManager = ProcessManager.getInstance();
39
+
40
+ // Mostra help se solicitado
41
+ if (args?.help) {
42
+ this.showHelp();
43
+ return;
44
+ }
45
+
15
46
  const action = positionals?.[1] || "status";
16
47
 
17
48
  const service = new DockerService();
@@ -109,9 +140,9 @@ export class DockerCommand implements Command {
109
140
 
110
141
  Logger.divider();
111
142
  Logger.info("Next steps", "");
112
- Logger.log(` ${Logger.C.gray}│${Logger.C.reset} ${Logger.C.primary}xavva docker build${Logger.C.reset} ${Logger.C.gray}- Build image${Logger.C.reset}`);
113
- Logger.log(` ${Logger.C.gray}│${Logger.C.reset} ${Logger.C.primary}xavva docker up${Logger.C.reset} ${Logger.C.gray}- Start containers${Logger.C.reset}`);
114
- Logger.log(` ${Logger.C.gray}│${Logger.C.reset} ${Logger.C.primary}xavva docker run${Logger.C.reset} ${Logger.C.gray}- Run dev mode${Logger.C.reset}`);
143
+ Logger.log(` ${C.gray}│${C.reset} ${C.primary}xavva docker build${C.reset} ${C.gray}- Build image${C.reset}`);
144
+ Logger.log(` ${C.gray}│${C.reset} ${C.primary}xavva docker up${C.reset} ${C.gray}- Start containers${C.reset}`);
145
+ Logger.log(` ${C.gray}│${C.reset} ${C.primary}xavva docker run${C.reset} ${C.gray}- Run dev mode${C.reset}`);
115
146
  Logger.endSection();
116
147
  }
117
148