@jango-blockchained/hoox-cli 0.3.4
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 +403 -0
- package/bin/hoox.js +12 -0
- package/package.json +60 -0
- package/src/commands/check/check-command.test.ts +468 -0
- package/src/commands/check/check-command.ts +1144 -0
- package/src/commands/check/index.ts +10 -0
- package/src/commands/check/prerequisites-command.test.ts +19 -0
- package/src/commands/check/prerequisites-command.ts +92 -0
- package/src/commands/check/types.ts +103 -0
- package/src/commands/clone/clone-command.test.ts +442 -0
- package/src/commands/clone/clone-command.ts +440 -0
- package/src/commands/clone/index.ts +1 -0
- package/src/commands/config/config-command.test.ts +583 -0
- package/src/commands/config/config-command.ts +901 -0
- package/src/commands/config/env-command.test.ts +43 -0
- package/src/commands/config/env-command.ts +314 -0
- package/src/commands/config/index.ts +3 -0
- package/src/commands/config/kv-command.test.ts +14 -0
- package/src/commands/config/kv-command.ts +329 -0
- package/src/commands/dashboard/dashboard-command.test.ts +47 -0
- package/src/commands/dashboard/dashboard-command.ts +127 -0
- package/src/commands/dashboard/index.ts +1 -0
- package/src/commands/db/db-command.test.ts +21 -0
- package/src/commands/db/db-command.ts +314 -0
- package/src/commands/db/index.ts +1 -0
- package/src/commands/deploy/deploy-command.test.ts +304 -0
- package/src/commands/deploy/deploy-command.ts +1053 -0
- package/src/commands/deploy/index.ts +2 -0
- package/src/commands/deploy/telegram-service.ts +61 -0
- package/src/commands/deploy/types.ts +34 -0
- package/src/commands/dev/dev-command.test.ts +383 -0
- package/src/commands/dev/dev-command.ts +407 -0
- package/src/commands/dev/index.ts +1 -0
- package/src/commands/infra/index.ts +5 -0
- package/src/commands/infra/infra-command.test.ts +719 -0
- package/src/commands/infra/infra-command.ts +940 -0
- package/src/commands/infra/types.ts +23 -0
- package/src/commands/init/index.ts +1 -0
- package/src/commands/init/init-command.test.ts +827 -0
- package/src/commands/init/init-command.ts +627 -0
- package/src/commands/init/types.ts +185 -0
- package/src/commands/monitor/index.ts +2 -0
- package/src/commands/monitor/monitor-command.test.ts +235 -0
- package/src/commands/monitor/monitor-command.ts +245 -0
- package/src/commands/monitor/monitor-service.ts +50 -0
- package/src/commands/monitor/types.ts +13 -0
- package/src/commands/repair/index.ts +2 -0
- package/src/commands/repair/repair-command.test.ts +204 -0
- package/src/commands/repair/repair-command.ts +199 -0
- package/src/commands/repair/repair-service.ts +102 -0
- package/src/commands/repair/types.ts +13 -0
- package/src/commands/test/index.ts +2 -0
- package/src/commands/test/test-command.test.ts +319 -0
- package/src/commands/test/test-command.ts +412 -0
- package/src/commands/waf/index.ts +2 -0
- package/src/commands/waf/types.ts +48 -0
- package/src/commands/waf/waf-command.test.ts +506 -0
- package/src/commands/waf/waf-command.ts +548 -0
- package/src/index.ts +198 -0
- package/src/services/cloudflare/cloudflare-service.test.ts +654 -0
- package/src/services/cloudflare/cloudflare-service.ts +435 -0
- package/src/services/cloudflare/index.ts +2 -0
- package/src/services/cloudflare/types.ts +29 -0
- package/src/services/config/config-service.test.ts +395 -0
- package/src/services/config/config-service.ts +207 -0
- package/src/services/config/index.ts +9 -0
- package/src/services/config/types.ts +66 -0
- package/src/services/db/db-service.test.ts +51 -0
- package/src/services/db/db-service.ts +140 -0
- package/src/services/db/index.ts +1 -0
- package/src/services/docker/docker-service.ts +155 -0
- package/src/services/docker/index.ts +1 -0
- package/src/services/env/env-service.test.ts +210 -0
- package/src/services/env/env-service.ts +156 -0
- package/src/services/env/index.ts +1 -0
- package/src/services/kv/index.ts +1 -0
- package/src/services/kv/kv-sync-service.test.ts +38 -0
- package/src/services/kv/kv-sync-service.ts +151 -0
- package/src/services/prerequisites/index.ts +1 -0
- package/src/services/prerequisites/prerequisites-service.test.ts +89 -0
- package/src/services/prerequisites/prerequisites-service.ts +269 -0
- package/src/services/prerequisites/types.ts +48 -0
- package/src/services/secrets/index.ts +12 -0
- package/src/services/secrets/secrets-service.test.ts +486 -0
- package/src/services/secrets/secrets-service.ts +293 -0
- package/src/services/secrets/types.ts +57 -0
- package/src/ui/banner.ts +52 -0
- package/src/ui/index.ts +8 -0
- package/src/ui/menu.ts +473 -0
- package/src/utils/errors.test.ts +69 -0
- package/src/utils/errors.ts +23 -0
- package/src/utils/formatters.test.ts +180 -0
- package/src/utils/formatters.ts +252 -0
- package/src/utils/theme.ts +94 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Hoox CLI — main entry point.
|
|
4
|
+
* Built with commander.js. Commands are registered via dedicated register* functions.
|
|
5
|
+
* Global options --json and --quiet are available to all commands via program.opts().
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Command } from "commander";
|
|
9
|
+
import { toError } from "@jango-blockchained/hoox-shared";
|
|
10
|
+
import { CLIError, ExitCode } from "./utils/errors.js";
|
|
11
|
+
import { formatError } from "./utils/formatters.js";
|
|
12
|
+
import { theme } from "./utils/theme.js";
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Program setup
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
const program = new Command();
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.name("hoox")
|
|
22
|
+
.description(
|
|
23
|
+
"Hoox CLI — manage Cloudflare Workers, infrastructure, secrets, and deployments"
|
|
24
|
+
)
|
|
25
|
+
.version("0.2.0")
|
|
26
|
+
.addHelpText(
|
|
27
|
+
"beforeAll",
|
|
28
|
+
theme.heading("\nHoox CLI — Cloudflare Workers Platform\n")
|
|
29
|
+
)
|
|
30
|
+
.configureHelp({
|
|
31
|
+
styleTitle: (str: string) => theme.heading(str),
|
|
32
|
+
styleCommandText: (str: string) => theme.bold(str),
|
|
33
|
+
styleOptionText: (str: string) => str,
|
|
34
|
+
styleDescriptionText: (str: string) => theme.dim(str),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Global options — accessible by all commands via program.opts()
|
|
38
|
+
program.option("--json", "Output in JSON format");
|
|
39
|
+
program.option("--quiet", "Minimal output");
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Error handling — map CommanderError and CLIError to proper exit codes
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
program.exitOverride((err) => {
|
|
46
|
+
// Commander's own informational exits — let them through
|
|
47
|
+
if (
|
|
48
|
+
err.code === "commander.helpDisplayed" ||
|
|
49
|
+
err.code === "commander.version"
|
|
50
|
+
) {
|
|
51
|
+
process.exit(ExitCode.SUCCESS);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Parent command without subcommand — already displayed help, clean exit
|
|
55
|
+
if (
|
|
56
|
+
err.code === "commander.missingArgument" ||
|
|
57
|
+
err.message === "(outputHelp)" ||
|
|
58
|
+
err.message?.includes("outputHelp")
|
|
59
|
+
) {
|
|
60
|
+
process.exit(ExitCode.SUCCESS);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Unknown command / option: exit code 2 (invalid usage)
|
|
64
|
+
if (
|
|
65
|
+
err.code === "commander.unknownCommand" ||
|
|
66
|
+
err.code === "commander.unknownOption"
|
|
67
|
+
) {
|
|
68
|
+
formatError(
|
|
69
|
+
new CLIError(err.message, ExitCode.INVALID_USAGE, undefined, false)
|
|
70
|
+
);
|
|
71
|
+
process.exit(ExitCode.INVALID_USAGE);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Missing mandatory option / argument: exit code 2 (invalid usage)
|
|
75
|
+
if (
|
|
76
|
+
err.code === "commander.missingMandatoryOptionValue" ||
|
|
77
|
+
err.code === "commander.missingArgument"
|
|
78
|
+
) {
|
|
79
|
+
formatError(
|
|
80
|
+
new CLIError(err.message, ExitCode.INVALID_USAGE, undefined, false)
|
|
81
|
+
);
|
|
82
|
+
process.exit(ExitCode.INVALID_USAGE);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If the error is already a CLIError, use its exit code
|
|
86
|
+
if (err instanceof CLIError) {
|
|
87
|
+
formatError(err);
|
|
88
|
+
process.exit((err as CLIError).code);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Generic fallback
|
|
92
|
+
formatError(new CLIError(err.message, ExitCode.ERROR, undefined, false));
|
|
93
|
+
process.exit(ExitCode.ERROR);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// Global process error handlers
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
process.on("uncaughtException", (err) => {
|
|
101
|
+
formatError(
|
|
102
|
+
err instanceof CLIError
|
|
103
|
+
? err
|
|
104
|
+
: new CLIError(
|
|
105
|
+
`Uncaught exception: ${err.message}`,
|
|
106
|
+
ExitCode.ERROR,
|
|
107
|
+
err.stack,
|
|
108
|
+
false
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
process.exit(ExitCode.ERROR);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
process.on("unhandledRejection", (reason) => {
|
|
115
|
+
const err =
|
|
116
|
+
reason instanceof Error
|
|
117
|
+
? reason
|
|
118
|
+
: new Error(`Unhandled rejection: ${toError(reason)}`);
|
|
119
|
+
|
|
120
|
+
formatError(new CLIError(err.message, ExitCode.ERROR, err.stack, false));
|
|
121
|
+
process.exit(ExitCode.ERROR);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// Command registration (added in subtasks 06–16)
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
import { registerInitCommand } from "./commands/init/index.js";
|
|
129
|
+
import { registerDevCommand } from "./commands/dev/index.js";
|
|
130
|
+
import { registerDeployCommand } from "./commands/deploy/index.js";
|
|
131
|
+
import { registerInfraCommand } from "./commands/infra/index.js";
|
|
132
|
+
import { registerConfigCommand } from "./commands/config/index.js";
|
|
133
|
+
import { registerCheckCommand } from "./commands/check/index.js";
|
|
134
|
+
import { registerLogsCommand } from "./commands/logs/index.js";
|
|
135
|
+
import { registerTestCommand } from "./commands/test/index.js";
|
|
136
|
+
import { registerWafCommand } from "./commands/waf/index.js";
|
|
137
|
+
import { registerCloneCommand } from "./commands/clone/index.js";
|
|
138
|
+
import { registerDashboardCommand } from "./commands/dashboard/index.js";
|
|
139
|
+
import { registerDbCommand } from "./commands/db/index.js";
|
|
140
|
+
import { registerMonitorCommand } from "./commands/monitor/index.js";
|
|
141
|
+
import { registerRepairCommand } from "./commands/repair/index.js";
|
|
142
|
+
import { runInteractiveTUI } from "./ui/index.js";
|
|
143
|
+
|
|
144
|
+
registerInitCommand(program);
|
|
145
|
+
registerDevCommand(program);
|
|
146
|
+
registerDeployCommand(program);
|
|
147
|
+
registerInfraCommand(program);
|
|
148
|
+
registerConfigCommand(program);
|
|
149
|
+
registerCheckCommand(program);
|
|
150
|
+
registerLogsCommand(program);
|
|
151
|
+
registerTestCommand(program);
|
|
152
|
+
registerWafCommand(program);
|
|
153
|
+
registerCloneCommand(program);
|
|
154
|
+
registerDashboardCommand(program);
|
|
155
|
+
registerDbCommand(program);
|
|
156
|
+
registerMonitorCommand(program);
|
|
157
|
+
registerRepairCommand(program);
|
|
158
|
+
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
// Main entry — exported so bin/hoox.js can invoke it explicitly
|
|
161
|
+
// (import.meta.main is false when loaded as a dependency)
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Main CLI entry point.
|
|
166
|
+
* Parses args or launches the interactive TUI if no args are given.
|
|
167
|
+
*/
|
|
168
|
+
export async function main(): Promise<void> {
|
|
169
|
+
const hasArgs = process.argv.slice(2).length > 0;
|
|
170
|
+
|
|
171
|
+
if (hasArgs) {
|
|
172
|
+
program.parse();
|
|
173
|
+
} else {
|
|
174
|
+
// Interactive TUI mode — launches when hoox is called with no arguments
|
|
175
|
+
await runInteractiveTUI(program);
|
|
176
|
+
process.exit(ExitCode.SUCCESS);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (import.meta.main) {
|
|
181
|
+
await main();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// Exports
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
export { program };
|
|
189
|
+
export { CLIError, ExitCode } from "./utils/errors.js";
|
|
190
|
+
export {
|
|
191
|
+
formatSuccess,
|
|
192
|
+
formatError,
|
|
193
|
+
formatTable,
|
|
194
|
+
formatJson,
|
|
195
|
+
formatKeyValue,
|
|
196
|
+
} from "./utils/formatters.js";
|
|
197
|
+
export type { FormatOptions } from "./utils/formatters.js";
|
|
198
|
+
export { theme, icons } from "./utils/theme.js";
|