@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
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Xavva is a high-performance CLI built with **Bun** that transforms the Java/Tomc
|
|
|
20
20
|
- 🔧 **Auto-Healing** — Automatic diagnosis and repair of common issues
|
|
21
21
|
- 🐱 **Embedded Tomcat** — Auto-install Tomcat, no manual setup needed
|
|
22
22
|
- 📦 **WAR Generation** — Build as .war file or exploded directory
|
|
23
|
+
- 🔤 **Encoding Converter** — Convert file encodings (UTF-8, Windows-1252, ISO-8859-1) and fix mojibake
|
|
23
24
|
|
|
24
25
|
---
|
|
25
26
|
|
|
@@ -56,6 +57,9 @@ xavva deps --update-safe
|
|
|
56
57
|
# Check for security vulnerabilities
|
|
57
58
|
xavva audit
|
|
58
59
|
|
|
60
|
+
# Convert file encoding (UTF-8 → Windows-1252)
|
|
61
|
+
xavva encoding convert --to cp1252 --backup src/main/java/
|
|
62
|
+
|
|
59
63
|
# Use embedded Tomcat (auto-install)
|
|
60
64
|
xavva dev --yes
|
|
61
65
|
```
|
|
@@ -91,6 +95,7 @@ xavva dev --yes
|
|
|
91
95
|
| `xavva profiles` | List available Maven/Gradle profiles |
|
|
92
96
|
| `xavva docs` | Generate endpoint documentation |
|
|
93
97
|
| `xavva tomcat` | Manage embedded Tomcat installations |
|
|
98
|
+
| `xavva encoding` | Convert file encodings (UTF-8, CP1252, ISO-8859-1) |
|
|
94
99
|
|
|
95
100
|
---
|
|
96
101
|
|
|
@@ -126,6 +131,56 @@ xavva dev --tomcat-version 9.0.115
|
|
|
126
131
|
|
|
127
132
|
---
|
|
128
133
|
|
|
134
|
+
## 🔤 File Encoding
|
|
135
|
+
|
|
136
|
+
The `xavva encoding` command helps you convert file encodings and fix mojibake (corrupted characters):
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Detect encoding of a file
|
|
140
|
+
xavva encoding detect src/main/java/MyClass.java
|
|
141
|
+
|
|
142
|
+
# Convert from UTF-8 to Windows-1252 (with backup)
|
|
143
|
+
xavva encoding convert --from utf-8 --to cp1252 --backup src/main/java/
|
|
144
|
+
|
|
145
|
+
# Convert a single file
|
|
146
|
+
xavva encoding convert --to cp1252 --backup src/main/java/MyClass.java
|
|
147
|
+
|
|
148
|
+
# Fix mojibake (e.g., "A��o" → "Ação")
|
|
149
|
+
xavva encoding fix src/main/java/MyClass.java
|
|
150
|
+
|
|
151
|
+
# List encodings of all files in src/
|
|
152
|
+
xavva encoding list
|
|
153
|
+
|
|
154
|
+
# Simulate conversion without modifying files
|
|
155
|
+
xavva encoding convert --from utf-8 --to cp1252 --dry-run src/
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Supported Encodings
|
|
159
|
+
|
|
160
|
+
- **utf-8** / **utf8** — UTF-8 (default)
|
|
161
|
+
- **windows-1252** / **cp1252** — Windows CP1252 (ANSI)
|
|
162
|
+
- **iso-8859-1** / **latin1** — ISO-8859-1 (Latin-1)
|
|
163
|
+
|
|
164
|
+
### Configuration
|
|
165
|
+
|
|
166
|
+
Set default encoding in `xavva.json`:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"project": {
|
|
171
|
+
"encoding": "cp1252"
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Then use without `--to`:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
xavva encoding convert --backup src/main/java/
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
129
184
|
## 🔍 Dependency Analysis
|
|
130
185
|
|
|
131
186
|
The `xavva deps` command provides comprehensive dependency analysis:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archznn/xavva",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Ultra-fast CLI tool for Java/Tomcat development with Hot-Reload and Zero Config. Supports Windows, Linux and macOS.",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
"typescript": "^5"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"
|
|
44
|
+
"@inquirer/prompts": "^8.3.2",
|
|
45
|
+
"glob": "^13.0.6",
|
|
46
|
+
"node-notifier": "^10.0.1"
|
|
45
47
|
}
|
|
46
48
|
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import type { Command } from "./Command";
|
|
2
|
+
import type { AppConfig, CLIArguments } from "../types/config";
|
|
3
|
+
import { Logger } from "../utils/ui";
|
|
4
|
+
|
|
5
|
+
export class CompletionCommand implements Command {
|
|
6
|
+
private readonly commands = [
|
|
7
|
+
"init", "config", "build", "deploy", "start", "stop", "restart",
|
|
8
|
+
"logs", "run", "audit", "deps", "docs", "doctor", "profiles",
|
|
9
|
+
"tomcat", "encoding", "history", "redo", "health", "completion", "help"
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
private readonly flags: Record<string, string[]> = {
|
|
13
|
+
"*": ["--help", "--version", "-v", "--verbose", "--quiet", "-q"],
|
|
14
|
+
"init": [],
|
|
15
|
+
"config": ["--interactive", "-i"],
|
|
16
|
+
"build": ["--clean", "-c", "--profile", "-p", "--no-build", "--cache"],
|
|
17
|
+
"deploy": ["--watch", "-w", "--clean", "-c", "--profile", "-p", "--debug", "--tui"],
|
|
18
|
+
"start": ["--debug", "--tui"],
|
|
19
|
+
"stop": [],
|
|
20
|
+
"restart": ["--debug"],
|
|
21
|
+
"logs": ["--grep", "-g", "--follow", "-f"],
|
|
22
|
+
"run": [],
|
|
23
|
+
"audit": ["--fix", "--strict"],
|
|
24
|
+
"deps": ["--output", "-o"],
|
|
25
|
+
"docs": [],
|
|
26
|
+
"doctor": [],
|
|
27
|
+
"profiles": [],
|
|
28
|
+
"tomcat": ["--tomcat-version", "--tomcat-action"],
|
|
29
|
+
"encoding": ["--from", "--to", "--backup"],
|
|
30
|
+
"history": ["--clear", "--limit"],
|
|
31
|
+
"redo": [],
|
|
32
|
+
"health": [],
|
|
33
|
+
"completion": ["bash", "zsh", "fish"]
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
async execute(_config: AppConfig, args?: CLIArguments, positionals?: string[]): Promise<void> {
|
|
37
|
+
const shell = positionals?.[0] || "bash";
|
|
38
|
+
|
|
39
|
+
switch (shell) {
|
|
40
|
+
case "bash":
|
|
41
|
+
console.log(this.generateBash());
|
|
42
|
+
break;
|
|
43
|
+
case "zsh":
|
|
44
|
+
console.log(this.generateZsh());
|
|
45
|
+
break;
|
|
46
|
+
case "fish":
|
|
47
|
+
console.log(this.generateFish());
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
Logger.banner("completion");
|
|
51
|
+
Logger.section("Shell Completion");
|
|
52
|
+
Logger.info("Uso: xavva completion <shell>");
|
|
53
|
+
Logger.newline();
|
|
54
|
+
Logger.log(`${Logger.C.gray}│${Logger.C.reset} ${Logger.C.primary}xavva completion bash${Logger.C.reset} ${Logger.C.gray}# Bash${Logger.C.reset}`);
|
|
55
|
+
Logger.log(`${Logger.C.gray}│${Logger.C.reset} ${Logger.C.primary}xavva completion zsh${Logger.C.reset} ${Logger.C.gray}# Zsh${Logger.C.reset}`);
|
|
56
|
+
Logger.log(`${Logger.C.gray}│${Logger.C.reset} ${Logger.C.primary}xavva completion fish${Logger.C.reset} ${Logger.C.gray}# Fish${Logger.C.reset}`);
|
|
57
|
+
Logger.endSection();
|
|
58
|
+
Logger.dim("Adicione ao seu shell:");
|
|
59
|
+
Logger.log(` ${Logger.C.gray}# Bash: echo 'eval "$(xavva completion bash)"' >> ~/.bashrc${Logger.C.reset}`);
|
|
60
|
+
Logger.log(` ${Logger.C.gray}# Zsh: echo 'eval "$(xavva completion zsh)"' >> ~/.zshrc${Logger.C.reset}`);
|
|
61
|
+
Logger.log(` ${Logger.C.gray}# Fish: xavva completion fish > ~/.config/fish/completions/xavva.fish${Logger.C.reset}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private generateBash(): string {
|
|
66
|
+
const cmds = this.commands.join(" ");
|
|
67
|
+
const flagCases = Object.entries(this.flags)
|
|
68
|
+
.filter(([cmd]) => cmd !== "*")
|
|
69
|
+
.map(([cmd, flags]) => `
|
|
70
|
+
${cmd})
|
|
71
|
+
opts="${flags.join(" ")}"
|
|
72
|
+
;;`)
|
|
73
|
+
.join("");
|
|
74
|
+
|
|
75
|
+
return `# xavva completion for bash
|
|
76
|
+
_xavva_completion() {
|
|
77
|
+
local cur prev opts
|
|
78
|
+
COMPREPLY=()
|
|
79
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
80
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
81
|
+
|
|
82
|
+
# Comandos principais
|
|
83
|
+
local commands="${cmds}"
|
|
84
|
+
local global_flags="${this.flags["*"].join(" ")}"
|
|
85
|
+
|
|
86
|
+
# Primeiro argumento: comandos
|
|
87
|
+
if [ \${COMP_CWORD} -eq 1 ]; then
|
|
88
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- \${cur}) )
|
|
89
|
+
return 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# Flags específicas por comando
|
|
93
|
+
local cmd="\${COMP_WORDS[1]}"
|
|
94
|
+
case \${cmd} in${flagCases}
|
|
95
|
+
*)
|
|
96
|
+
opts="\${global_flags}"
|
|
97
|
+
;;
|
|
98
|
+
esac
|
|
99
|
+
|
|
100
|
+
if [[ \${cur} == -* ]]; then
|
|
101
|
+
COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
|
|
102
|
+
return 0
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
complete -F _xavva_completion xavva
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private generateZsh(): string {
|
|
111
|
+
const cmds = this.commands.map(c => `"${c}"`).join(" ");
|
|
112
|
+
|
|
113
|
+
return `#compdef xavva
|
|
114
|
+
|
|
115
|
+
# xavva completion for zsh
|
|
116
|
+
|
|
117
|
+
_xavva() {
|
|
118
|
+
local curcontext="$curcontext" state line
|
|
119
|
+
typeset -A opt_args
|
|
120
|
+
|
|
121
|
+
_arguments -C \\
|
|
122
|
+
'1: :_xavva_commands' \\
|
|
123
|
+
'*:: :->args'
|
|
124
|
+
|
|
125
|
+
case $line[1] in
|
|
126
|
+
config)
|
|
127
|
+
_arguments \\
|
|
128
|
+
'(-i --interactive)'{-i,--interactive}'[Modo interativo]'
|
|
129
|
+
;;
|
|
130
|
+
build)
|
|
131
|
+
_arguments \\
|
|
132
|
+
'(-c --clean)'{-c,--clean}'[Clean build]' \\
|
|
133
|
+
'(-p --profile)'{-p,--profile}'[Profile]:profile:(dev test prod)' \\
|
|
134
|
+
'--cache[Enable cache]'
|
|
135
|
+
;;
|
|
136
|
+
deploy)
|
|
137
|
+
_arguments \\
|
|
138
|
+
'(-w --watch)'{-w,--watch}'[Watch mode]' \\
|
|
139
|
+
'(-c --clean)'{-c,--clean}'[Clean build]' \\
|
|
140
|
+
'(-p --profile)'{-p,--profile}'[Profile]:profile:(dev test prod)' \\
|
|
141
|
+
'--debug[Debug mode]' \\
|
|
142
|
+
'--tui[Enable TUI]'
|
|
143
|
+
;;
|
|
144
|
+
logs)
|
|
145
|
+
_arguments \\
|
|
146
|
+
'(-g --grep)'{-g,--grep}'[Filter pattern]:pattern:' \\
|
|
147
|
+
'(-f --follow)'{-f,--follow}'[Follow mode]'
|
|
148
|
+
;;
|
|
149
|
+
history)
|
|
150
|
+
_arguments \\
|
|
151
|
+
'--clear[Clear history]' \\
|
|
152
|
+
'--limit[Limit entries]:number:'
|
|
153
|
+
;;
|
|
154
|
+
completion)
|
|
155
|
+
_arguments \\
|
|
156
|
+
'1:shell:(bash zsh fish)'
|
|
157
|
+
;;
|
|
158
|
+
esac
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
_xavva_commands() {
|
|
162
|
+
local commands=(${cmds})
|
|
163
|
+
_describe -t commands 'xavva commands' commands
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
compdef _xavva xavva
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private generateFish(): string {
|
|
171
|
+
const lines: string[] = [
|
|
172
|
+
"# xavva completion for fish",
|
|
173
|
+
"",
|
|
174
|
+
`# Comandos principais`,
|
|
175
|
+
`complete -c xavva -n "not __fish_seen_subcommand_from ${this.commands.join(" ")}" -a "${this.commands.join(" ")}"`,
|
|
176
|
+
"",
|
|
177
|
+
`# Flags globais`,
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
// Global flags
|
|
181
|
+
for (const flag of this.flags["*"]) {
|
|
182
|
+
const short = flag.startsWith("-") && flag.length === 2 ? flag : "";
|
|
183
|
+
const long = flag.startsWith("--") ? flag : "";
|
|
184
|
+
if (short && long) {
|
|
185
|
+
lines.push(`complete -c xavva -s ${short[1]} -l ${long.slice(2)}`);
|
|
186
|
+
} else if (short) {
|
|
187
|
+
lines.push(`complete -c xavva -s ${short[1]}`);
|
|
188
|
+
} else if (long) {
|
|
189
|
+
lines.push(`complete -c xavva -l ${long.slice(2)}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Command-specific flags
|
|
194
|
+
for (const [cmd, flags] of Object.entries(this.flags)) {
|
|
195
|
+
if (cmd === "*") continue;
|
|
196
|
+
|
|
197
|
+
lines.push("");
|
|
198
|
+
lines.push(`# ${cmd}`);
|
|
199
|
+
for (const flag of flags) {
|
|
200
|
+
if (flag.startsWith("--")) {
|
|
201
|
+
lines.push(`complete -c xavva -n "__fish_seen_subcommand_from ${cmd}" -l ${flag.slice(2)}`);
|
|
202
|
+
} else if (flag.startsWith("-") && flag.length === 2) {
|
|
203
|
+
lines.push(`complete -c xavva -n "__fish_seen_subcommand_from ${cmd}" -s ${flag[1]}`);
|
|
204
|
+
} else {
|
|
205
|
+
lines.push(`complete -c xavva -n "__fish_seen_subcommand_from ${cmd}" -a "${flag}"`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return lines.join("\n");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { input, select, confirm, number, editor } from "@inquirer/prompts";
|
|
2
|
+
import { readFile, writeFile } from "fs/promises";
|
|
3
|
+
import { existsSync } from "fs";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import type { Command } from "./Command";
|
|
6
|
+
import type { AppConfig, CLIArguments } from "../types/config";
|
|
7
|
+
import { Logger } from "../utils/ui";
|
|
8
|
+
|
|
9
|
+
export class ConfigCommand implements Command {
|
|
10
|
+
async execute(config: AppConfig, args?: CLIArguments): Promise<void> {
|
|
11
|
+
const interactive = args?.["interactive"] || args?.["i"] || false;
|
|
12
|
+
const configPath = join(process.cwd(), "xavva.json");
|
|
13
|
+
|
|
14
|
+
if (!interactive) {
|
|
15
|
+
// Modo view: mostrar configuração atual
|
|
16
|
+
Logger.banner("config");
|
|
17
|
+
Logger.section("Configuração Atual");
|
|
18
|
+
|
|
19
|
+
Logger.config("App Name", config.project.appName);
|
|
20
|
+
Logger.config("Build Tool", config.project.buildTool);
|
|
21
|
+
Logger.config("Profile", config.project.profile);
|
|
22
|
+
Logger.config("Port", config.tomcat.port);
|
|
23
|
+
Logger.config("Cache", config.project.cache ?? true);
|
|
24
|
+
Logger.config("TUI", config.project.tui);
|
|
25
|
+
Logger.config("Encoding", config.project.encoding || "UTF-8");
|
|
26
|
+
|
|
27
|
+
if (config.tomcat.embedded) {
|
|
28
|
+
Logger.config("Tomcat", "embedded");
|
|
29
|
+
Logger.config("Version", config.tomcat.version || "10.1.52");
|
|
30
|
+
} else {
|
|
31
|
+
Logger.config("Tomcat Path", config.tomcat.path);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Logger.endSection();
|
|
35
|
+
Logger.dim("Use --interactive ou -i para editar");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Modo interativo
|
|
40
|
+
Logger.banner("config --interactive");
|
|
41
|
+
Logger.section("Editor Interativo");
|
|
42
|
+
|
|
43
|
+
if (!existsSync(configPath)) {
|
|
44
|
+
Logger.warn("xavva.json não encontrado. Execute 'xavva init' primeiro.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Carregar config atual
|
|
49
|
+
let currentConfig: Record<string, unknown>;
|
|
50
|
+
try {
|
|
51
|
+
const content = await readFile(configPath, "utf-8");
|
|
52
|
+
currentConfig = JSON.parse(content);
|
|
53
|
+
} catch {
|
|
54
|
+
Logger.error("Erro ao ler xavva.json");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Menu de opções
|
|
59
|
+
const action = await select({
|
|
60
|
+
message: "O que deseja editar?",
|
|
61
|
+
choices: [
|
|
62
|
+
{ name: "Informações básicas (nome, profile)", value: "basic" },
|
|
63
|
+
{ name: "Configurações do Tomcat (porta, path)", value: "tomcat" },
|
|
64
|
+
{ name: "Opções de build (cache, encoding)", value: "build" },
|
|
65
|
+
{ name: "Editor de texto (JSON completo)", value: "json" }
|
|
66
|
+
]
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
switch (action) {
|
|
70
|
+
case "basic":
|
|
71
|
+
await this.editBasic(currentConfig);
|
|
72
|
+
break;
|
|
73
|
+
case "tomcat":
|
|
74
|
+
await this.editTomcat(currentConfig);
|
|
75
|
+
break;
|
|
76
|
+
case "build":
|
|
77
|
+
await this.editBuild(currentConfig);
|
|
78
|
+
break;
|
|
79
|
+
case "json":
|
|
80
|
+
await this.editJson(currentConfig, configPath);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Salvar
|
|
85
|
+
await writeFile(configPath, JSON.stringify(currentConfig, null, 2));
|
|
86
|
+
Logger.success("Configuração salva!");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private async editBasic(config: Record<string, unknown>): Promise<void> {
|
|
90
|
+
config.appName = await input({
|
|
91
|
+
message: "Nome da aplicação:",
|
|
92
|
+
default: String(config.appName || "")
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
config.profile = await select({
|
|
96
|
+
message: "Profile:",
|
|
97
|
+
choices: [
|
|
98
|
+
{ name: "dev", value: "dev" },
|
|
99
|
+
{ name: "test", value: "test" },
|
|
100
|
+
{ name: "prod", value: "prod" },
|
|
101
|
+
{ name: "custom", value: "custom" }
|
|
102
|
+
],
|
|
103
|
+
default: String(config.profile || "dev")
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (config.profile === "custom") {
|
|
107
|
+
config.profile = await input({
|
|
108
|
+
message: "Nome do profile:",
|
|
109
|
+
default: "local"
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private async editTomcat(config: Record<string, unknown>): Promise<void> {
|
|
115
|
+
config.port = await number({
|
|
116
|
+
message: "Porta:",
|
|
117
|
+
default: Number(config.port || 8080)
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const useEmbedded = await confirm({
|
|
121
|
+
message: "Usar Tomcat embutido?",
|
|
122
|
+
default: Boolean(config.embedded ?? true)
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
config.embedded = useEmbedded;
|
|
126
|
+
|
|
127
|
+
if (useEmbedded) {
|
|
128
|
+
config.tomcatVersion = await select({
|
|
129
|
+
message: "Versão do Tomcat:",
|
|
130
|
+
choices: [
|
|
131
|
+
{ name: "10.1.52 (recomendada)", value: "10.1.52" },
|
|
132
|
+
{ name: "9.0.115", value: "9.0.115" },
|
|
133
|
+
{ name: "11.0.18", value: "11.0.18" }
|
|
134
|
+
],
|
|
135
|
+
default: String(config.tomcatVersion || "10.1.52")
|
|
136
|
+
});
|
|
137
|
+
delete config.tomcatPath;
|
|
138
|
+
} else {
|
|
139
|
+
config.tomcatPath = await input({
|
|
140
|
+
message: "Caminho do Tomcat:",
|
|
141
|
+
default: String(config.tomcatPath || "")
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private async editBuild(config: Record<string, unknown>): Promise<void> {
|
|
147
|
+
config.cache = await confirm({
|
|
148
|
+
message: "Habilitar cache de build?",
|
|
149
|
+
default: Boolean(config.cache ?? true)
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
config.tui = await confirm({
|
|
153
|
+
message: "Habilitar dashboard TUI?",
|
|
154
|
+
default: Boolean(config.tui ?? true)
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
config.encoding = await select({
|
|
158
|
+
message: "Encoding:",
|
|
159
|
+
choices: [
|
|
160
|
+
{ name: "UTF-8", value: "UTF-8" },
|
|
161
|
+
{ name: "ISO-8859-1", value: "ISO-8859-1" },
|
|
162
|
+
{ name: "Windows-1252", value: "Windows-1252" }
|
|
163
|
+
],
|
|
164
|
+
default: String(config.encoding || "UTF-8")
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private async editJson(config: Record<string, unknown>, path: string): Promise<void> {
|
|
169
|
+
const current = JSON.stringify(config, null, 2);
|
|
170
|
+
const edited = await editor({
|
|
171
|
+
message: "Edite o JSON:",
|
|
172
|
+
default: current,
|
|
173
|
+
postfix: ".json"
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
const parsed = JSON.parse(edited);
|
|
178
|
+
await writeFile(path, JSON.stringify(parsed, null, 2));
|
|
179
|
+
Logger.success("Configuração salva!");
|
|
180
|
+
} catch {
|
|
181
|
+
Logger.error("JSON inválido!");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -260,10 +260,11 @@ export class DeployCommand implements Command {
|
|
|
260
260
|
if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
|
|
261
261
|
|
|
262
262
|
fs.copyFileSync(filename, targetPath);
|
|
263
|
-
|
|
263
|
+
Logger.success(`${path.basename(filename)} updated → Tomcat`);
|
|
264
264
|
|
|
265
265
|
const appUrl = `http://localhost:${config.tomcat.port}/${appFolder}`;
|
|
266
266
|
await BrowserService.reload(appUrl);
|
|
267
|
+
Logger.ready(`Browser reloaded`);
|
|
267
268
|
} catch (e) {
|
|
268
269
|
Logger.error(`Failed to sync resource: ${filename}`);
|
|
269
270
|
}
|