import { createDirectus, rest, authentication, readItems, readCollections } from '@directus/sdk'; import { config } from './config'; const { url, adminEmail, password, token, proxyPath, internalUrl } = config.directus; // Use internal URL if on server to bypass Gatekeeper/Auth const effectiveUrl = typeof window === 'undefined' && internalUrl ? internalUrl : url; const client = createDirectus(effectiveUrl).with(rest()).with(authentication()); export async function ensureAuthenticated() { if (token) { client.setToken(token); return; } if (adminEmail && password) { try { await client.login(adminEmail, password); } catch (e) { console.error('Failed to authenticate with Directus:', e); } } } /** * Maps the new translation-based schema back to the application's Product interface */ function mapDirectusProduct(item: any, locale: string): any { const langCode = locale === 'en' ? 'en-US' : 'de-DE'; const translation = item.translations?.find((t: any) => t.languages_code === langCode) || item.translations?.[0] || {}; return { id: item.id, sku: item.sku, title: translation.name || '', description: translation.description || '', content: translation.content || '', technicalData: { technicalItems: translation.technical_items || [], voltageTables: translation.voltage_tables || [], }, locale: locale, // Use proxy URL for assets to avoid CORS and handle internal/external issues data_sheet_url: item.data_sheet ? `${proxyPath}/assets/${item.data_sheet}` : null, categories: (item.categories_link || []) .map((c: any) => c.categories_id?.translations?.[0]?.name) .filter(Boolean), }; } export async function getProducts(locale: string = 'de') { await ensureAuthenticated(); try { const items = await client.request( readItems('products', { fields: ['*', 'translations.*', 'categories_link.categories_id.translations.name'], }), ); return items.map((item) => mapDirectusProduct(item, locale)); } catch (error) { console.error('Error fetching products:', error); return []; } } export async function getProductBySlug(slug: string, locale: string = 'de') { await ensureAuthenticated(); const langCode = locale === 'en' ? 'en-US' : 'de-DE'; try { const items = await client.request( readItems('products', { filter: { translations: { slug: { _eq: slug }, languages_code: { _eq: langCode }, }, }, fields: ['*', 'translations.*', 'categories_link.categories_id.translations.name'], limit: 1, }), ); if (!items || items.length === 0) return null; return mapDirectusProduct(items[0], locale); } catch (error) { console.error(`Error fetching product ${slug}:`, error); return null; } } export async function checkHealth() { try { await ensureAuthenticated(); // 1. Basic connectivity check await client.request(readCollections()); // 2. Schema check (does the products table exist?) try { await client.request(readItems('products', { limit: 1 })); } catch (e: any) { if (e.message?.includes('does not exist') || e.code === 'INVALID_PAYLOAD') { return { status: 'error', message: 'The "products" collection is missing. Please sync your data.', code: 'SCHEMA_MISSING', }; } throw e; } return { status: 'ok', message: 'Directus is reachable and responding.' }; } catch (error: any) { console.error('Directus health check failed:', error); return { status: 'error', message: error.message || 'Unknown error', code: error.code || 'UNKNOWN', }; } } export default client;