#!/usr/bin/env node // Bootstrap Directus schema using the directus CLI (schema apply) // This approach bypasses the REST API permission issues entirely import fs from 'fs'; import path from 'path'; import { execSync } from 'child_process'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const __filename = fileURLToPath(import.meta.url); const DIRECTUS_URL = process.env.DIRECTUS_URL || 'http://directus:8055'; const DIRECTUS_TOKEN = process.env.DIRECTUS_TOKEN || ''; const DIRECTUS_ADMIN_EMAIL = process.env.DIRECTUS_ADMIN_EMAIL || 'admin@example.com'; const DIRECTUS_ADMIN_PASSWORD = process.env.DIRECTUS_ADMIN_PASSWORD || 'change-me'; const SNAPSHOT_PATH = path.join(__dirname, '..', 'directus', 'schema-snapshot.json'); console.log('========================================'); console.log('Directus Bootstrap (CLI-based)'); console.log('========================================'); console.log(''); // Check if snapshot exists if (!fs.existsSync(SNAPSHOT_PATH)) { console.error(`❌ ERROR: Schema snapshot not found at ${SNAPSHOT_PATH}`); process.exit(1); } console.log(`✓ Found schema snapshot at ${SNAPSHOT_PATH}`); console.log(''); // Determine authentication method let hasToken = Boolean(DIRECTUS_TOKEN); if (hasToken) { console.log('✓ DIRECTUS_TOKEN is set; will use bearer token'); } else { console.log('⚠️ DIRECTUS_TOKEN not set; will attempt email/password login'); } console.log(''); // Wait for Directus to be fully ready console.log('⏳ Waiting for Directus to be ready...'); const maxRetries = 30; let retry = 0; async function checkHealth() { while (retry < maxRetries) { try { const response = await fetch(`${DIRECTUS_URL}/server/health`, { timeout: 5000, }); if (response.ok) { console.log('✓ Directus is ready'); return true; } } catch (e) { // Continue retrying } retry++; if (retry % 5 === 0) { process.stdout.write('.'); } await new Promise(r => setTimeout(r, 1000)); } if (retry >= maxRetries) { console.error(`\n❌ ERROR: Directus did not become ready after ${maxRetries} seconds`); process.exit(1); } return false; } async function applySchema() { await checkHealth(); console.log(''); console.log('📋 Applying schema snapshot...'); console.log(' This will create all collections, fields, and relations.'); console.log(''); // Set environment variables for the directus CLI process.env.DIRECTUS_URL = DIRECTUS_URL; process.env.DIRECTUS_TOKEN = DIRECTUS_TOKEN; process.env.DIRECTUS_ADMIN_EMAIL = DIRECTUS_ADMIN_EMAIL; process.env.DIRECTUS_ADMIN_PASSWORD = DIRECTUS_ADMIN_PASSWORD; try { // Execute the schema apply command using npx // The directus CLI is available globally in the directus container const command = `npx directus schema apply "${SNAPSHOT_PATH}" --yes`; console.log(`Running: ${command}`); console.log(''); // Execute synchronously and capture output const output = execSync(command, { stdio: 'inherit', env: process.env, }); console.log(''); console.log('✅ SUCCESS: Schema snapshot applied successfully!'); console.log(''); console.log('Created collections:'); console.log(' - tags'); console.log(' - news'); console.log(' - events'); console.log(' - notices'); console.log(' - fuel_prices'); console.log(' - documents'); console.log(' - contacts'); console.log(' - news_tags (M2M junction)'); console.log(' - events_tags (M2M junction)'); console.log(''); console.log('All fields and relations have been initialized.'); process.exit(0); } catch (error) { console.error(''); console.error('❌ ERROR: Schema apply failed'); console.error(error.message); process.exit(1); } } // Run the bootstrap applySchema().catch((error) => { console.error('❌ Unexpected error:', error); process.exit(1); });