All files / src/auth supabaseClient.ts

35.8% Statements 29/81
11.11% Branches 1/9
20% Functions 1/5
35.8% Lines 29/81

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 811x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x   2x 2x 2x 2x 2x 2x   2x 2x 2x                                                                                           1x 1x 1x 1x 1x          
import { createClient, SupabaseClient } from '@supabase/supabase-js';
import * as vscode from 'vscode';
import { globalContext } from '../extension';
 
let client: SupabaseClient | null = null;
 
/**
 * Returns a singleton Supabase client with VS Code globalState storage.
 */
export function getSupabase(): SupabaseClient {
  if (client) return client;
 
  const url = (
    vscode.workspace.getConfiguration().get<string>('collabAgent.supabase.url') ||
    process.env.SUPABASE_URL ||
    ''
  ).trim();
 
  const anonKey = (
    vscode.workspace.getConfiguration().get<string>('collabAgent.supabase.anonKey') ||
    process.env.SUPABASE_ANON_KEY ||
    process.env.SUPABASE_KEY ||
    ''
  ).trim();
 
  if (!url || !anonKey) {
    throw new Error(
      'Supabase not configured. Set collabAgent.supabase.url & collabAgent.supabase.anonKey in Settings or export SUPABASE_URL and SUPABASE_ANON_KEY/SUPABASE_KEY environment variables.'
    );
  }

  /**
   * Supabase requires synchronous storage functions.
   * We'll mirror VS Code globalState into a simple in-memory cache that persists to globalState.
   */
  const memoryStorage: Record<string, string> = {};

  const storage = {
    getItem(key: string) {
      if (memoryStorage[key]) return memoryStorage[key];
      const val = globalContext?.globalState.get<string>(key) ?? null;
      if (val) memoryStorage[key] = val;
      return val;
    },
    setItem(key: string, value: string) {
      memoryStorage[key] = value;
      globalContext?.globalState.update(key, value);
    },
    removeItem(key: string) {
      delete memoryStorage[key];
      globalContext?.globalState.update(key, undefined);
    },
  };

  client = createClient(url, anonKey, {
    auth: {
      storage,
      persistSession: true,
      autoRefreshToken: true,
      detectSessionInUrl: false,
    },
  });

  console.log('[Supabase] Client created, checking for existing session...');
  client.auth.getSession().then(({ data, error }) => {
    if (error) console.error('[Supabase] Session fetch error:', error);
    console.log('[Supabase] Existing session found:', !!data.session);
  });

  return client;
}
 
/**
 * Retrieves the current authenticated user.
 */
export async function getCurrentUser() {
  const supabase = getSupabase();
  const { data, error } = await supabase.auth.getUser();
  if (error) console.error('[getCurrentUser] error:', error.message);
  return data.user;
}