- Created setup-directus-collections.js to automate the creation of tech stack collections, fields, and relations in Directus. - Created setup-directus-hobbies.js for setting up hobbies collection with translations. - Created setup-directus-projects.js for establishing projects collection with comprehensive fields and translations. - Added setup-tech-stack-directus.js to populate tech_stack_items with predefined data.
124 lines
3.3 KiB
JavaScript
124 lines
3.3 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* Migrate Content Pages from PostgreSQL (Prisma) to Directus
|
||
*
|
||
* - Copies `content_pages` + translations from Postgres into Directus
|
||
* - Creates or updates items per (slug, locale)
|
||
*
|
||
* Usage:
|
||
* DATABASE_URL=postgresql://... DIRECTUS_STATIC_TOKEN=... DIRECTUS_URL=... \
|
||
* node scripts/migrate-content-pages-to-directus.js
|
||
*/
|
||
|
||
const fetch = require('node-fetch');
|
||
const { PrismaClient } = require('@prisma/client');
|
||
require('dotenv').config();
|
||
|
||
const DIRECTUS_URL = process.env.DIRECTUS_URL || 'https://cms.dk0.dev';
|
||
const DIRECTUS_TOKEN = process.env.DIRECTUS_STATIC_TOKEN;
|
||
|
||
if (!DIRECTUS_TOKEN) {
|
||
console.error('❌ Error: DIRECTUS_STATIC_TOKEN not found in env');
|
||
process.exit(1);
|
||
}
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
const localeMap = {
|
||
en: 'en-US',
|
||
de: 'de-DE',
|
||
};
|
||
|
||
function toDirectusLocale(locale) {
|
||
return localeMap[locale] || locale;
|
||
}
|
||
|
||
async function directusRequest(endpoint, method = 'GET', body = null) {
|
||
const url = `${DIRECTUS_URL}/${endpoint}`;
|
||
const options = {
|
||
method,
|
||
headers: {
|
||
Authorization: `Bearer ${DIRECTUS_TOKEN}`,
|
||
'Content-Type': 'application/json',
|
||
},
|
||
};
|
||
|
||
if (body) {
|
||
options.body = JSON.stringify(body);
|
||
}
|
||
|
||
const res = await fetch(url, options);
|
||
if (!res.ok) {
|
||
const text = await res.text();
|
||
throw new Error(`HTTP ${res.status} on ${endpoint}: ${text}`);
|
||
}
|
||
return res.json();
|
||
}
|
||
|
||
async function upsertContentIntoDirectus({ slug, locale, status, title, content }) {
|
||
const directusLocale = toDirectusLocale(locale);
|
||
|
||
// allow locale-specific slug variants: base for en, base-locale for others
|
||
const slugVariant = directusLocale === 'en-US' ? slug : `${slug}-${directusLocale.toLowerCase()}`;
|
||
|
||
const payload = {
|
||
slug: slugVariant,
|
||
locale: directusLocale,
|
||
status: status?.toLowerCase?.() === 'published' ? 'published' : status || 'draft',
|
||
title: title || slug,
|
||
content: content || null,
|
||
};
|
||
|
||
try {
|
||
const { data } = await directusRequest('items/content_pages', 'POST', payload);
|
||
console.log(` ➕ Created ${slugVariant} (${directusLocale}) [id=${data?.id}]`);
|
||
return data?.id;
|
||
} catch (error) {
|
||
const msg = error?.message || '';
|
||
if (msg.includes('already exists') || msg.includes('duplicate key') || msg.includes('UNIQUE')) {
|
||
console.log(` ⚠️ Skipping ${slugVariant} (${directusLocale}) – already exists`);
|
||
return null;
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
async function migrateContentPages() {
|
||
console.log('\n📦 Migrating Content Pages from PostgreSQL to Directus...');
|
||
|
||
const pages = await prisma.contentPage.findMany({
|
||
include: { translations: true },
|
||
});
|
||
|
||
console.log(`Found ${pages.length} pages in PostgreSQL`);
|
||
|
||
for (const page of pages) {
|
||
const status = page.status || 'PUBLISHED';
|
||
for (const tr of page.translations) {
|
||
await upsertContentIntoDirectus({
|
||
slug: page.key,
|
||
locale: tr.locale,
|
||
status,
|
||
title: tr.title,
|
||
content: tr.content,
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log('✅ Content page migration finished.');
|
||
}
|
||
|
||
async function main() {
|
||
try {
|
||
await prisma.$connect();
|
||
await migrateContentPages();
|
||
} catch (error) {
|
||
console.error('❌ Migration failed:', error.message);
|
||
process.exit(1);
|
||
} finally {
|
||
await prisma.$disconnect();
|
||
}
|
||
}
|
||
|
||
main();
|