feat: Configure Vite to inject Supabase env vars directly for Hugging Face compatibility
Browse files- frontend/src/services/supabaseClient.js +15 -56
- frontend/vite.config.js +81 -60
frontend/src/services/supabaseClient.js
CHANGED
|
@@ -1,36 +1,30 @@
|
|
| 1 |
import { createClient } from '@supabase/supabase-js';
|
| 2 |
|
| 3 |
-
//
|
| 4 |
-
//
|
| 5 |
-
const supabaseUrl =
|
| 6 |
-
const supabaseAnonKey =
|
| 7 |
-
|
| 8 |
-
//
|
| 9 |
-
if (!supabaseUrl) {
|
| 10 |
-
console.error('
|
| 11 |
}
|
| 12 |
|
| 13 |
-
if (!supabaseAnonKey) {
|
| 14 |
-
console.error('
|
| 15 |
}
|
| 16 |
|
| 17 |
// Create Supabase client instance
|
| 18 |
export const supabase = createClient(
|
| 19 |
-
supabaseUrl
|
| 20 |
-
supabaseAnonKey
|
| 21 |
{
|
| 22 |
-
// Optional: Add any additional configuration options here
|
| 23 |
auth: {
|
| 24 |
-
// Automatically refresh the session if it's close to expiring
|
| 25 |
autoRefreshToken: true,
|
| 26 |
-
// Persist the session in local storage
|
| 27 |
persistSession: true,
|
| 28 |
-
// Detect changes to the session (e.g., token refresh)
|
| 29 |
detectSessionInUrl: true
|
| 30 |
},
|
| 31 |
-
// Global fetch options
|
| 32 |
global: {
|
| 33 |
-
// Set a default timeout for requests (in milliseconds)
|
| 34 |
headers: {
|
| 35 |
'X-Client-Info': 'lin-app/1.0'
|
| 36 |
}
|
|
@@ -38,58 +32,23 @@ export const supabase = createClient(
|
|
| 38 |
}
|
| 39 |
);
|
| 40 |
|
| 41 |
-
// ---
|
| 42 |
-
|
| 43 |
|
| 44 |
// Listen for auth state changes
|
| 45 |
const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
|
| 46 |
console.log('Supabase Auth State Change Event:', event);
|
| 47 |
console.log('Supabase Auth State Change Session:', session ? `User: ${session.user?.id || 'N/A'}` : 'No session');
|
| 48 |
-
|
| 49 |
-
// Handle specific events
|
| 50 |
-
if (event === 'PASSWORD_RECOVERY') {
|
| 51 |
-
console.log('*** PASSWORD_RECOVERY event detected. A password reset link was used. ***');
|
| 52 |
-
// The session provided here should be the temporary recovery session.
|
| 53 |
-
// The app should now allow the user to set a new password.
|
| 54 |
-
} else if (event === 'SIGNED_IN') {
|
| 55 |
-
console.log('User signed in.');
|
| 56 |
-
} else if (event === 'SIGNED_OUT') {
|
| 57 |
-
console.log('User signed out.');
|
| 58 |
-
} else if (event === 'TOKEN_REFRESHED') {
|
| 59 |
-
console.log('Session token refreshed.');
|
| 60 |
-
} else if (event === 'USER_UPDATED') {
|
| 61 |
-
console.log('User data updated.');
|
| 62 |
-
}
|
| 63 |
});
|
| 64 |
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
// Initial session check on app load
|
| 68 |
supabase.auth.getSession()
|
| 69 |
.then(({ data: { session }, error }) => {
|
| 70 |
-
initialSessionCheckDone = true;
|
| 71 |
if (error) {
|
| 72 |
console.error("Error getting initial session:", error);
|
| 73 |
} else {
|
| 74 |
console.log("Initial session check result (on app load):", session ? `Session exists for user: ${session.user?.id || 'N/A'}` : "No active session found");
|
| 75 |
-
// If session is null here when coming from a reset link, it means processing failed or the token was already used/expired.
|
| 76 |
}
|
| 77 |
});
|
| 78 |
|
| 79 |
-
// Fallback check in case the initial check happens too early or misses something
|
| 80 |
-
setTimeout(() => {
|
| 81 |
-
if (!initialSessionCheckDone) {
|
| 82 |
-
console.warn("Initial session check might have been missed or delayed. Checking again...");
|
| 83 |
-
supabase.auth.getSession()
|
| 84 |
-
.then(({ data: { session }, error }) => {
|
| 85 |
-
initialSessionCheckDone = true; // Mark as done even on retry
|
| 86 |
-
if (error) {
|
| 87 |
-
console.error("Fallback - Error getting session:", error);
|
| 88 |
-
} else {
|
| 89 |
-
console.log("Fallback - Session check result:", session ? `Session exists for user: ${session.user?.id || 'N/A'}` : "No active session found (Fallback)");
|
| 90 |
-
}
|
| 91 |
-
});
|
| 92 |
-
}
|
| 93 |
-
}, 1000); // Check again after 1 second
|
| 94 |
-
|
| 95 |
export default supabase;
|
|
|
|
| 1 |
import { createClient } from '@supabase/supabase-js';
|
| 2 |
|
| 3 |
+
// Utilise les constantes définies par Vite au lieu de import.meta.env
|
| 4 |
+
// Ces constantes sont des chaînes littérales injectées lors du build
|
| 5 |
+
const supabaseUrl = __VITE_SUPABASE_URL__;
|
| 6 |
+
const supabaseAnonKey = __VITE_SUPABASE_ANON_KEY__;
|
| 7 |
+
|
| 8 |
+
// Validation de la configuration (toujours une bonne pratique)
|
| 9 |
+
if (!supabaseUrl || supabaseUrl === 'https://your-project.supabase.co') {
|
| 10 |
+
console.error('❌ VITE_SUPABASE_URL n\'est pas correctement définie. Veuillez vérifier vos variables d\'environnement ou la configuration de Vite.');
|
| 11 |
}
|
| 12 |
|
| 13 |
+
if (!supabaseAnonKey || supabaseAnonKey === 'your-anon-key') {
|
| 14 |
+
console.error('❌ VITE_SUPABASE_ANON_KEY n\'est pas correctement définie. Veuillez vérifier vos variables d\'environnement ou la configuration de Vite.');
|
| 15 |
}
|
| 16 |
|
| 17 |
// Create Supabase client instance
|
| 18 |
export const supabase = createClient(
|
| 19 |
+
supabaseUrl,
|
| 20 |
+
supabaseAnonKey,
|
| 21 |
{
|
|
|
|
| 22 |
auth: {
|
|
|
|
| 23 |
autoRefreshToken: true,
|
|
|
|
| 24 |
persistSession: true,
|
|
|
|
| 25 |
detectSessionInUrl: true
|
| 26 |
},
|
|
|
|
| 27 |
global: {
|
|
|
|
| 28 |
headers: {
|
| 29 |
'X-Client-Info': 'lin-app/1.0'
|
| 30 |
}
|
|
|
|
| 32 |
}
|
| 33 |
);
|
| 34 |
|
| 35 |
+
// --- Logging et vérification de la session initiale ---
|
| 36 |
+
console.log("Supabase client initialized with URL:", supabaseUrl);
|
| 37 |
|
| 38 |
// Listen for auth state changes
|
| 39 |
const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
|
| 40 |
console.log('Supabase Auth State Change Event:', event);
|
| 41 |
console.log('Supabase Auth State Change Session:', session ? `User: ${session.user?.id || 'N/A'}` : 'No session');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
});
|
| 43 |
|
| 44 |
+
// Initial session check
|
|
|
|
|
|
|
| 45 |
supabase.auth.getSession()
|
| 46 |
.then(({ data: { session }, error }) => {
|
|
|
|
| 47 |
if (error) {
|
| 48 |
console.error("Error getting initial session:", error);
|
| 49 |
} else {
|
| 50 |
console.log("Initial session check result (on app load):", session ? `Session exists for user: ${session.user?.id || 'N/A'}` : "No active session found");
|
|
|
|
| 51 |
}
|
| 52 |
});
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
export default supabase;
|
frontend/vite.config.js
CHANGED
|
@@ -1,70 +1,91 @@
|
|
| 1 |
-
import { defineConfig } from 'vite'
|
| 2 |
-
import react from '@vitejs/plugin-react'
|
| 3 |
-
import path from 'path'
|
| 4 |
|
| 5 |
// https://vitejs.dev/config/
|
| 6 |
-
export default defineConfig({
|
| 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 |
-
// Proxy for WebSocket connections (if needed for real-time features)
|
| 41 |
-
'/ws': {
|
| 42 |
-
target: 'http://localhost:5000',
|
| 43 |
-
ws: true,
|
| 44 |
-
changeOrigin: true,
|
| 45 |
-
secure: false,
|
| 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 |
-
})
|
|
|
|
| 1 |
+
import { defineConfig, loadEnv } from 'vite';
|
| 2 |
+
import react from '@vitejs/plugin-react';
|
| 3 |
+
import path from 'path';
|
| 4 |
|
| 5 |
// https://vitejs.dev/config/
|
| 6 |
+
export default defineConfig(({ mode }) => {
|
| 7 |
+
// Charge les variables d'environnement pour le mode actuel ('development', 'production', etc.)
|
| 8 |
+
// Cela inclut les variables définies dans l'environnement d'exécution (comme sur Hugging Face)
|
| 9 |
+
const env = loadEnv(mode, process.cwd(), '');
|
| 10 |
+
|
| 11 |
+
// --- Vérification des variables critiques pour le frontend ---
|
| 12 |
+
if (!env.VITE_SUPABASE_URL) {
|
| 13 |
+
console.warn('⚠️ Variable d\'environnement VITE_SUPABASE_URL non définie. Utilisation d\'une valeur par défaut pour le développement.');
|
| 14 |
+
}
|
| 15 |
+
if (!env.VITE_SUPABASE_ANON_KEY) {
|
| 16 |
+
console.warn('⚠️ Variable d\'environnement VITE_SUPABASE_ANON_KEY non définie. Utilisation d\'une valeur par défaut pour le développement.');
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
// --- Configuration de base ---
|
| 20 |
+
const config = {
|
| 21 |
+
plugins: [react({
|
| 22 |
+
jsx: 'transform',
|
| 23 |
+
jsxFactory: 'React.createElement',
|
| 24 |
+
jsxFragment: 'React.Fragment',
|
| 25 |
+
})],
|
| 26 |
+
resolve: {
|
| 27 |
+
alias: {
|
| 28 |
+
'@': path.resolve(__dirname, './src'),
|
| 29 |
+
},
|
| 30 |
},
|
| 31 |
+
server: {
|
| 32 |
+
port: 3000,
|
| 33 |
+
host: 'localhost', // Explicitly bind to localhost
|
| 34 |
+
proxy: {
|
| 35 |
+
'/api': {
|
| 36 |
+
target: 'http://localhost:5000',
|
| 37 |
+
changeOrigin: true,
|
| 38 |
+
secure: false,
|
| 39 |
+
// Configure proxy to handle WebSocket connections if needed
|
| 40 |
+
ws: true,
|
| 41 |
+
// Configure proxy to handle CORS headers
|
| 42 |
+
configure: (proxy, _options) => {
|
| 43 |
+
proxy.on('error', (err, _req, _res) => {
|
| 44 |
+
console.log('proxy error', err);
|
| 45 |
+
});
|
| 46 |
+
proxy.on('proxyReq', (proxyReq, req, _res) => {
|
| 47 |
+
console.log('Sending Request to the Target:', req.method, req.url);
|
| 48 |
+
});
|
| 49 |
+
proxy.on('proxyRes', (proxyRes, req, _res) => {
|
| 50 |
+
console.log('Received Response from the Target:', proxyRes.statusCode, req.url);
|
| 51 |
+
});
|
| 52 |
+
},
|
| 53 |
+
},
|
| 54 |
+
// Proxy for WebSocket connections (if needed for real-time features)
|
| 55 |
+
'/ws': {
|
| 56 |
+
target: 'http://localhost:5000',
|
| 57 |
+
ws: true,
|
| 58 |
+
changeOrigin: true,
|
| 59 |
+
secure: false,
|
| 60 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
},
|
| 62 |
},
|
| 63 |
+
build: {
|
| 64 |
+
outDir: 'dist',
|
| 65 |
+
sourcemap: true,
|
| 66 |
+
// Configure build for production
|
| 67 |
+
rollupOptions: {
|
| 68 |
+
output: {
|
| 69 |
+
manualChunks: {
|
| 70 |
+
// Create separate chunks for vendor libraries
|
| 71 |
+
vendor: ['react', 'react-dom', 'react-router-dom', 'react-redux'],
|
| 72 |
+
},
|
| 73 |
},
|
| 74 |
},
|
| 75 |
+
// Ensure JSX is processed during build
|
| 76 |
+
commonjsOptions: {
|
| 77 |
+
include: [/node_modules/],
|
| 78 |
+
},
|
| 79 |
},
|
| 80 |
+
// --- Injection directe des variables dans le code bundle ---
|
| 81 |
+
define: {
|
| 82 |
+
// Ces variables seront remplacées par leurs valeurs littérales dans le bundle JS
|
| 83 |
+
__VITE_SUPABASE_URL__: JSON.stringify(env.VITE_SUPABASE_URL || 'https://your-project.supabase.co'),
|
| 84 |
+
__VITE_SUPABASE_ANON_KEY__: JSON.stringify(env.VITE_SUPABASE_ANON_KEY || 'your-anon-key'),
|
| 85 |
+
// Conserver l'ancienne définition si elle est utilisée ailleurs
|
| 86 |
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
|
| 87 |
},
|
| 88 |
+
};
|
| 89 |
+
|
| 90 |
+
return config;
|
| 91 |
+
});
|
|
|
|
|
|