@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.
- package/bin/hoox.js +3 -4
- package/dist/index.js +32545 -0
- package/package.json +10 -15
- package/src/commands/check/check-command.test.ts +0 -476
- package/src/commands/check/check-command.ts +0 -1144
- package/src/commands/check/index.ts +0 -10
- package/src/commands/check/prerequisites-command.test.ts +0 -19
- package/src/commands/check/prerequisites-command.ts +0 -96
- package/src/commands/check/types.ts +0 -103
- package/src/commands/clone/clone-command.test.ts +0 -442
- package/src/commands/clone/clone-command.ts +0 -431
- package/src/commands/clone/index.ts +0 -1
- package/src/commands/config/config-command.test.ts +0 -583
- package/src/commands/config/config-command.ts +0 -897
- package/src/commands/config/env-command.test.ts +0 -43
- package/src/commands/config/env-command.ts +0 -295
- package/src/commands/config/index.ts +0 -3
- package/src/commands/config/kv-command.test.ts +0 -14
- package/src/commands/config/kv-command.ts +0 -290
- package/src/commands/dashboard/dashboard-command.test.ts +0 -47
- package/src/commands/dashboard/dashboard-command.ts +0 -128
- package/src/commands/dashboard/index.ts +0 -1
- package/src/commands/db/db-command.test.ts +0 -21
- package/src/commands/db/db-command.ts +0 -312
- package/src/commands/db/index.ts +0 -1
- package/src/commands/deploy/deploy-command.test.ts +0 -304
- package/src/commands/deploy/deploy-command.ts +0 -1135
- package/src/commands/deploy/index.ts +0 -2
- package/src/commands/deploy/telegram-service.ts +0 -76
- package/src/commands/deploy/types.ts +0 -34
- package/src/commands/dev/dev-command.test.ts +0 -383
- package/src/commands/dev/dev-command.ts +0 -398
- package/src/commands/dev/index.ts +0 -1
- package/src/commands/infra/index.ts +0 -5
- package/src/commands/infra/infra-command.test.ts +0 -719
- package/src/commands/infra/infra-command.ts +0 -974
- package/src/commands/infra/types.ts +0 -23
- package/src/commands/init/__tests__/cli-provisioner.test.ts +0 -17
- package/src/commands/init/cli-provisioner.ts +0 -71
- package/src/commands/init/index.ts +0 -1
- package/src/commands/init/init-command.test.ts +0 -876
- package/src/commands/init/init-command.ts +0 -593
- package/src/commands/init/types.ts +0 -23
- package/src/commands/logs/index.ts +0 -1
- package/src/commands/logs/logs-command.test.ts +0 -294
- package/src/commands/logs/logs-command.ts +0 -452
- package/src/commands/monitor/index.ts +0 -2
- package/src/commands/monitor/monitor-command.test.ts +0 -263
- package/src/commands/monitor/monitor-command.ts +0 -269
- package/src/commands/monitor/monitor-service.ts +0 -65
- package/src/commands/monitor/types.ts +0 -13
- package/src/commands/repair/index.ts +0 -2
- package/src/commands/repair/repair-command.test.ts +0 -224
- package/src/commands/repair/repair-command.ts +0 -220
- package/src/commands/repair/repair-service.ts +0 -138
- package/src/commands/repair/types.ts +0 -13
- package/src/commands/test/index.ts +0 -2
- package/src/commands/test/test-command.test.ts +0 -319
- package/src/commands/test/test-command.ts +0 -406
- package/src/commands/tui/index.ts +0 -1
- package/src/commands/tui/tui-command.ts +0 -87
- package/src/commands/update/index.ts +0 -1
- package/src/commands/update/update-command.ts +0 -168
- package/src/commands/waf/index.ts +0 -2
- package/src/commands/waf/types.ts +0 -48
- package/src/commands/waf/waf-command.test.ts +0 -506
- package/src/commands/waf/waf-command.ts +0 -548
- package/src/index.ts +0 -269
- package/src/services/cloudflare/cloudflare-service.test.ts +0 -658
- package/src/services/cloudflare/cloudflare-service.ts +0 -433
- package/src/services/cloudflare/index.ts +0 -2
- package/src/services/cloudflare/types.ts +0 -30
- package/src/services/config/config-service.test.ts +0 -395
- package/src/services/config/config-service.ts +0 -207
- package/src/services/config/index.ts +0 -9
- package/src/services/config/types.ts +0 -66
- package/src/services/db/db-service.test.ts +0 -51
- package/src/services/db/db-service.ts +0 -131
- package/src/services/db/index.ts +0 -1
- package/src/services/docker/docker-service.ts +0 -155
- package/src/services/docker/index.ts +0 -1
- package/src/services/env/env-service.test.ts +0 -236
- package/src/services/env/env-service.ts +0 -386
- package/src/services/env/index.ts +0 -1
- package/src/services/kv/index.ts +0 -1
- package/src/services/kv/kv-sync-service.test.ts +0 -38
- package/src/services/kv/kv-sync-service.ts +0 -234
- package/src/services/prerequisites/index.ts +0 -1
- package/src/services/prerequisites/prerequisites-service.test.ts +0 -89
- package/src/services/prerequisites/prerequisites-service.ts +0 -377
- package/src/services/prerequisites/types.ts +0 -48
- package/src/services/secrets/index.ts +0 -11
- package/src/services/secrets/secrets-service.test.ts +0 -495
- package/src/services/secrets/secrets-service.ts +0 -287
- package/src/services/secrets/types.ts +0 -50
- package/src/services/update/index.ts +0 -2
- package/src/services/update/update-service.test.ts +0 -76
- package/src/services/update/update-service.ts +0 -193
- package/src/ui/banner.ts +0 -141
- package/src/ui/index.ts +0 -8
- package/src/ui/menu.ts +0 -490
- package/src/utils/errors.test.ts +0 -69
- package/src/utils/errors.ts +0 -23
- package/src/utils/formatters.test.ts +0 -180
- package/src/utils/formatters.ts +0 -269
- 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 };
|