1+ import { readFile } from "fs/promises" ;
2+ import { join } from "path" ;
3+ import { homedir } from "os" ;
14import type { SyncTarget , SyncResult , TargetStatus } from "./types" ;
25
36export 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