@jango-blockchained/hoox-cli 0.5.2 → 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 (114) 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 -1087
  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 -97
  9. package/src/commands/check/types.ts +0 -103
  10. package/src/commands/clone/clone-command.test.ts +0 -440
  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 -896
  15. package/src/commands/config/env-command.test.ts +0 -43
  16. package/src/commands/config/env-command.ts +0 -292
  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 -130
  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 -311
  25. package/src/commands/db/index.ts +0 -1
  26. package/src/commands/deploy/deploy-command.test.ts +0 -324
  27. package/src/commands/deploy/deploy-command.ts +0 -1054
  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 -405
  32. package/src/commands/dev/dev-command.ts +0 -398
  33. package/src/commands/dev/index.ts +0 -1
  34. package/src/commands/disclaimer/disclaimer-command.ts +0 -21
  35. package/src/commands/disclaimer/index.ts +0 -1
  36. package/src/commands/infra/index.ts +0 -5
  37. package/src/commands/infra/infra-command.test.ts +0 -719
  38. package/src/commands/infra/infra-command.ts +0 -974
  39. package/src/commands/infra/types.ts +0 -23
  40. package/src/commands/init/__tests__/cli-provisioner.test.ts +0 -17
  41. package/src/commands/init/cli-provisioner.ts +0 -71
  42. package/src/commands/init/index.ts +0 -1
  43. package/src/commands/init/init-command.test.ts +0 -854
  44. package/src/commands/init/init-command.ts +0 -597
  45. package/src/commands/init/types.ts +0 -23
  46. package/src/commands/logs/index.ts +0 -1
  47. package/src/commands/logs/logs-command.test.ts +0 -293
  48. package/src/commands/logs/logs-command.ts +0 -452
  49. package/src/commands/monitor/index.ts +0 -2
  50. package/src/commands/monitor/monitor-command.test.ts +0 -271
  51. package/src/commands/monitor/monitor-command.ts +0 -269
  52. package/src/commands/monitor/monitor-service.ts +0 -65
  53. package/src/commands/monitor/types.ts +0 -13
  54. package/src/commands/repair/index.ts +0 -2
  55. package/src/commands/repair/repair-command.test.ts +0 -243
  56. package/src/commands/repair/repair-command.ts +0 -220
  57. package/src/commands/repair/repair-service.ts +0 -164
  58. package/src/commands/repair/types.ts +0 -13
  59. package/src/commands/schema/index.ts +0 -1
  60. package/src/commands/schema/schema-command.ts +0 -137
  61. package/src/commands/test/index.ts +0 -2
  62. package/src/commands/test/test-command.test.ts +0 -318
  63. package/src/commands/test/test-command.ts +0 -406
  64. package/src/commands/tui/index.ts +0 -1
  65. package/src/commands/tui/tui-command.ts +0 -87
  66. package/src/commands/update/index.ts +0 -1
  67. package/src/commands/update/update-command.ts +0 -109
  68. package/src/commands/waf/index.ts +0 -2
  69. package/src/commands/waf/types.ts +0 -48
  70. package/src/commands/waf/waf-command.test.ts +0 -506
  71. package/src/commands/waf/waf-command.ts +0 -545
  72. package/src/index.ts +0 -261
  73. package/src/services/cloudflare/cloudflare-service.test.ts +0 -658
  74. package/src/services/cloudflare/cloudflare-service.ts +0 -433
  75. package/src/services/cloudflare/index.ts +0 -2
  76. package/src/services/cloudflare/types.ts +0 -30
  77. package/src/services/config/config-service.test.ts +0 -395
  78. package/src/services/config/config-service.ts +0 -202
  79. package/src/services/config/index.ts +0 -9
  80. package/src/services/config/types.ts +0 -66
  81. package/src/services/db/db-service.test.ts +0 -63
  82. package/src/services/db/db-service.ts +0 -131
  83. package/src/services/db/index.ts +0 -1
  84. package/src/services/docker/docker-service.ts +0 -155
  85. package/src/services/docker/index.ts +0 -1
  86. package/src/services/env/env-service.test.ts +0 -259
  87. package/src/services/env/env-service.ts +0 -372
  88. package/src/services/env/index.ts +0 -1
  89. package/src/services/kv/index.ts +0 -1
  90. package/src/services/kv/kv-sync-service.test.ts +0 -38
  91. package/src/services/kv/kv-sync-service.ts +0 -243
  92. package/src/services/prerequisites/index.ts +0 -1
  93. package/src/services/prerequisites/prerequisites-service.test.ts +0 -89
  94. package/src/services/prerequisites/prerequisites-service.ts +0 -377
  95. package/src/services/prerequisites/types.ts +0 -48
  96. package/src/services/schema/index.ts +0 -1
  97. package/src/services/schema/schema-service.ts +0 -99
  98. package/src/services/secrets/index.ts +0 -11
  99. package/src/services/secrets/secrets-service.test.ts +0 -502
  100. package/src/services/secrets/secrets-service.ts +0 -287
  101. package/src/services/secrets/types.ts +0 -50
  102. package/src/services/update/index.ts +0 -2
  103. package/src/services/update/update-service.test.ts +0 -76
  104. package/src/services/update/update-service.ts +0 -193
  105. package/src/ui/banner.ts +0 -141
  106. package/src/ui/index.ts +0 -8
  107. package/src/ui/menu.ts +0 -490
  108. package/src/utils/error-handler.ts +0 -62
  109. package/src/utils/errors.test.ts +0 -69
  110. package/src/utils/errors.ts +0 -24
  111. package/src/utils/formatters.test.ts +0 -180
  112. package/src/utils/formatters.ts +0 -269
  113. package/src/utils/git.ts +0 -134
  114. package/src/utils/theme.ts +0 -92
@@ -1,406 +0,0 @@
1
- /**
2
- * `hoox test` command group — run tests and CI pipeline.
3
- *
4
- * Subcommands:
5
- * all — Run full CI pipeline (lint → typecheck → unit → integration)
6
- * unit — Run bun test (unit tests)
7
- * integration — Run vitest integration tests
8
- * worker — Run tests for a specific worker directory
9
- * live — Run live Cloudflare service tests (no mocks)
10
- */
11
- import { Command } from "commander";
12
- import { spinner } from "@clack/prompts";
13
- import { ConfigService } from "../../services/config/index.js";
14
- import { theme, icons } from "../../utils/theme.js";
15
- import {
16
- formatSuccess,
17
- formatError,
18
- formatTable,
19
- formatJson,
20
- getFormatOptions,
21
- } from "../../utils/formatters.js";
22
- import { CLIError, ExitCode } from "../../utils/errors.js";
23
-
24
- // ---------------------------------------------------------------------------
25
- // Types
26
- // ---------------------------------------------------------------------------
27
-
28
- /** Result of a single pipeline step or test run. */
29
- export interface TestStepResult {
30
- /** Human-readable step name (e.g. "Lint", "Unit Tests"). */
31
- step: string;
32
- /** The raw command string that was executed. */
33
- command: string;
34
- /** Whether the step exited with code 0. */
35
- success: boolean;
36
- /** Process exit code (null if the process failed to spawn). */
37
- exitCode: number | null;
38
- /** Wall-clock duration in milliseconds. */
39
- duration: number;
40
- /** Captured stdout (trimmed). */
41
- output?: string;
42
- /** Captured stderr or exception message. */
43
- error?: string;
44
- }
45
-
46
- /** Aggregated summary of a test pipeline run. */
47
- export interface TestSummary {
48
- total: number;
49
- passed: number;
50
- failed: number;
51
- results: TestStepResult[];
52
- }
53
-
54
- /**
55
- * Spawn a command with stdout/stderr piped, capture output, and return a
56
- * structured result. Does NOT print anything — the caller decides display.
57
- */
58
- export async function runStep(
59
- args: string[],
60
- cwd?: string
61
- ): Promise<TestStepResult> {
62
- const command = args.join(" ");
63
- const start = Date.now();
64
-
65
- try {
66
- const proc = Bun.spawn(args, {
67
- cwd: cwd ?? process.cwd(),
68
- stdout: "pipe",
69
- stderr: "pipe",
70
- });
71
-
72
- const exitCode = await proc.exited;
73
- const stdout = await new Response(proc.stdout).text();
74
- const stderr = await new Response(proc.stderr).text();
75
- const duration = Date.now() - start;
76
-
77
- return {
78
- step: command,
79
- command,
80
- success: exitCode === 0,
81
- exitCode,
82
- duration,
83
- output: stdout.trim() || undefined,
84
- error: stderr.trim() ? stderr.trim() : undefined,
85
- };
86
- } catch (err) {
87
- return {
88
- step: command,
89
- command,
90
- success: false,
91
- exitCode: null,
92
- duration: Date.now() - start,
93
- error: err instanceof Error ? err.message : String(err),
94
- };
95
- }
96
- }
97
-
98
- /**
99
- * Spawn a command with stdout/stderr inherited so the user sees live output.
100
- * Returns a minimal result with exit code.
101
- */
102
- async function runWithInherit(
103
- args: string[],
104
- cwd?: string
105
- ): Promise<TestStepResult> {
106
- const command = args.join(" ");
107
- const start = Date.now();
108
-
109
- try {
110
- const proc = Bun.spawn(args, {
111
- cwd: cwd ?? process.cwd(),
112
- stdout: "inherit",
113
- stderr: "inherit",
114
- });
115
- const exitCode = await proc.exited;
116
- const duration = Date.now() - start;
117
-
118
- return {
119
- step: command,
120
- command,
121
- success: exitCode === 0,
122
- exitCode,
123
- duration,
124
- };
125
- } catch (err) {
126
- return {
127
- step: command,
128
- command,
129
- success: false,
130
- exitCode: null,
131
- duration: Date.now() - start,
132
- error: err instanceof Error ? err.message : String(err),
133
- };
134
- }
135
- }
136
-
137
- /**
138
- * Print a pipeline summary table (or JSON if --json is set).
139
- * Quiet mode suppresses all output.
140
- */
141
- export function printSummary(
142
- summary: TestSummary,
143
- opts: { json?: boolean; quiet?: boolean }
144
- ): void {
145
- if (opts.quiet) return;
146
-
147
- if (opts.json) {
148
- formatJson(summary, opts);
149
- return;
150
- }
151
-
152
- const rows = summary.results.map((r) => ({
153
- Step: r.step,
154
- Status: r.success ? "passed" : "failed",
155
- Time: `${r.duration}ms`,
156
- }));
157
-
158
- formatTable(rows, opts);
159
-
160
- // Final status line
161
- if (summary.failed > 0) {
162
- formatError(
163
- new CLIError(
164
- `${summary.passed}/${summary.total} passed — ${summary.failed} failed`,
165
- ExitCode.ERROR
166
- ),
167
- opts
168
- );
169
- } else {
170
- formatSuccess(`All ${summary.total} steps passed`, opts);
171
- }
172
- }
173
-
174
- // ---------------------------------------------------------------------------
175
- // Pipeline step definitions for `all` subcommand
176
- // ---------------------------------------------------------------------------
177
-
178
- const PIPELINE_STEPS: { label: string; args: string[] }[] = [
179
- { label: "Lint", args: ["bun", "run", "lint"] },
180
- { label: "TypeCheck", args: ["bun", "run", "typecheck"] },
181
- { label: "Unit Tests", args: ["bun", "test", "--coverage"] },
182
- {
183
- label: "Integration Tests",
184
- args: ["vitest", "run", "--config", "vitest.config.ts"],
185
- },
186
- ];
187
-
188
- // ---------------------------------------------------------------------------
189
- // Command registration
190
- // ---------------------------------------------------------------------------
191
-
192
- /**
193
- * Register the `hoox test` command group with subcommands:
194
- * all, unit, integration, worker, live.
195
- */
196
- export function registerTestCommand(program: Command): void {
197
- const testCmd = program
198
- .command("test")
199
- .description("Run tests and CI pipeline");
200
-
201
- // -- test all ----------------------------------------------------------
202
- testCmd
203
- .command("all")
204
- .description(
205
- "Run full CI pipeline: lint → typecheck → unit tests → integration tests"
206
- )
207
- .option("--json", "Output results as JSON")
208
- .action(async (options: { json?: boolean }) => {
209
- const fmt = getFormatOptions(program);
210
- // Allow local --json to override global
211
- const useJson = options.json || fmt.json;
212
- const opts = { json: useJson, quiet: fmt.quiet };
213
-
214
- const results: TestStepResult[] = [];
215
- const s = spinner();
216
- s.start("Running CI pipeline...");
217
-
218
- try {
219
- for (const step of PIPELINE_STEPS) {
220
- s.message(`${theme.info(icons.info)} ${step.label}...`);
221
- const result = await runStep(step.args, process.cwd());
222
- results.push({ ...result, step: step.label });
223
-
224
- if (result.success) {
225
- s.message(
226
- ` ${theme.success(icons.success)} ${step.label} passed (${result.duration}ms)`
227
- );
228
- } else {
229
- s.message(
230
- ` ${theme.error(icons.error)} ${step.label} failed (${result.duration}ms)`
231
- );
232
- if (result.error) {
233
- s.message(theme.dim(result.error.slice(0, 500)));
234
- }
235
- // Stop on first failure
236
- break;
237
- }
238
- }
239
- } catch (err) {
240
- const message = err instanceof Error ? err.message : String(err);
241
- formatError(message, opts);
242
- process.exitCode = ExitCode.ERROR;
243
- s.stop("Pipeline aborted with unexpected error");
244
- return;
245
- }
246
-
247
- const summary: TestSummary = {
248
- total: results.length,
249
- passed: results.filter((r) => r.success).length,
250
- failed: results.filter((r) => !r.success).length,
251
- results,
252
- };
253
-
254
- s.stop(
255
- summary.failed > 0
256
- ? `Pipeline complete: ${summary.passed} passed, ${summary.failed} failed`
257
- : "Pipeline complete"
258
- );
259
-
260
- printSummary(summary, opts);
261
-
262
- if (summary.failed > 0) {
263
- process.exitCode = ExitCode.ERROR;
264
- }
265
- });
266
-
267
- // -- test unit ---------------------------------------------------------
268
- testCmd
269
- .command("unit")
270
- .description("Run unit tests with bun test")
271
- .option("--coverage", "Run with coverage reporting")
272
- .action(async (options: { coverage?: boolean }) => {
273
- const fmt = getFormatOptions(program);
274
- const args = ["bun", "test"];
275
- if (options.coverage) args.push("--coverage");
276
-
277
- const result = await runWithInherit(args, process.cwd());
278
-
279
- if (result.success) {
280
- formatSuccess("Unit tests passed", fmt);
281
- } else {
282
- formatError(
283
- new CLIError(
284
- `Unit tests failed (exit code ${result.exitCode})`,
285
- ExitCode.ERROR
286
- ),
287
- fmt
288
- );
289
- process.exitCode = ExitCode.ERROR;
290
- }
291
- });
292
-
293
- // -- test integration --------------------------------------------------
294
- testCmd
295
- .command("integration")
296
- .description("Run integration tests with vitest")
297
- .option("--coverage", "Run with coverage reporting")
298
- .action(async (options: { coverage?: boolean }) => {
299
- const fmt = getFormatOptions(program);
300
- const args = ["vitest", "run", "--config", "vitest.config.ts"];
301
- if (options.coverage) args.push("--coverage");
302
-
303
- const result = await runWithInherit(args, process.cwd());
304
-
305
- if (result.success) {
306
- formatSuccess("Integration tests passed", fmt);
307
- } else {
308
- formatError(
309
- new CLIError(
310
- `Integration tests failed (exit code ${result.exitCode})`,
311
- ExitCode.ERROR
312
- ),
313
- fmt
314
- );
315
- process.exitCode = ExitCode.ERROR;
316
- }
317
- });
318
-
319
- // -- test worker <name> ------------------------------------------------
320
- testCmd
321
- .command("worker <name>")
322
- .description("Run tests for a specific worker by name")
323
- .option("--coverage", "Run with coverage reporting")
324
- .action(async (name: string, options: { coverage?: boolean }) => {
325
- const fmt = getFormatOptions(program);
326
-
327
- try {
328
- const configService = new ConfigService();
329
- await configService.load();
330
- const workerConfig = configService.getWorker(name);
331
-
332
- if (!workerConfig) {
333
- formatError(
334
- new CLIError(
335
- `Worker "${name}" not found in wrangler.jsonc`,
336
- ExitCode.INVALID_USAGE
337
- ),
338
- fmt
339
- );
340
- process.exitCode = ExitCode.INVALID_USAGE;
341
- return;
342
- }
343
-
344
- const workerDir = `${process.cwd()}/${workerConfig.path}`;
345
- const args = ["bun", "test"];
346
- if (options.coverage) args.push("--coverage");
347
-
348
- const result = await runWithInherit(args, workerDir);
349
-
350
- if (result.success) {
351
- formatSuccess(`Worker "${name}" tests passed`, fmt);
352
- } else {
353
- formatError(
354
- new CLIError(
355
- `Worker "${name}" tests failed (exit code ${result.exitCode})`,
356
- ExitCode.ERROR
357
- ),
358
- fmt
359
- );
360
- process.exitCode = ExitCode.ERROR;
361
- }
362
- } catch (err) {
363
- const message = err instanceof Error ? err.message : String(err);
364
- formatError(message, fmt);
365
- process.exitCode = ExitCode.ERROR;
366
- }
367
- });
368
-
369
- // -- test live ---------------------------------------------------------
370
- testCmd
371
- .command("live")
372
- .description("Run live Cloudflare service integration tests (no mocks)")
373
- .option(
374
- "--service <name>",
375
- "Test a specific service: d1, kv, r2, queues, ai, api, secrets, durable-objects"
376
- )
377
- .action(async (options: { service?: string }) => {
378
- const fmt = getFormatOptions(program);
379
- const s = spinner();
380
-
381
- try {
382
- let filePattern = options.service
383
- ? `tests/live/${options.service}.test.ts`
384
- : "tests/live/";
385
-
386
- s.start(
387
- `Running live tests${options.service ? ` for ${options.service}` : ""}...`
388
- );
389
-
390
- const args = ["bun", "test", filePattern, "--jobs", "1"];
391
- const result = await runWithInherit(args, process.cwd());
392
-
393
- if (result.success) {
394
- s.stop("Live tests complete");
395
- } else {
396
- s.stop(`Live tests: some failures (exit code ${result.exitCode})`);
397
- process.exitCode = ExitCode.ERROR;
398
- }
399
- } catch (err) {
400
- s.stop("Live tests aborted");
401
- const message = err instanceof Error ? err.message : String(err);
402
- formatError(message, fmt);
403
- process.exitCode = ExitCode.ERROR;
404
- }
405
- });
406
- }
@@ -1 +0,0 @@
1
- export { registerTUICommand } from "./tui-command.js";
@@ -1,87 +0,0 @@
1
- /**
2
- * `hoox tui` command — launch the OpenTUI terminal operations center.
3
- *
4
- * Spawns the TUI as a child Bun process so it can take over the terminal
5
- * with alternate screen mode. When the TUI exits, control returns to the CLI.
6
- */
7
- import { Command } from "commander";
8
- import { spawn } from "node:child_process";
9
- import { resolve, dirname } from "node:path";
10
- import { fileURLToPath } from "node:url";
11
- import { existsSync } from "node:fs";
12
- import { theme } from "../../utils/theme.js";
13
- import { CLIError, ExitCode } from "../../utils/errors.js";
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
-
17
- /** Resolve the TUI entry point relative to the monorepo root */
18
- function resolveTUIEntry(): string {
19
- // Try monorepo-relative paths first
20
- const candidates = [
21
- resolve(__dirname, "../../../../tui/src/main.tsx"), // packages/cli → packages/tui
22
- resolve(process.cwd(), "packages/tui/src/main.tsx"), // CWD = repo root
23
- resolve(process.cwd(), "../tui/src/main.tsx"), // CWD = packages/cli
24
- ];
25
-
26
- for (const path of candidates) {
27
- if (existsSync(path)) return path;
28
- }
29
-
30
- throw new CLIError(
31
- "Could not find TUI entry point. Ensure packages/tui/src/main.tsx exists.",
32
- ExitCode.ERROR
33
- );
34
- }
35
-
36
- export function registerTUICommand(program: Command): void {
37
- program
38
- .command("tui")
39
- .description("Launch the OpenTUI terminal operations center")
40
- .option("--fps <number>", "Target frames per second", "30")
41
- .option("--no-mouse", "Disable mouse support")
42
- .action(async (options) => {
43
- const tuiEntry = resolveTUIEntry();
44
-
45
- console.log(
46
- theme.heading("\nLaunching HOOX Terminal Operations Center...\n")
47
- );
48
- console.log(theme.dim(` Entry: ${tuiEntry}`));
49
- console.log(theme.dim(` FPS: ${options.fps}`));
50
- console.log(
51
- theme.dim(` Mouse: ${options.mouse ? "enabled" : "disabled"}\n`)
52
- );
53
-
54
- // Spawn the TUI as a child process — it takes over the terminal
55
- const child = spawn("bun", ["run", tuiEntry], {
56
- stdio: "inherit", // TUI gets full terminal control
57
- env: {
58
- ...process.env,
59
- TUI_FPS: options.fps,
60
- TUI_MOUSE: options.mouse ? "1" : "0",
61
- },
62
- });
63
-
64
- // Wait for TUI to exit
65
- await new Promise<void>((resolveChild, reject) => {
66
- child.on("close", (code) => {
67
- if (code === 0) {
68
- console.log(theme.dim("\nTUI session ended.\n"));
69
- resolveChild();
70
- } else if (code !== null) {
71
- console.log(theme.dim(`\nTUI exited with code ${code}\n`));
72
- resolveChild();
73
- } else {
74
- reject(
75
- new CLIError("TUI process terminated abnormally", ExitCode.ERROR)
76
- );
77
- }
78
- });
79
-
80
- child.on("error", (err) => {
81
- reject(
82
- new CLIError(`Failed to launch TUI: ${err.message}`, ExitCode.ERROR)
83
- );
84
- });
85
- });
86
- });
87
- }
@@ -1 +0,0 @@
1
- export { registerUpdateCommand } from "./update-command.js";
@@ -1,109 +0,0 @@
1
- import { Command } from "commander";
2
- import { spinner } from "@clack/prompts";
3
- import { ConfigService } from "../../services/config/index.js";
4
- import { UpdateService } from "../../services/update/index.js";
5
- import { formatError, getFormatOptions } from "../../utils/formatters.js";
6
- import { CLIError, ExitCode } from "../../utils/errors.js";
7
- import { theme } from "../../utils/theme.js";
8
- import {
9
- gitPull,
10
- gitSubmoduleUpdate,
11
- isGitRepo,
12
- isSubmodule,
13
- } from "../../utils/git.js";
14
-
15
- export function registerUpdateCommand(program: Command): void {
16
- program
17
- .command("update")
18
- .summary("Sync repo from GitHub or update wrangler")
19
- .description(
20
- `Update your local project from GitHub or update wrangler.
21
-
22
- Without arguments, pulls latest changes for the main repo.
23
- With a worker name, updates that worker's submodule from its remote.
24
- With "wrangler", updates wrangler to the latest version.
25
-
26
- EXAMPLES:
27
- hoox update Pull latest for main repo
28
- hoox update d1-worker Update the d1-worker submodule
29
- hoox update wrangler Update wrangler to latest version`
30
- )
31
- .argument(
32
- "[target]",
33
- 'What to update: worker name (e.g. d1-worker) or "wrangler"'
34
- )
35
- .action(async (target?: string) => {
36
- const fmt = getFormatOptions(program);
37
- const cwd = process.cwd();
38
-
39
- try {
40
- if (target === "wrangler") {
41
- const service = new UpdateService();
42
- const result = await service.updateWrangler();
43
-
44
- if (result.error) {
45
- formatError(
46
- new CLIError(`Update failed: ${result.error}`, ExitCode.ERROR),
47
- fmt
48
- );
49
- process.exitCode = ExitCode.ERROR;
50
- }
51
- return;
52
- }
53
-
54
- if (!(await isGitRepo(cwd))) {
55
- throw new CLIError(
56
- "Not a git repository — run this command from the project root",
57
- ExitCode.INVALID_USAGE
58
- );
59
- }
60
-
61
- if (target) {
62
- const configService = new ConfigService();
63
- await configService.load();
64
- const worker = configService.getWorker(target);
65
-
66
- if (!worker) {
67
- throw new CLIError(
68
- `Unknown worker "${target}" — not found in wrangler.jsonc`,
69
- ExitCode.INVALID_USAGE
70
- );
71
- }
72
-
73
- const submodulePath = worker.path;
74
- if (!(await isSubmodule(cwd, submodulePath))) {
75
- throw new CLIError(
76
- `"${submodulePath}" is not a git submodule — nothing to update`,
77
- ExitCode.INVALID_USAGE
78
- );
79
- }
80
-
81
- const s = spinner();
82
- s.start(`Updating ${target}...`);
83
-
84
- const output = await gitSubmoduleUpdate(cwd, submodulePath);
85
-
86
- s.stop(
87
- output
88
- ? theme.success(`Updated ${target}`)
89
- : theme.muted(`${target} already up to date`)
90
- );
91
- } else {
92
- const s = spinner();
93
- s.start("Pulling latest from remote...");
94
-
95
- const output = await gitPull(cwd);
96
-
97
- s.stop(
98
- output
99
- ? theme.success("Repository up to date")
100
- : theme.muted("Already up to date")
101
- );
102
- }
103
- } catch (err) {
104
- const message = err instanceof Error ? err.message : String(err);
105
- formatError(message, fmt);
106
- process.exitCode = ExitCode.ERROR;
107
- }
108
- });
109
- }
@@ -1,2 +0,0 @@
1
- export { registerWafCommand } from "./waf-command.js";
2
- export type { WafStatus, WafRule, WafMode, WafRuleInput } from "./types.js";
@@ -1,48 +0,0 @@
1
- /**
2
- * Waf command type definitions.
3
- */
4
-
5
- /** WAF status summary returned by `hoox waf status`. */
6
- export interface WafStatus {
7
- /** Whether WAF protection is enabled on the zone. */
8
- enabled: boolean;
9
- /** WAF mode (e.g. "on", "off", "simulate"). */
10
- mode: string;
11
- /** Number of active firewall rules on the zone. */
12
- activeRulesCount: number;
13
- /** Approximate count of recent blocked requests (last 24h). */
14
- recentBlocks: number;
15
- /** Cloudflare zone ID. */
16
- zoneId: string;
17
- /** Cloudflare zone name (domain). */
18
- zoneName: string;
19
- }
20
-
21
- /** A Cloudflare WAF / firewall rule. */
22
- export interface WafRule {
23
- /** Unique rule identifier. */
24
- id: string;
25
- /** Human-readable description of the rule. */
26
- description: string;
27
- /** Rule mode: "block", "challenge", "js_challenge", "allow", "log". */
28
- mode: string;
29
- /** Cloudflare Filters expression that triggers the rule. */
30
- expression: string;
31
- /** ISO 8601 creation timestamp. */
32
- created_at: string;
33
- /** ISO 8601 last-modified timestamp. */
34
- updated_at: string;
35
- }
36
-
37
- /** WAF toggle mode. */
38
- export type WafMode = "on" | "off";
39
-
40
- /** Input for creating a new WAF rule. */
41
- export interface WafRuleInput {
42
- /** Rule type: "ip-allowlist", "ip-blocklist", "rate-limit", "custom". */
43
- type: "ip-allowlist" | "ip-blocklist" | "rate-limit" | "custom";
44
- /** Value associated with the rule type (IP address, requests/period, etc.). */
45
- value: string;
46
- /** Optional human-readable description. */
47
- description?: string;
48
- }