#!/usr/bin/env node /** * Setup Book Reviews Collection in Directus */ 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); } async function api(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); try { const response = await fetch(url, options); const data = await response.json(); if (!response.ok) { if (data.errors?.[0]?.extensions?.code === 'RECORD_NOT_UNIQUE' || data.errors?.[0]?.message?.includes('already exists')) { return { alreadyExists: true }; } return { error: true, message: data.errors?.[0]?.message }; } return data; } catch (error) { return { error: true, message: error.message }; } } async function setup() { console.log('šŸš€ Starting Directus Book Reviews Setup...'); const coll = await api('collections', 'POST', { collection: 'book_reviews', meta: { icon: 'menu_book', display_template: '{{book_title}}' } }); console.log(coll.alreadyExists ? ' āš ļø Collection exists.' : ' āœ… Collection created.'); const fields = [ { field: 'status', type: 'string', meta: { interface: 'select-dropdown' } }, { field: 'book_title', type: 'string', meta: { interface: 'input' } }, { field: 'book_author', type: 'string', meta: { interface: 'input' } }, { field: 'book_image', type: 'string', meta: { interface: 'input' } }, { field: 'rating', type: 'integer', meta: { interface: 'slider' } }, { field: 'hardcover_id', type: 'string', meta: { interface: 'input' } }, { field: 'finished_at', type: 'date', meta: { interface: 'datetime' } } ]; for (const f of fields) { await api('fields/book_reviews', 'POST', f); } console.log(' āœ… Fields created.'); await api('collections', 'POST', { collection: 'book_reviews_translations', meta: { hidden: true } }); await api('fields/book_reviews_translations', 'POST', { field: 'id', type: 'integer', schema: { is_primary_key: true, has_auto_increment: true } }); await api('fields/book_reviews_translations', 'POST', { field: 'book_reviews_id', type: 'integer' }); await api('fields/book_reviews_translations', 'POST', { field: 'languages_code', type: 'string' }); await api('fields/book_reviews_translations', 'POST', { field: 'review', type: 'text', meta: { interface: 'input-multiline' } }); await api('fields/book_reviews', 'POST', { field: 'translations', type: 'alias', meta: { interface: 'translations', special: ['translations'] } }); await api('relations', 'POST', { collection: 'book_reviews_translations', field: 'book_reviews_id', related_collection: 'book_reviews', meta: { one_field: 'translations' } }); console.log('\n✨ Setup Complete!'); } setup().catch(console.error);