mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-05-01 19:06:16 +00:00
This commit introduces the ability to fetch and store Supabase API keys and URL credentials when a project is selected. This enables the application to dynamically configure the Supabase connection environment variables, improving the integration with Supabase services. The changes include updates to the Supabase connection logic, new API endpoints, and modifications to the chat and prompt components to utilize the new credentials.
148 lines
4.1 KiB
TypeScript
148 lines
4.1 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { toast } from 'react-toastify';
|
|
import { useStore } from '@nanostores/react';
|
|
import { logStore } from '~/lib/stores/logs';
|
|
import {
|
|
supabaseConnection,
|
|
isConnecting,
|
|
isFetchingStats,
|
|
isFetchingApiKeys,
|
|
updateSupabaseConnection,
|
|
fetchProjectApiKeys,
|
|
} from '~/lib/stores/supabase';
|
|
|
|
export function useSupabaseConnection() {
|
|
const connection = useStore(supabaseConnection);
|
|
const connecting = useStore(isConnecting);
|
|
const fetchingStats = useStore(isFetchingStats);
|
|
const fetchingApiKeys = useStore(isFetchingApiKeys);
|
|
const [isProjectsExpanded, setIsProjectsExpanded] = useState(false);
|
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const savedConnection = localStorage.getItem('supabase_connection');
|
|
const savedCredentials = localStorage.getItem('supabaseCredentials');
|
|
|
|
if (savedConnection) {
|
|
const parsed = JSON.parse(savedConnection);
|
|
|
|
if (savedCredentials && !parsed.credentials) {
|
|
parsed.credentials = JSON.parse(savedCredentials);
|
|
}
|
|
|
|
updateSupabaseConnection(parsed);
|
|
|
|
if (parsed.token && parsed.selectedProjectId && !parsed.credentials) {
|
|
fetchProjectApiKeys(parsed.selectedProjectId, parsed.token).catch(console.error);
|
|
}
|
|
}
|
|
}, []);
|
|
|
|
const handleConnect = async () => {
|
|
isConnecting.set(true);
|
|
|
|
try {
|
|
const cleanToken = connection.token.trim();
|
|
|
|
const response = await fetch('/api/supabase', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
token: cleanToken,
|
|
}),
|
|
});
|
|
|
|
const data = (await response.json()) as any;
|
|
|
|
if (!response.ok) {
|
|
throw new Error(data.error || 'Failed to connect');
|
|
}
|
|
|
|
updateSupabaseConnection({
|
|
user: data.user,
|
|
token: connection.token,
|
|
stats: data.stats,
|
|
});
|
|
|
|
toast.success('Successfully connected to Supabase');
|
|
|
|
setIsProjectsExpanded(true);
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Connection error:', error);
|
|
logStore.logError('Failed to authenticate with Supabase', { error });
|
|
toast.error(error instanceof Error ? error.message : 'Failed to connect to Supabase');
|
|
updateSupabaseConnection({ user: null, token: '' });
|
|
|
|
return false;
|
|
} finally {
|
|
isConnecting.set(false);
|
|
}
|
|
};
|
|
|
|
const handleDisconnect = () => {
|
|
updateSupabaseConnection({ user: null, token: '' });
|
|
toast.success('Disconnected from Supabase');
|
|
setIsDropdownOpen(false);
|
|
};
|
|
|
|
const selectProject = async (projectId: string) => {
|
|
const currentState = supabaseConnection.get();
|
|
let projectData = undefined;
|
|
|
|
if (projectId && currentState.stats?.projects) {
|
|
projectData = currentState.stats.projects.find((project) => project.id === projectId);
|
|
}
|
|
|
|
updateSupabaseConnection({
|
|
selectedProjectId: projectId,
|
|
project: projectData,
|
|
});
|
|
|
|
if (projectId && currentState.token) {
|
|
try {
|
|
await fetchProjectApiKeys(projectId, currentState.token);
|
|
toast.success('Project selected successfully');
|
|
} catch (error) {
|
|
console.error('Failed to fetch API keys:', error);
|
|
toast.error('Selected project but failed to fetch API keys');
|
|
}
|
|
} else {
|
|
toast.success('Project selected successfully');
|
|
}
|
|
|
|
setIsDropdownOpen(false);
|
|
};
|
|
|
|
const handleCreateProject = async () => {
|
|
window.open('https://app.supabase.com/new/new-project', '_blank');
|
|
};
|
|
|
|
return {
|
|
connection,
|
|
connecting,
|
|
fetchingStats,
|
|
fetchingApiKeys,
|
|
isProjectsExpanded,
|
|
setIsProjectsExpanded,
|
|
isDropdownOpen,
|
|
setIsDropdownOpen,
|
|
handleConnect,
|
|
handleDisconnect,
|
|
selectProject,
|
|
handleCreateProject,
|
|
updateToken: (token: string) => updateSupabaseConnection({ ...connection, token }),
|
|
isConnected: !!(connection.user && connection.token),
|
|
fetchProjectApiKeys: (projectId: string) => {
|
|
if (connection.token) {
|
|
return fetchProjectApiKeys(projectId, connection.token);
|
|
}
|
|
|
|
return Promise.reject(new Error('No token available'));
|
|
},
|
|
};
|
|
}
|