// Import kampaní a šablón cenoviek zo supabase/data/ (vytvorené cez npm run db:export) do nového Supabase. // - nahrá obrázky zo supabase/data/files/ do úložiska newsletter-assets // - odkazy na pôvodné úložisko v dátach prepíše na úložisko nového projektu // - záznamy vloží s pôvodnými ID; existujúce záznamy s rovnakým ID prepíše (dá sa spustiť opakovane) // Predpoklad: spustený supabase/schema.sql. Spustenie: npm run db:import // Skúška bez zápisu: npm run db:import -- --dry-run import { createClient } from '@supabase/supabase-js'; import { readFile, readdir } from 'node:fs/promises'; import path from 'node:path'; const BUCKET = 'newsletter-assets'; const TABLES = ['templates', 'badges']; const DATA_DIR = path.join(process.cwd(), 'supabase', 'data'); const FILES_DIR = path.join(DATA_DIR, 'files'); const CONTENT_TYPES = { '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml', '.webp': 'image/webp' }; const url = (process.env.NEXT_PUBLIC_SUPABASE_URL || '').replace(/\/$/, ''); const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY; if (!url || !serviceKey) { console.error('Chýba NEXT_PUBLIC_SUPABASE_URL alebo SUPABASE_SERVICE_ROLE_KEY v .env.local'); process.exit(1); } const dryRun = process.argv.includes('--dry-run'); const supabase = createClient(url, serviceKey); if (dryRun) console.log('Skúšobný režim (--dry-run): nič sa nezapíše.'); const meta = JSON.parse(await readFile(path.join(DATA_DIR, 'meta.json'), 'utf8')); const newStorageBase = `${url}/storage/v1/object/public/${BUCKET}/`; // 1. Obrázky async function listFiles(dir, prefix = '') { const entries = await readdir(dir, { withFileTypes: true }).catch(() => []); const out = []; for (const e of entries) { const rel = prefix ? `${prefix}/${e.name}` : e.name; if (e.isDirectory()) out.push(...(await listFiles(path.join(dir, e.name), rel))); else out.push(rel); } return out; } const files = await listFiles(FILES_DIR); let failed = 0; for (const rel of files) { if (dryRun) continue; const { error } = await supabase.storage.from(BUCKET).upload(rel, await readFile(path.join(FILES_DIR, rel)), { contentType: CONTENT_TYPES[path.extname(rel).toLowerCase()] || 'application/octet-stream', upsert: true }); if (error) { failed++; console.error(`✗ súbor ${rel}: ${error.message}`); } } console.log(`${dryRun ? '•' : '✓'} obrázky: ${files.length - failed}/${files.length} ${dryRun ? 'na nahratie' : 'nahratých'}`); // 2. Dáta (s prepisom odkazov na nové úložisko) for (const table of TABLES) { const raw = await readFile(path.join(DATA_DIR, `${table}.json`), 'utf8'); const rewritten = raw.split(meta.sourceStorageBase).length - 1; const rows = JSON.parse(raw.split(meta.sourceStorageBase).join(newStorageBase)); if (dryRun) { console.log(`• ${table}: ${rows.length} záznamov, ${meta.sourceStorageBase === newStorageBase ? 0 : rewritten} prepísaných odkazov na úložisko`); continue; } for (let i = 0; i < rows.length; i += 50) { const { error } = await supabase.from(table).upsert(rows.slice(i, i + 50), { onConflict: 'id' }); if (error) { console.error(`✗ ${table}: ${error.message}`); process.exit(1); } } console.log(`✓ ${table}: ${rows.length} záznamov`); } if (meta.sourceStorageBase !== newStorageBase) { console.log(`\nOdkazy ${meta.sourceStorageBase} → ${newStorageBase}`); } console.log('Hotovo.'); if (failed) process.exit(1);