northbase 0.1.5 → 0.1.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/northbase.mjs +59 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "northbase",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Local-first CLI for reading and writing text files stored in Supabase",
5
5
  "type": "module",
6
6
  "bin": {
package/src/northbase.mjs CHANGED
@@ -81,12 +81,16 @@ async function doRefresh(supabase, stored) {
81
81
  refresh_token: stored.refresh_token,
82
82
  });
83
83
  if (error) {
84
- const revoked = error.message?.includes("invalid_grant") || error.status === 400;
85
- if (revoked) deleteSession();
86
- throw new Error(revoked
87
- ? "Session revoked. Run `northbase login`."
88
- : `Session refresh failed (${error.message}). Run \`northbase login\`.`
89
- );
84
+ const revoked = error.message?.includes("invalid_grant")
85
+ || error.error === "invalid_grant"
86
+ || error.code === "invalid_grant";
87
+ if (revoked) {
88
+ console.error("NORTHBASE session revoked deleting session.json");
89
+ deleteSession();
90
+ throw new Error("Session revoked. Run `northbase login`.");
91
+ }
92
+ // Transient error (network, rate limit, etc.) — do NOT delete session.json
93
+ throw new Error(`Session refresh failed (${error.message}) — session preserved, will retry next command.`);
90
94
  }
91
95
  const newSession = data.session;
92
96
  if (!newSession?.access_token || !newSession?.refresh_token) {
@@ -412,17 +416,59 @@ async function cmdSession() {
412
416
  console.log(`email=${stored.user?.email ?? "(unknown)"}`);
413
417
  }
414
418
 
419
+ async function cmdAuthDebug() {
420
+ const exists = fs.existsSync(SESSION_PATH);
421
+ console.log(`session_file_exists=${exists}`);
422
+ if (!exists) { console.log("status=not_logged_in"); return; }
423
+
424
+ let stored;
425
+ try {
426
+ stored = JSON.parse(fs.readFileSync(SESSION_PATH, "utf8"));
427
+ } catch (e) {
428
+ console.log(`session_file_parse_error=${e.message}`);
429
+ return;
430
+ }
431
+
432
+ const nowSec = Math.floor(Date.now() / 1000);
433
+ const expiresAt = stored.expires_at ?? 0;
434
+ const secsRemaining = expiresAt - nowSec;
435
+
436
+ console.log(`has_access_token=${!!stored.access_token}`);
437
+ console.log(`has_refresh_token=${!!stored.refresh_token}`);
438
+ console.log(`expires_at=${expiresAt}`);
439
+ console.log(`seconds_remaining=${secsRemaining}`);
440
+ console.log(`will_refresh_soon=${secsRemaining <= 60}`);
441
+ console.log(`email=${stored.user?.email ?? "(unknown)"}`);
442
+
443
+ let refreshAttempted = false, refreshSucceeded = false, userFetchSucceeded = false;
444
+ try {
445
+ const supabase = await getAuthenticatedClient();
446
+ const after = JSON.parse(fs.readFileSync(SESSION_PATH, "utf8"));
447
+ refreshAttempted = secsRemaining <= 60 || after.expires_at !== expiresAt;
448
+ refreshSucceeded = !!after.access_token;
449
+ const { data, error } = await supabase.auth.getUser();
450
+ userFetchSucceeded = !error && !!data?.user;
451
+ } catch (e) {
452
+ console.log(`auth_error=${e.message}`);
453
+ }
454
+
455
+ console.log(`refresh_attempted=${refreshAttempted}`);
456
+ console.log(`refresh_succeeded=${refreshSucceeded}`);
457
+ console.log(`user_fetch_succeeded=${userFetchSucceeded}`);
458
+ }
459
+
415
460
  // ── main ──────────────────────────────────────────────────────────────────────
416
461
 
417
462
  async function main() {
418
463
  const [cmd, ...args] = process.argv.slice(2);
419
464
 
420
- if (cmd === "login") { await cmdLogin(); return; }
421
- if (cmd === "logout") { await cmdLogout(); return; }
422
- if (cmd === "whoami") { await cmdWhoami(); return; }
423
- if (cmd === "session") { await cmdSession(); return; }
424
- if (cmd === "list") { await cmdList(args[0]); return; }
425
- if (cmd === "pull") { await cmdPull(args[0]); return; }
465
+ if (cmd === "login") { await cmdLogin(); return; }
466
+ if (cmd === "logout") { await cmdLogout(); return; }
467
+ if (cmd === "whoami") { await cmdWhoami(); return; }
468
+ if (cmd === "session") { await cmdSession(); return; }
469
+ if (cmd === "auth-debug") { await cmdAuthDebug(); return; }
470
+ if (cmd === "list") { await cmdList(args[0]); return; }
471
+ if (cmd === "pull") { await cmdPull(args[0]); return; }
426
472
 
427
473
  if (cmd === "get") {
428
474
  const rel = args[0];
@@ -448,6 +494,7 @@ async function main() {
448
494
  console.log(" northbase logout");
449
495
  console.log(" northbase whoami");
450
496
  console.log(" northbase session");
497
+ console.log(" northbase auth-debug");
451
498
  console.log(" northbase list [prefix]");
452
499
  console.log(" northbase pull [prefix]");
453
500
  console.log(" northbase get <path>");