@jango-blockchained/hoox-cli 0.5.1 → 0.5.6

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 (106) hide show
  1. package/bin/hoox.js +3 -4
  2. package/dist/index.js +32545 -0
  3. package/package.json +10 -15
  4. package/src/commands/check/check-command.test.ts +0 -476
  5. package/src/commands/check/check-command.ts +0 -1144
  6. package/src/commands/check/index.ts +0 -10
  7. package/src/commands/check/prerequisites-command.test.ts +0 -19
  8. package/src/commands/check/prerequisites-command.ts +0 -96
  9. package/src/commands/check/types.ts +0 -103
  10. package/src/commands/clone/clone-command.test.ts +0 -442
  11. package/src/commands/clone/clone-command.ts +0 -431
  12. package/src/commands/clone/index.ts +0 -1
  13. package/src/commands/config/config-command.test.ts +0 -583
  14. package/src/commands/config/config-command.ts +0 -897
  15. package/src/commands/config/env-command.test.ts +0 -43
  16. package/src/commands/config/env-command.ts +0 -295
  17. package/src/commands/config/index.ts +0 -3
  18. package/src/commands/config/kv-command.test.ts +0 -14
  19. package/src/commands/config/kv-command.ts +0 -290
  20. package/src/commands/dashboard/dashboard-command.test.ts +0 -47
  21. package/src/commands/dashboard/dashboard-command.ts +0 -128
  22. package/src/commands/dashboard/index.ts +0 -1
  23. package/src/commands/db/db-command.test.ts +0 -21
  24. package/src/commands/db/db-command.ts +0 -312
  25. package/src/commands/db/index.ts +0 -1
  26. package/src/commands/deploy/deploy-command.test.ts +0 -304
  27. package/src/commands/deploy/deploy-command.ts +0 -1135
  28. package/src/commands/deploy/index.ts +0 -2
  29. package/src/commands/deploy/telegram-service.ts +0 -76
  30. package/src/commands/deploy/types.ts +0 -34
  31. package/src/commands/dev/dev-command.test.ts +0 -383
  32. package/src/commands/dev/dev-command.ts +0 -398
  33. package/src/commands/dev/index.ts +0 -1
  34. package/src/commands/infra/index.ts +0 -5
  35. package/src/commands/infra/infra-command.test.ts +0 -719
  36. package/src/commands/infra/infra-command.ts +0 -974
  37. package/src/commands/infra/types.ts +0 -23
  38. package/src/commands/init/__tests__/cli-provisioner.test.ts +0 -17
  39. package/src/commands/init/cli-provisioner.ts +0 -71
  40. package/src/commands/init/index.ts +0 -1
  41. package/src/commands/init/init-command.test.ts +0 -876
  42. package/src/commands/init/init-command.ts +0 -593
  43. package/src/commands/init/types.ts +0 -23
  44. package/src/commands/logs/index.ts +0 -1
  45. package/src/commands/logs/logs-command.test.ts +0 -294
  46. package/src/commands/logs/logs-command.ts +0 -452
  47. package/src/commands/monitor/index.ts +0 -2
  48. package/src/commands/monitor/monitor-command.test.ts +0 -263
  49. package/src/commands/monitor/monitor-command.ts +0 -269
  50. package/src/commands/monitor/monitor-service.ts +0 -65
  51. package/src/commands/monitor/types.ts +0 -13
  52. package/src/commands/repair/index.ts +0 -2
  53. package/src/commands/repair/repair-command.test.ts +0 -224
  54. package/src/commands/repair/repair-command.ts +0 -220
  55. package/src/commands/repair/repair-service.ts +0 -138
  56. package/src/commands/repair/types.ts +0 -13
  57. package/src/commands/test/index.ts +0 -2
  58. package/src/commands/test/test-command.test.ts +0 -319
  59. package/src/commands/test/test-command.ts +0 -406
  60. package/src/commands/tui/index.ts +0 -1
  61. package/src/commands/tui/tui-command.ts +0 -87
  62. package/src/commands/update/index.ts +0 -1
  63. package/src/commands/update/update-command.ts +0 -168
  64. package/src/commands/waf/index.ts +0 -2
  65. package/src/commands/waf/types.ts +0 -48
  66. package/src/commands/waf/waf-command.test.ts +0 -506
  67. package/src/commands/waf/waf-command.ts +0 -548
  68. package/src/index.ts +0 -269
  69. package/src/services/cloudflare/cloudflare-service.test.ts +0 -658
  70. package/src/services/cloudflare/cloudflare-service.ts +0 -433
  71. package/src/services/cloudflare/index.ts +0 -2
  72. package/src/services/cloudflare/types.ts +0 -30
  73. package/src/services/config/config-service.test.ts +0 -395
  74. package/src/services/config/config-service.ts +0 -207
  75. package/src/services/config/index.ts +0 -9
  76. package/src/services/config/types.ts +0 -66
  77. package/src/services/db/db-service.test.ts +0 -51
  78. package/src/services/db/db-service.ts +0 -131
  79. package/src/services/db/index.ts +0 -1
  80. package/src/services/docker/docker-service.ts +0 -155
  81. package/src/services/docker/index.ts +0 -1
  82. package/src/services/env/env-service.test.ts +0 -236
  83. package/src/services/env/env-service.ts +0 -386
  84. package/src/services/env/index.ts +0 -1
  85. package/src/services/kv/index.ts +0 -1
  86. package/src/services/kv/kv-sync-service.test.ts +0 -38
  87. package/src/services/kv/kv-sync-service.ts +0 -234
  88. package/src/services/prerequisites/index.ts +0 -1
  89. package/src/services/prerequisites/prerequisites-service.test.ts +0 -89
  90. package/src/services/prerequisites/prerequisites-service.ts +0 -377
  91. package/src/services/prerequisites/types.ts +0 -48
  92. package/src/services/secrets/index.ts +0 -11
  93. package/src/services/secrets/secrets-service.test.ts +0 -495
  94. package/src/services/secrets/secrets-service.ts +0 -287
  95. package/src/services/secrets/types.ts +0 -50
  96. package/src/services/update/index.ts +0 -2
  97. package/src/services/update/update-service.test.ts +0 -76
  98. package/src/services/update/update-service.ts +0 -193
  99. package/src/ui/banner.ts +0 -141
  100. package/src/ui/index.ts +0 -8
  101. package/src/ui/menu.ts +0 -490
  102. package/src/utils/errors.test.ts +0 -69
  103. package/src/utils/errors.ts +0 -23
  104. package/src/utils/formatters.test.ts +0 -180
  105. package/src/utils/formatters.ts +0 -269
  106. package/src/utils/theme.ts +0 -94
@@ -1,128 +0,0 @@
1
- import type { Command } from "commander";
2
- import { ConfigService } from "../../services/config/index.js";
3
- import { CLIError, ExitCode } from "../../utils/errors.js";
4
- import {
5
- formatSuccess,
6
- formatError,
7
- formatTable,
8
- } from "../../utils/formatters.js";
9
- import type { FormatOptions } from "../../utils/formatters.js";
10
- import { theme, icons } from "../../utils/theme.js";
11
- import * as jsonc from "jsonc-parser";
12
- import { readFileSync, writeFileSync, existsSync } from "node:fs";
13
- import { resolve } from "node:path";
14
-
15
- interface ServiceUrl {
16
- worker: string;
17
- url: string;
18
- }
19
-
20
- function getServiceUrls(config: ConfigService): ServiceUrl[] {
21
- const global = config.getGlobal();
22
- const prefix = global.subdomain_prefix ?? "hoox";
23
- const workers = config.listEnabledWorkers();
24
-
25
- return workers.map((name) => ({
26
- worker: name,
27
- url: `https://${name}.${prefix}.workers.dev`,
28
- }));
29
- }
30
-
31
- function updateWranglerVars(
32
- filePath: string,
33
- urls: ServiceUrl[],
34
- dryRun: boolean,
35
- opts: FormatOptions
36
- ): void {
37
- if (!existsSync(filePath)) {
38
- throw new CLIError(
39
- `Dashboard wrangler.jsonc not found at ${filePath}`,
40
- ExitCode.ERROR
41
- );
42
- }
43
-
44
- const content = readFileSync(filePath, "utf-8");
45
- const errors: jsonc.ParseError[] = [];
46
- const parsed = jsonc.parse(content, errors) as Record<string, unknown>;
47
-
48
- if (errors.length > 0) {
49
- throw new CLIError(`Invalid JSONC in ${filePath}`, ExitCode.ERROR);
50
- }
51
-
52
- const vars = (parsed.vars as Record<string, string>) ?? {};
53
- const changes: { key: string; oldValue: string; newValue: string }[] = [];
54
-
55
- for (const { worker, url } of urls) {
56
- const key = `${worker.toUpperCase().replace(/-/g, "_")}_URL`;
57
- const oldValue = vars[key] ?? "(not set)";
58
- changes.push({ key, oldValue, newValue: url });
59
- vars[key] = url;
60
- }
61
-
62
- if (changes.length === 0) {
63
- formatSuccess("No service URLs to update.", opts);
64
- return;
65
- }
66
-
67
- if (!opts.quiet) {
68
- const rows = changes.map((c) => ({
69
- Key: c.key,
70
- Old: c.oldValue,
71
- New: theme.success(c.newValue),
72
- }));
73
- console.log(theme.heading("\nService URL changes:"));
74
- formatTable(rows, opts);
75
- }
76
-
77
- if (dryRun) {
78
- formatSuccess("Dry run — no changes written.", opts);
79
- return;
80
- }
81
-
82
- const fresh = readFileSync(filePath, "utf-8");
83
- const edits = jsonc.modify(fresh, ["vars"], vars, {
84
- formattingOptions: { tabSize: 2, insertSpaces: true },
85
- });
86
- const updated = jsonc.applyEdits(fresh, edits);
87
- writeFileSync(filePath, updated, "utf-8");
88
-
89
- formatSuccess(
90
- `Updated ${changes.length} service URL(s) in dashboard wrangler.jsonc`,
91
- opts
92
- );
93
- }
94
-
95
- export function registerDashboardCommand(program: Command): void {
96
- const dashboardCmd = program
97
- .command("dashboard")
98
- .description("Dashboard-specific operations");
99
-
100
- dashboardCmd
101
- .command("update-urls")
102
- .description("Update dashboard wrangler.jsonc with current service URLs")
103
- .option("--dry-run", "Show changes without applying")
104
- .action(async (options: { dryRun?: boolean }) => {
105
- const opts: FormatOptions = {
106
- json: program.opts<{ json?: boolean }>().json,
107
- quiet: program.opts<{ quiet?: boolean }>().quiet,
108
- };
109
-
110
- try {
111
- const config = new ConfigService();
112
- await config.load();
113
-
114
- const urls = getServiceUrls(config);
115
- const dashboardPath = resolve(
116
- process.cwd(),
117
- "pages",
118
- "dashboard",
119
- "wrangler.jsonc"
120
- );
121
-
122
- updateWranglerVars(dashboardPath, urls, options.dryRun === true, opts);
123
- } catch (err) {
124
- formatError(err instanceof Error ? err : String(err), opts);
125
- process.exit(err instanceof CLIError ? err.code : ExitCode.ERROR);
126
- }
127
- });
128
- }
@@ -1 +0,0 @@
1
- export { registerDashboardCommand } from "./dashboard-command.js";
@@ -1,21 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { DbService } from "../../services/db/index.js";
3
-
4
- describe("db command", () => {
5
- describe("DbService integration", () => {
6
- it("resolves database name from explicit arg", async () => {
7
- const svc = new DbService();
8
- const name = await svc.resolveDbName("my-test-db");
9
- expect(name).toBe("my-test-db");
10
- });
11
-
12
- it("parses table names from wrangler output", () => {
13
- const output = JSON.stringify([
14
- { results: [{ name: "trades" }, { name: "signals" }] },
15
- ]);
16
- const tables = DbService.parseTableNames(output);
17
- expect(tables).toContain("trades");
18
- expect(tables).toContain("signals");
19
- });
20
- });
21
- });
@@ -1,312 +0,0 @@
1
- /**
2
- * `hoox db` command group — database management.
3
- *
4
- * Subcommands:
5
- * apply [--remote] [--file <path>] — Apply schema.sql to D1
6
- * migrate [--remote] — Run tracking migrations
7
- * list [--remote] — List database tables
8
- * query <sql> [--remote] — Execute a SQL query
9
- * export [--output <path>] — Export database
10
- * reset [--confirm] — Drop and recreate (DESTRUCTIVE)
11
- */
12
-
13
- import { Command } from "commander";
14
- import * as p from "@clack/prompts";
15
- import { DbService } from "../../services/db/index.js";
16
- import {
17
- formatSuccess,
18
- formatError,
19
- formatTable,
20
- formatJson,
21
- getFormatOptions,
22
- } from "../../utils/formatters.js";
23
- import { CLIError, ExitCode } from "../../utils/errors.js";
24
- import type { FormatOptions } from "../../utils/formatters.js";
25
-
26
- /**
27
- * Resolve database name from config or --database flag.
28
- */
29
- async function resolveDb(cmd: Command, svc: DbService): Promise<string> {
30
- const opts = cmd.optsWithGlobals<{ database?: string }>();
31
- return await svc.resolveDbName(opts.database);
32
- }
33
-
34
- // ---------------------------------------------------------------------------
35
- // db apply
36
- // ---------------------------------------------------------------------------
37
-
38
- async function handleApply(
39
- opts: FormatOptions,
40
- dbName: string,
41
- remote: boolean,
42
- file?: string
43
- ): Promise<void> {
44
- const svc = new DbService();
45
- const output = await svc.apply(dbName, remote, file);
46
- formatSuccess(
47
- `Schema applied to ${dbName}${remote ? " (remote)" : " (local)"}`,
48
- opts
49
- );
50
- if (!opts.quiet && output) {
51
- process.stdout.write(`${output}\n`);
52
- }
53
- }
54
-
55
- // ---------------------------------------------------------------------------
56
- // db migrate
57
- // ---------------------------------------------------------------------------
58
-
59
- async function handleMigrate(
60
- opts: FormatOptions,
61
- dbName: string,
62
- remote: boolean
63
- ): Promise<void> {
64
- const svc = new DbService();
65
- const output = await svc.migrate(dbName, remote);
66
- formatSuccess(
67
- `Migrations applied to ${dbName}${remote ? " (remote)" : " (local)"}`,
68
- opts
69
- );
70
- if (!opts.quiet && output) {
71
- process.stdout.write(`${output}\n`);
72
- }
73
- }
74
-
75
- // ---------------------------------------------------------------------------
76
- // db list
77
- // ---------------------------------------------------------------------------
78
-
79
- async function handleList(
80
- opts: FormatOptions,
81
- dbName: string,
82
- remote: boolean
83
- ): Promise<void> {
84
- const svc = new DbService();
85
- const tables = await svc.listTables(dbName, remote);
86
-
87
- if (opts.json) {
88
- formatJson(tables, opts);
89
- } else if (!opts.quiet) {
90
- if (tables.length === 0) {
91
- process.stdout.write("No tables found.\n");
92
- return;
93
- }
94
- const rows = tables.map((t) => ({ Table: t }));
95
- formatTable(rows, opts);
96
- }
97
- }
98
-
99
- // ---------------------------------------------------------------------------
100
- // db query
101
- // ---------------------------------------------------------------------------
102
-
103
- async function handleQuery(
104
- opts: FormatOptions,
105
- dbName: string,
106
- sql: string,
107
- remote: boolean
108
- ): Promise<void> {
109
- const svc = new DbService();
110
- const output = await svc.query(dbName, sql, remote);
111
-
112
- if (opts.json) {
113
- // Already JSON from wrangler — try to parse for cleaner output
114
- try {
115
- const parsed = JSON.parse(output);
116
- formatJson(parsed, opts);
117
- } catch {
118
- process.stdout.write(`${output}\n`);
119
- }
120
- } else {
121
- process.stdout.write(`${output}\n`);
122
- }
123
- }
124
-
125
- // ---------------------------------------------------------------------------
126
- // db export
127
- // ---------------------------------------------------------------------------
128
-
129
- async function handleExport(
130
- opts: FormatOptions,
131
- dbName: string,
132
- outputPath?: string
133
- ): Promise<void> {
134
- const svc = new DbService();
135
- const path = await svc.export(dbName, outputPath);
136
- formatSuccess(`Database exported to ${path}`, opts);
137
- }
138
-
139
- // ---------------------------------------------------------------------------
140
- // db reset
141
- // ---------------------------------------------------------------------------
142
-
143
- async function handleReset(
144
- opts: FormatOptions,
145
- dbName: string,
146
- confirmed: boolean
147
- ): Promise<void> {
148
- if (!confirmed) {
149
- const answer = await p.confirm({
150
- message: `WARNING: This will DELETE and recreate the "${dbName}" database. ALL DATA WILL BE LOST. Continue?`,
151
- initialValue: false,
152
- });
153
- if (p.isCancel(answer) || !answer) {
154
- p.cancel("Reset cancelled.");
155
- return;
156
- }
157
- }
158
-
159
- const svc = new DbService();
160
- const output = await svc.reset(dbName);
161
- formatSuccess(`Database "${dbName}" has been recreated`, opts);
162
- if (!opts.quiet && output) {
163
- process.stdout.write(`${output}\n`);
164
- }
165
- }
166
-
167
- // ---------------------------------------------------------------------------
168
- // Registration
169
- // ---------------------------------------------------------------------------
170
-
171
- export function registerDbCommand(program: Command): void {
172
- const dbCmd = program
173
- .command("db")
174
- .summary("Manage D1 databases")
175
- .description(
176
- `Manage Cloudflare D1 databases — schema, queries, migrations, backup.
177
-
178
- SUBCOMMANDS:
179
- apply Apply schema.sql to D1
180
- migrate Run tracking migrations
181
- list List database tables
182
- query <sql> Execute a SQL query
183
- export Export database to .sql file
184
- reset Drop and recreate database (DESTRUCTIVE)
185
-
186
- OPTIONS:
187
- --database <name> Database name (auto-detected from config if omitted)
188
- --remote Operate on production (remote) database
189
-
190
- EXAMPLES:
191
- hoox db apply
192
- hoox db apply --remote
193
- hoox db migrate
194
- hoox db list
195
- hoox db query "SELECT * FROM trade_signals LIMIT 5"
196
- hoox db export
197
- hoox db reset`
198
- )
199
- .option("--database <name>", "Database name (auto-detected if omitted)")
200
- .option("--remote", "Operate on production (remote) database");
201
-
202
- // -- apply
203
- dbCmd
204
- .command("apply")
205
- .description("Apply schema.sql to the database")
206
- .option("--file <path>", "Path to schema.sql file")
207
- .action(async (options: { file?: string }, cmd: Command) => {
208
- const opts = getFormatOptions(cmd);
209
- try {
210
- const svc = new DbService();
211
- const dbName = await resolveDb(cmd, svc);
212
- const remote = Boolean(
213
- cmd.optsWithGlobals<{ remote?: boolean }>().remote
214
- );
215
- await handleApply(opts, dbName, remote, options.file);
216
- } catch (err) {
217
- formatError(err instanceof Error ? err : String(err), opts);
218
- process.exit(err instanceof CLIError ? err.code : ExitCode.ERROR);
219
- }
220
- });
221
-
222
- // -- migrate
223
- dbCmd
224
- .command("migrate")
225
- .description("Run tracking migrations")
226
- .action(async (_, cmd: Command) => {
227
- const opts = getFormatOptions(cmd);
228
- try {
229
- const svc = new DbService();
230
- const dbName = await resolveDb(cmd, svc);
231
- const remote = Boolean(
232
- cmd.optsWithGlobals<{ remote?: boolean }>().remote
233
- );
234
- await handleMigrate(opts, dbName, remote);
235
- } catch (err) {
236
- formatError(err instanceof Error ? err : String(err), opts);
237
- process.exit(err instanceof CLIError ? err.code : ExitCode.ERROR);
238
- }
239
- });
240
-
241
- // -- list
242
- dbCmd
243
- .command("list")
244
- .description("List database tables")
245
- .action(async (_, cmd: Command) => {
246
- const opts = getFormatOptions(cmd);
247
- try {
248
- const svc = new DbService();
249
- const dbName = await resolveDb(cmd, svc);
250
- const remote = Boolean(
251
- cmd.optsWithGlobals<{ remote?: boolean }>().remote
252
- );
253
- await handleList(opts, dbName, remote);
254
- } catch (err) {
255
- formatError(err instanceof Error ? err : String(err), opts);
256
- process.exit(err instanceof CLIError ? err.code : ExitCode.ERROR);
257
- }
258
- });
259
-
260
- // -- query
261
- dbCmd
262
- .command("query <sql>")
263
- .description("Execute a SQL query")
264
- .action(async (sql: string, _, cmd: Command) => {
265
- const opts = getFormatOptions(cmd);
266
- try {
267
- const svc = new DbService();
268
- const dbName = await resolveDb(cmd, svc);
269
- const remote = Boolean(
270
- cmd.optsWithGlobals<{ remote?: boolean }>().remote
271
- );
272
- await handleQuery(opts, dbName, sql, remote);
273
- } catch (err) {
274
- formatError(err instanceof Error ? err : String(err), opts);
275
- process.exit(err instanceof CLIError ? err.code : ExitCode.ERROR);
276
- }
277
- });
278
-
279
- // -- export
280
- dbCmd
281
- .command("export")
282
- .description("Export database to .sql file")
283
- .option("--output <path>", "Output file path")
284
- .action(async (options: { output?: string }, cmd: Command) => {
285
- const opts = getFormatOptions(cmd);
286
- try {
287
- const svc = new DbService();
288
- const dbName = await resolveDb(cmd, svc);
289
- await handleExport(opts, dbName, options.output);
290
- } catch (err) {
291
- formatError(err instanceof Error ? err : String(err), opts);
292
- process.exit(err instanceof CLIError ? err.code : ExitCode.ERROR);
293
- }
294
- });
295
-
296
- // -- reset
297
- dbCmd
298
- .command("reset")
299
- .description("Drop and recreate the database (DESTRUCTIVE)")
300
- .option("--confirm", "Skip confirmation prompt")
301
- .action(async (options: { confirm?: boolean }, cmd: Command) => {
302
- const opts = getFormatOptions(cmd);
303
- try {
304
- const svc = new DbService();
305
- const dbName = await resolveDb(cmd, svc);
306
- await handleReset(opts, dbName, Boolean(options.confirm));
307
- } catch (err) {
308
- formatError(err instanceof Error ? err : String(err), opts);
309
- process.exit(err instanceof CLIError ? err.code : ExitCode.ERROR);
310
- }
311
- });
312
- }
@@ -1 +0,0 @@
1
- export { registerDbCommand } from "./db-command.js";