import fs from 'fs/promises'; import path from 'path'; const DATA_FILE = path.join(process.cwd(), 'data', 'prompts.json'); const HABU_FILE = path.join(process.cwd(), 'data', 'habu_prompts.json'); async function mergePrompts() { console.log("Reading files..."); let existingCache = { prompts: [], last_updated: null, categories: {}, total_count: 0, sources: [] }; try { const data = await fs.readFile(DATA_FILE, 'utf-8'); existingCache = JSON.parse(data); } catch (e) { console.log("No existing prompts found or error reading."); } let habuRaw = []; try { const habuData = await fs.readFile(HABU_FILE, 'utf-8'); habuRaw = JSON.parse(habuData); } catch (e) { console.error("Error reading habu_prompts.json", e); return; } console.log(`Found ${existingCache.prompts.length} existing prompts and ${habuRaw.length} Habu prompts.`); // Map Habu to Prompt type const habuPrompts = habuRaw.map(p => ({ id: 0, title: p.name || 'Untitled Habu Prompt', prompt: p.prompt, category: 'Habu', category_type: 'style', description: p.prompt ? (p.prompt.substring(0, 150) + (p.prompt.length > 150 ? '...' : '')) : '', images: p.imageUrl ? [p.imageUrl] : [], author: 'Habu', source: 'habu', source_url: `https://taoanhez.com/#/prompt-library/${p.id}`, createdAt: p.createdAt ? new Date(p.createdAt).getTime() : Date.now(), useCount: 0 })); // Merge Logic // Preserving existing logic: dedupe by source_url const existingMap = new Map(); const finalPrompts = []; let addedCount = 0; const now = Date.now(); existingCache.prompts.forEach(p => { if (p.source_url) { existingMap.set(p.source_url, p); } else { // Keep manually added prompts without source_url finalPrompts.push(p); } }); habuPrompts.forEach(newP => { const existing = existingMap.get(newP.source_url); if (existing) { finalPrompts.push({ ...newP, id: existing.id, images: existing.images, // Keep existing images if modified? Or sync? Logic in service was keeping existing images. createdAt: existing.createdAt, useCount: existing.useCount, lastUsedAt: existing.lastUsedAt }); existingMap.delete(newP.source_url); } else { addedCount++; finalPrompts.push({ ...newP, createdAt: now, useCount: 0 }); } }); // Add remaining existing existingMap.forEach(p => finalPrompts.push(p)); // Re-ID finalPrompts.forEach((p, i) => p.id = i + 1); // Update Meta const categories = { "style": Array.from(new Set(finalPrompts.map(p => p.category))) }; const newCache = { last_updated: new Date(now).toISOString(), lastSync: now, categories, total_count: finalPrompts.length, sources: Array.from(new Set(finalPrompts.map(p => p.source))), prompts: finalPrompts }; await fs.writeFile(DATA_FILE, JSON.stringify(newCache, null, 2), 'utf-8'); console.log(`Merge complete. Total: ${finalPrompts.length}, Added: ${addedCount}`); } mergePrompts().catch(console.error);