Files
portfolio/scripts/setup-tech-stack-directus.js
denshooter e431ff50fc 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.
2026-01-23 02:53:31 +01:00

152 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* Setup tech stack items in Directus
* Creates tech_stack_items collection and populates it with data
*/
const https = require('https');
const DIRECTUS_URL = 'https://cms.dk0.dev';
const DIRECTUS_TOKEN = process.env.DIRECTUS_STATIC_TOKEN || '';
if (!DIRECTUS_TOKEN) {
console.error('❌ DIRECTUS_STATIC_TOKEN not set');
process.exit(1);
}
// Tech stack items to create
const techStackItems = [
// Frontend & Mobile (category 1)
{ category: '1', name: 'Next.js', sort: 1 },
{ category: '1', name: 'Tailwind CSS', sort: 2 },
{ category: '1', name: 'Flutter', sort: 3 },
// Backend & DevOps (category 2)
{ category: '2', name: 'Docker Swarm', sort: 1 },
{ category: '2', name: 'Traefik', sort: 2 },
{ category: '2', name: 'Nginx Proxy Manager', sort: 3 },
{ category: '2', name: 'Redis', sort: 4 },
// Tools & Automation (category 3)
{ category: '3', name: 'Git', sort: 1 },
{ category: '3', name: 'CI/CD', sort: 2 },
{ category: '3', name: 'n8n', sort: 3 },
{ category: '3', name: 'Self-hosted Services', sort: 4 },
// Security & Admin (category 4)
{ category: '4', name: 'CrowdSec', sort: 1 },
{ category: '4', name: 'Suricata', sort: 2 },
{ category: '4', name: 'Mailcow', sort: 3 },
];
async function makeRequest(method, endpoint, body = null) {
return new Promise((resolve, reject) => {
const url = new URL(endpoint, DIRECTUS_URL);
const options = {
hostname: url.hostname,
port: 443,
path: url.pathname + url.search,
method: method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${DIRECTUS_TOKEN}`,
},
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
try {
const parsed = JSON.parse(data);
if (res.statusCode >= 400) {
reject(new Error(`HTTP ${res.statusCode}: ${data}`));
} else {
resolve(parsed);
}
} catch (e) {
resolve(data);
}
});
});
req.on('error', reject);
if (body) req.write(JSON.stringify(body));
req.end();
});
}
async function checkCollectionExists() {
try {
const response = await makeRequest('GET', '/api/items/tech_stack_items?limit=1');
if (response.data !== undefined) {
console.log('✅ Collection tech_stack_items already exists');
return true;
}
} catch (e) {
if (e.message.includes('does not exist') || e.message.includes('ROUTE_NOT_FOUND')) {
console.log(' Collection tech_stack_items does not exist yet');
return false;
}
throw e;
}
return false;
}
async function addTechStackItems() {
console.log(`📝 Adding ${techStackItems.length} tech stack items...`);
let created = 0;
for (const item of techStackItems) {
try {
const response = await makeRequest('POST', '/api/items/tech_stack_items', {
category: item.category,
name: item.name,
sort: item.sort,
status: 'published'
});
if (response.data) {
created++;
console.log(` ✅ Created: ${item.name} (category ${item.category})`);
}
} catch (error) {
console.error(` ❌ Failed to create "${item.name}":`, error.message);
}
}
console.log(`\n✅ Successfully created ${created}/${techStackItems.length} items`);
return created === techStackItems.length;
}
async function main() {
try {
console.log('🚀 Setting up Tech Stack in Directus...\n');
const exists = await checkCollectionExists();
if (exists) {
// Count existing items
const response = await makeRequest('GET', '/api/items/tech_stack_items?limit=1000');
const count = response.data?.length || 0;
if (count > 0) {
console.log(`✅ Tech stack already populated with ${count} items`);
return;
}
}
// Add items
await addTechStackItems();
console.log('\n✅ Tech stack setup complete!');
} catch (error) {
console.error('❌ Error setting up tech stack:', error.message);
process.exit(1);
}
}
main();