directus
This commit is contained in:
111
lib/directus.ts
Normal file
111
lib/directus.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
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
|
||||
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;
|
||||
Reference in New Issue
Block a user