@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,89 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { PrerequisitesService } from "./prerequisites-service.js";
3
-
4
- describe("PrerequisitesService", () => {
5
- describe("checkBun", () => {
6
- it("returns passed=true when bun version >= 1.2", async () => {
7
- const svc = new PrerequisitesService();
8
- const result = await svc.checkBun();
9
- expect(result.name).toBe("Bun");
10
- expect(result.category).toBe("tool");
11
- });
12
-
13
- it("returns version string", async () => {
14
- const svc = new PrerequisitesService();
15
- const result = await svc.checkBun();
16
- expect(typeof result.version).toBe("string");
17
- expect(result.version.length).toBeGreaterThan(0);
18
- });
19
- });
20
-
21
- describe("checkGit", () => {
22
- it("returns a result with name 'Git'", async () => {
23
- const svc = new PrerequisitesService();
24
- const result = await svc.checkGit();
25
- expect(result.name).toBe("Git");
26
- expect(result.category).toBe("tool");
27
- });
28
- });
29
-
30
- describe("checkNode", () => {
31
- it("returns a result (advisory — always passes)", async () => {
32
- const svc = new PrerequisitesService();
33
- const result = await svc.checkNode();
34
- expect(result.name).toBe("Node.js");
35
- expect(result.category).toBe("tool");
36
- });
37
- });
38
-
39
- describe("checkWrangler", () => {
40
- it("returns a result with name 'Wrangler CLI'", async () => {
41
- const svc = new PrerequisitesService();
42
- const result = await svc.checkWrangler();
43
- expect(result.name).toBe("Wrangler CLI");
44
- expect(result.category).toBe("tool");
45
- });
46
- });
47
-
48
- describe("checkCloudflareAuth", () => {
49
- it("returns a result with name 'Cloudflare Auth'", async () => {
50
- const svc = new PrerequisitesService();
51
- const result = await svc.checkCloudflareAuth();
52
- expect(result.name).toBe("Cloudflare Auth");
53
- expect(result.category).toBe("account");
54
- });
55
- });
56
-
57
- describe("checkDocker", () => {
58
- it("returns result (advisory — always passes)", async () => {
59
- const svc = new PrerequisitesService();
60
- const result = await svc.checkDocker();
61
- expect(result.name).toBe("Docker");
62
- expect(result.category).toBe("tool");
63
- });
64
- });
65
-
66
- describe("checkRepository", () => {
67
- it("returns a result with name 'Repository'", async () => {
68
- const svc = new PrerequisitesService();
69
- const result = await svc.checkRepository();
70
- expect(result.name).toBe("Repository");
71
- expect(result.category).toBe("repository");
72
- });
73
- });
74
-
75
- describe("runAll", () => {
76
- it("returns all 7 checks", async () => {
77
- const svc = new PrerequisitesService();
78
- const report = await svc.runAll();
79
- expect(report.checks.length).toBe(7);
80
- }, 30000);
81
-
82
- it("filters by tool name (case-insensitive exact match)", async () => {
83
- const svc = new PrerequisitesService();
84
- const report = await svc.runAll("bun");
85
- expect(report.checks.length).toBe(1);
86
- expect(report.checks[0].name).toBe("Bun");
87
- }, 30000);
88
- });
89
- });
@@ -1,377 +0,0 @@
1
- /**
2
- * PrerequisitesService checks runtime prerequisites before dev commands.
3
- *
4
- * Currently checks wrangler version against a known minimum.
5
- */
6
-
7
- interface WranglerVersionCheck {
8
- outdated: boolean;
9
- current?: string;
10
- minimum?: string;
11
- }
12
-
13
- /** Result of a single tool/account prerequisite check. */
14
- export interface PrerequisiteCheck {
15
- /** Display name (e.g. "Bun", "Git", "Wrangler CLI"). */
16
- name: string;
17
- /** Whether the check passed. */
18
- passed: boolean;
19
- /** Tool category for grouping: "tool", "account", "repository". */
20
- category: "tool" | "account" | "repository";
21
- /** The installed version (or "not found"). */
22
- version: string;
23
- /** The minimum required version (or "-" if not versioned). */
24
- required: string;
25
- /** How to install/fix if the check failed. */
26
- hint?: string;
27
- }
28
-
29
- /** Aggregated result from running all checks. */
30
- export interface PrerequisitesReport {
31
- checks: PrerequisiteCheck[];
32
- allPassed: boolean;
33
- }
34
-
35
- export class PrerequisitesService {
36
- private readonly MINIMUM_WRANGLER = "3.88.0";
37
-
38
- /**
39
- * Check if wrangler is installed and meets the minimum version.
40
- *
41
- * Returns `{ outdated: true }` when wrangler is found but below minimum.
42
- * Returns `{ outdated: false }` when version meets or exceeds minimum.
43
- * Returns `{ outdated: false }` when wrangler is not installed (advisory only).
44
- */
45
- async checkWranglerVersion(): Promise<WranglerVersionCheck> {
46
- try {
47
- const proc = Bun.spawn(["wrangler", "--version"], {
48
- stdout: "pipe",
49
- stderr: "pipe",
50
- });
51
-
52
- const stdout = await new Response(proc.stdout).text();
53
- const exitCode = await proc.exited;
54
-
55
- if (exitCode !== 0) {
56
- // wrangler not found or error — advisory, don't block
57
- return { outdated: false };
58
- }
59
-
60
- // wrangler --version output: "wrangler 3.87.0" or "3.87.0"
61
- const raw = stdout.trim();
62
- const match = raw.match(/(\d+\.\d+\.\d+)/);
63
- if (!match) {
64
- return { outdated: false };
65
- }
66
-
67
- const current = match[1];
68
- const meetsMin = this.satisfies(current, this.MINIMUM_WRANGLER);
69
-
70
- return {
71
- outdated: !meetsMin,
72
- current,
73
- minimum: this.MINIMUM_WRANGLER,
74
- };
75
- } catch {
76
- // wrangler not installed — advisory, don't block
77
- return { outdated: false };
78
- }
79
- }
80
-
81
- /**
82
- * Simple semver satisfies check: "3.87.0" satisfies "3.88.0" is false.
83
- * Returns true if `current >= minimum`.
84
- */
85
- private satisfies(current: string, minimum: string): boolean {
86
- const a = current.split(".").map(Number);
87
- const b = minimum.split(".").map(Number);
88
-
89
- for (let i = 0; i < 3; i++) {
90
- if ((a[i] ?? 0) > (b[i] ?? 0)) return true;
91
- if ((a[i] ?? 0) < (b[i] ?? 0)) return false;
92
- }
93
- return true;
94
- }
95
-
96
- /**
97
- * Check Bun version (minimum 1.2).
98
- * Runs `bun --version` and parses the output.
99
- */
100
- async checkBun(): Promise<PrerequisiteCheck> {
101
- const base = { name: "Bun", category: "tool" as const, required: ">=1.2" };
102
- try {
103
- const proc = Bun.spawn(["bun", "--version"], {
104
- stdout: "pipe",
105
- stderr: "pipe",
106
- });
107
- const stdout = await new Response(proc.stdout).text();
108
- const version = stdout.trim();
109
- const [major, minor] = version.split(".").map(Number);
110
- const passed = (major ?? 0) >= 1 && (minor ?? 0) >= 2;
111
- return {
112
- ...base,
113
- passed,
114
- version: version || "not found",
115
- hint: passed ? undefined : "Install: curl -fsSL https://bun.sh | bash",
116
- };
117
- } catch {
118
- return {
119
- ...base,
120
- passed: false,
121
- version: "not found",
122
- hint: "Install: curl -fsSL https://bun.sh | bash",
123
- };
124
- }
125
- }
126
-
127
- /**
128
- * Check Git version (minimum 2.40).
129
- * Runs `git --version` and parses the output.
130
- */
131
- async checkGit(): Promise<PrerequisiteCheck> {
132
- const base = { name: "Git", category: "tool" as const, required: ">=2.40" };
133
- try {
134
- const proc = Bun.spawn(["git", "--version"], {
135
- stdout: "pipe",
136
- stderr: "pipe",
137
- });
138
- const stdout = await new Response(proc.stdout).text();
139
- const match = stdout.match(/(\d+\.\d+)/);
140
- const version = match ? match[1] : "unknown";
141
- const [major, minor] = version.split(".").map(Number);
142
- const passed = (major ?? 0) >= 2 && (minor ?? 0) >= 40;
143
- return {
144
- ...base,
145
- passed,
146
- version,
147
- hint: passed ? undefined : "Install: apt install git",
148
- };
149
- } catch {
150
- return {
151
- ...base,
152
- passed: false,
153
- version: "not found",
154
- hint: "Install: apt install git",
155
- };
156
- }
157
- }
158
-
159
- /**
160
- * Check Node.js version — advisory only (minimum 18).
161
- * Runs `node --version` if available, skips gracefully if not installed.
162
- */
163
- async checkNode(): Promise<PrerequisiteCheck> {
164
- const base = {
165
- name: "Node.js",
166
- category: "tool" as const,
167
- required: ">=18 (optional)",
168
- };
169
- try {
170
- const proc = Bun.spawn(["node", "--version"], {
171
- stdout: "pipe",
172
- stderr: "pipe",
173
- });
174
- const stdout = await new Response(proc.stdout).text();
175
- const version = stdout.trim().replace(/^v/, "");
176
- const [major] = version.split(".").map(Number);
177
- const passed = (major ?? 0) >= 18;
178
- return {
179
- ...base,
180
- passed,
181
- version: version || "not found",
182
- hint: passed ? undefined : "Install: nvm or https://nodejs.org",
183
- };
184
- } catch {
185
- return {
186
- ...base,
187
- passed: true,
188
- version: "not installed",
189
- hint: "Optional — not required when using Bun",
190
- };
191
- }
192
- }
193
-
194
- /**
195
- * Check wrangler CLI version using existing checkWranglerVersion().
196
- * Delegates to the existing method to avoid duplicating semver logic.
197
- */
198
- async checkWrangler(): Promise<PrerequisiteCheck> {
199
- const base = {
200
- name: "Wrangler CLI",
201
- category: "tool" as const,
202
- required: `>=${this.MINIMUM_WRANGLER}`,
203
- };
204
- const result = await this.checkWranglerVersion();
205
- if (!result.current) {
206
- return {
207
- ...base,
208
- passed: false,
209
- version: "not found",
210
- hint: "Install: bun add -g wrangler",
211
- };
212
- }
213
- return {
214
- ...base,
215
- passed: !result.outdated,
216
- version: result.current,
217
- hint: result.outdated
218
- ? `Update: bun add -g wrangler@latest (${result.current} < ${result.minimum})`
219
- : undefined,
220
- };
221
- }
222
-
223
- /**
224
- * Check Cloudflare authentication via wrangler whoami.
225
- * Verifies the CLI is authenticated and extracts the user email.
226
- */
227
- async checkCloudflareAuth(): Promise<PrerequisiteCheck> {
228
- const base = {
229
- name: "Cloudflare Auth",
230
- category: "account" as const,
231
- required: "wrangler whoami",
232
- };
233
- try {
234
- const proc = Bun.spawn(["wrangler", "whoami"], {
235
- stdout: "pipe",
236
- stderr: "pipe",
237
- });
238
- const stdout = await new Response(proc.stdout).text();
239
- const exitCode = await proc.exited;
240
- const passed = exitCode === 0 && !stdout.includes("not authenticated");
241
- const email = stdout.match(/[\w.+-]+@[\w-]+\.[\w.]+/)?.[0];
242
- return {
243
- ...base,
244
- passed,
245
- version: email ? `Authenticated as ${email}` : "not authenticated",
246
- hint: passed ? undefined : "Run: wrangler login",
247
- };
248
- } catch {
249
- return {
250
- ...base,
251
- passed: false,
252
- version: "not authenticated",
253
- hint: "Run: wrangler login",
254
- };
255
- }
256
- }
257
-
258
- /**
259
- * Check Docker availability (optional — always passes even if not found).
260
- * Also checks `docker compose` availability separately.
261
- */
262
- async checkDocker(): Promise<PrerequisiteCheck> {
263
- const base = {
264
- name: "Docker",
265
- category: "tool" as const,
266
- required: "optional",
267
- };
268
- try {
269
- const proc = Bun.spawn(["docker", "--version"], {
270
- stdout: "pipe",
271
- stderr: "pipe",
272
- });
273
- const stdout = await new Response(proc.stdout).text();
274
- const version = stdout
275
- .trim()
276
- .replace(/^Docker version /, "")
277
- .replace(/,.*$/, "");
278
- let composeVersion = "";
279
- try {
280
- const composeProc = Bun.spawn(["docker", "compose", "version"], {
281
- stdout: "pipe",
282
- stderr: "pipe",
283
- });
284
- composeVersion = (await new Response(composeProc.stdout).text()).trim();
285
- } catch {
286
- /* compose optional */
287
- }
288
- return {
289
- ...base,
290
- passed: true,
291
- version:
292
- version + (composeVersion ? ` (compose: yes)` : " (compose: no)"),
293
- };
294
- } catch {
295
- return {
296
- ...base,
297
- passed: true,
298
- version: "not installed",
299
- hint: "Optional — used for Docker dev runtime",
300
- };
301
- }
302
- }
303
-
304
- /**
305
- * Check repository integrity: wrangler.jsonc exists, .env file present, submodules initialized.
306
- */
307
- async checkRepository(): Promise<PrerequisiteCheck> {
308
- const base = {
309
- name: "Repository",
310
- category: "repository" as const,
311
- required: "valid",
312
- };
313
- try {
314
- const wranglerExists = await Bun.file("wrangler.jsonc").exists();
315
- const envExists =
316
- (await Bun.file(".env.local").exists()) ||
317
- (await Bun.file(".env.example").exists());
318
- const issues: string[] = [];
319
- if (!wranglerExists) issues.push("wrangler.jsonc not found");
320
- if (!envExists) issues.push("no .env.local or .env.example found");
321
- let submoduleOk = false;
322
- try {
323
- const proc = Bun.spawn(["git", "submodule", "status"], {
324
- stdout: "pipe",
325
- stderr: "pipe",
326
- });
327
- const stdout = await new Response(proc.stdout).text();
328
- submoduleOk = !stdout.startsWith("-");
329
- } catch {
330
- /* not a git repo */
331
- }
332
- const passed = wranglerExists && issues.length === 0;
333
- return {
334
- ...base,
335
- passed,
336
- version:
337
- issues.length > 0
338
- ? issues.join("; ")
339
- : submoduleOk
340
- ? "OK"
341
- : "submodules may need init",
342
- hint: passed ? undefined : "Run: hoox init or hoox clone --all",
343
- };
344
- } catch {
345
- return {
346
- ...base,
347
- passed: false,
348
- version: "check failed",
349
- hint: "Check repository structure",
350
- };
351
- }
352
- }
353
-
354
- async runAll(filterTool?: string): Promise<PrerequisitesReport> {
355
- const allChecks: Promise<PrerequisiteCheck>[] = [
356
- this.checkBun(),
357
- this.checkGit(),
358
- this.checkNode(),
359
- this.checkWrangler(),
360
- this.checkCloudflareAuth(),
361
- this.checkDocker(),
362
- this.checkRepository(),
363
- ];
364
-
365
- let checks = await Promise.all(allChecks);
366
-
367
- if (filterTool) {
368
- const lower = filterTool.toLowerCase();
369
- checks = checks.filter((c) => c.name.toLowerCase() === lower);
370
- }
371
-
372
- return {
373
- checks,
374
- allPassed: checks.every((c) => c.passed),
375
- };
376
- }
377
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Types for the PrerequisitesService.
3
- *
4
- * Provides version checking for wrangler and Docker availability checks.
5
- */
6
-
7
- /** Version information for a CLI tool. */
8
- export interface VersionInfo {
9
- /** Installed version (semver string) or null if not installed. */
10
- installed: string | null;
11
- /** Latest available version (semver string) or null if fetch failed. */
12
- latest: string | null;
13
- /** Whether the installed version is outdated. */
14
- outdated: boolean;
15
- }
16
-
17
- /** Docker and Docker Compose availability status. */
18
- export interface DockerStatus {
19
- /** Whether Docker is available and running. */
20
- dockerAvailable: boolean;
21
- /** Docker version string or null if unavailable. */
22
- dockerVersion: string | null;
23
- /** Whether Docker Compose is available. */
24
- composeAvailable: boolean;
25
- /** Docker Compose version string or null if unavailable. */
26
- composeVersion: string | null;
27
- }
28
-
29
- /** Complete prerequisites check result. */
30
- export interface PrerequisitesResult {
31
- /** Wrangler version information. */
32
- wrangler: VersionInfo;
33
- /** Docker and Compose availability. */
34
- docker: DockerStatus;
35
- }
36
-
37
- /** Result of a wrangler version check operation. */
38
- export type WranglerVersionResult =
39
- | { ok: true; data: VersionInfo }
40
- | { ok: false; error: string };
41
-
42
- /** Result of a Docker check operation. */
43
- export type DockerCheckResult =
44
- | { ok: true; data: DockerStatus }
45
- | { ok: false; error: string };
46
-
47
- /** Result of a wrangler update operation. */
48
- export type UpdateWranglerResult = { ok: true } | { ok: false; error: string };
@@ -1,11 +0,0 @@
1
- export {
2
- SecretsService,
3
- default as SecretsServiceDefault,
4
- } from "./secrets-service.js";
5
- export type {
6
- Result,
7
- SecretStatus,
8
- SecretCheckResult,
9
- WorkerSecretConfig,
10
- WorkersJsonc,
11
- } from "./types.js";