feat: Add Directus setup scripts for collections, fields, and relations
- 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.
This commit is contained in:
123
scripts/migrate-content-pages-to-directus.js
Normal file
123
scripts/migrate-content-pages-to-directus.js
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/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();
|
||||
Reference in New Issue
Block a user