Skip to content

Commit 73d7eb9

Browse files
guo-yuclaude
andcommitted
fix: check wrangler auth via config file instead of unreliable whoami
wrangler whoami fails in Bun.spawn due to network issues, causing false not_authenticated status. Read the local config file to check for oauth_token/api_token instead. Bump shipkey to 0.3.10 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 45fa7bf commit 73d7eb9

2 files changed

Lines changed: 42 additions & 8 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "shipkey",
3-
"version": "0.3.9",
3+
"version": "0.3.10",
44
"type": "module",
55
"workspaces": ["packages/*"],
66
"repository": {

src/targets/cloudflare.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,41 @@
1+
import { readFile } from "fs/promises";
2+
import { join } from "path";
3+
import { homedir } from "os";
14
import type { SyncTarget, SyncResult, TargetStatus } from "./types";
25

36
export class CloudflareTarget implements SyncTarget {
47
readonly name = "Cloudflare Workers";
58

9+
private getWranglerConfigPaths(): string[] {
10+
const home = homedir();
11+
const custom = process.env.WRANGLER_HOME;
12+
const paths: string[] = [];
13+
if (custom) paths.push(join(custom, "config", "default.toml"));
14+
if (process.platform === "darwin") {
15+
paths.push(join(home, "Library", "Preferences", ".wrangler", "config", "default.toml"));
16+
}
17+
// XDG / Linux / fallback
18+
const xdg = process.env.XDG_CONFIG_HOME || join(home, ".config");
19+
paths.push(join(xdg, ".wrangler", "config", "default.toml"));
20+
// Windows
21+
if (process.env.APPDATA) {
22+
paths.push(join(process.env.APPDATA, ".wrangler", "config", "default.toml"));
23+
}
24+
return paths;
25+
}
26+
27+
private async checkAuthFromConfig(): Promise<boolean> {
28+
for (const configPath of this.getWranglerConfigPaths()) {
29+
try {
30+
const config = await readFile(configPath, "utf-8");
31+
if (config.includes("oauth_token") || config.includes("api_token")) {
32+
return true;
33+
}
34+
} catch {}
35+
}
36+
return false;
37+
}
38+
639
async checkStatus(): Promise<TargetStatus> {
740
try {
841
const proc = Bun.spawn(["wrangler", "--version"], {
@@ -15,20 +48,21 @@ export class CloudflareTarget implements SyncTarget {
1548
return "not_installed";
1649
}
1750

51+
// Try wrangler whoami first (most accurate when network is available)
1852
try {
1953
const proc = Bun.spawn(["wrangler", "whoami"], {
2054
stdout: "pipe",
2155
stderr: "pipe",
2256
});
2357
const stdout = await new Response(proc.stdout).text();
2458
await proc.exited;
25-
if (proc.exitCode !== 0 || !stdout.includes("You are logged in")) {
26-
return "not_authenticated";
27-
}
28-
return "ready";
29-
} catch {
30-
return "not_authenticated";
31-
}
59+
if (stdout.includes("You are logged in")) return "ready";
60+
} catch {}
61+
62+
// Fallback: check local config file (works offline / when Bun.spawn network fails)
63+
if (await this.checkAuthFromConfig()) return "ready";
64+
65+
return "not_authenticated";
3266
}
3367

3468
async isAvailable(): Promise<boolean> {

0 commit comments

Comments
 (0)