112 lines
3.4 KiB
TypeScript
112 lines
3.4 KiB
TypeScript
import { createDirectus, rest, staticToken, authentication, readItems, readItem } from '@directus/sdk';
|
|
|
|
const DIRECTUS_URL = process.env.DIRECTUS_URL || 'http://localhost:8055';
|
|
// We use Admin credentials for server-side operations if no token is provided
|
|
// This approach allows "auto-connect" without manual token generation
|
|
const DIRECTUS_EMAIL = process.env.DIRECTUS_ADMIN_EMAIL;
|
|
const DIRECTUS_PASSWORD = process.env.DIRECTUS_ADMIN_PASSWORD;
|
|
|
|
// Use a static token if provided (preferred for prod), otherwise fall back to admin auth
|
|
const DIRECTUS_TOKEN = process.env.DIRECTUS_API_TOKEN;
|
|
|
|
// Initialize the client
|
|
const client = createDirectus(DIRECTUS_URL)
|
|
.with(rest())
|
|
.with(authentication());
|
|
|
|
// Helper to authenticate if needed
|
|
export async function ensureAuthenticated() {
|
|
if (DIRECTUS_TOKEN) {
|
|
client.setToken(DIRECTUS_TOKEN);
|
|
return;
|
|
}
|
|
|
|
if (DIRECTUS_EMAIL && DIRECTUS_PASSWORD) {
|
|
// Check if we already have a valid token (optional optimization, but simple login is robust)
|
|
try {
|
|
await client.login(DIRECTUS_EMAIL, DIRECTUS_PASSWORD);
|
|
} catch (e) {
|
|
console.error("Failed to authenticate with Directus:", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
export interface Product {
|
|
id: string;
|
|
title: string;
|
|
sku: string;
|
|
description: string;
|
|
application: string;
|
|
content: string; // rich text
|
|
technical_data: any; // json
|
|
locale: string;
|
|
images?: {
|
|
directus_files_id: string;
|
|
}[];
|
|
}
|
|
|
|
// Maps Directus response to match our internal Product interface (mimicking Strapi for now)
|
|
function mapDirectusProduct(item: any): any {
|
|
return {
|
|
id: item.id,
|
|
title: item.title,
|
|
sku: item.sku,
|
|
description: item.description,
|
|
application: item.application,
|
|
content: item.content,
|
|
technicalData: item.technical_data,
|
|
locale: item.locale || 'de', // default
|
|
// Map images structure if needed
|
|
images: item.images ? {
|
|
data: item.images.map((img: any) => ({
|
|
attributes: {
|
|
url: `${DIRECTUS_URL}/assets/${img.directus_files_id}`,
|
|
alternativeText: img.caption || ''
|
|
}
|
|
}))
|
|
} : undefined
|
|
};
|
|
}
|
|
|
|
export async function getProducts(locale: string = 'de') {
|
|
await ensureAuthenticated();
|
|
try {
|
|
const items = await client.request(readItems('products', {
|
|
filter: {
|
|
_and: [
|
|
{ locale: { _eq: locale } }
|
|
]
|
|
},
|
|
fields: ['*', 'images.directus_files_id']
|
|
}));
|
|
|
|
return items.map(mapDirectusProduct);
|
|
} catch (error) {
|
|
console.error('Error fetching products from Directus:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export async function getProductBySku(sku: string, locale: string = 'de') {
|
|
await ensureAuthenticated();
|
|
try {
|
|
const items = await client.request(readItems('products', {
|
|
filter: {
|
|
_and: [
|
|
{ sku: { _eq: sku } },
|
|
{ locale: { _eq: locale } }
|
|
]
|
|
},
|
|
fields: ['*', 'images.directus_files_id']
|
|
}));
|
|
|
|
if (!items || items.length === 0) return null;
|
|
return mapDirectusProduct(items[0]);
|
|
} catch (error) {
|
|
console.error(`Error fetching product ${sku} from Directus:`, error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export default client;
|