UNPKG

lorehub

Version:

Capture and surface the collective wisdom of your codebase

146 lines 6.73 kB
import React, { useState, useEffect } from 'react'; import { render, Box, Text } from 'ink'; import { Database } from '../../db/database.js'; import { getDbPath } from '../utils/db-config.js'; import { Progress } from '../components/Progress.js'; import { ErrorMessage } from '../components/ErrorMessage.js'; import fs from 'fs/promises'; import path from 'path'; function Import({ inputFile, merge = false }) { const [status, setStatus] = useState('loading'); const [error, setError] = useState(null); const [importedCount, setImportedCount] = useState(0); const [totalCount, setTotalCount] = useState(0); const [summary, setSummary] = useState(null); useEffect(() => { async function performImport() { try { // Read and parse import file const resolvedPath = path.resolve(inputFile); const fileContent = await fs.readFile(resolvedPath, 'utf-8'); let importData; try { importData = JSON.parse(fileContent); } catch (err) { throw new Error('Invalid JSON format. Please ensure the file is a valid LoreHub export.'); } // Validate import data if (!importData.version || !importData.realms || !importData.lores) { throw new Error('Invalid import file format. Missing required fields.'); } setTotalCount(importData.realms.length + importData.lores.length); setStatus('importing'); const dbPath = getDbPath(); const db = new Database(dbPath); // Clear existing data if not merging if (!merge) { // Get all existing realms and delete their lores const existingRealms = db.listRealms(); for (const realm of existingRealms) { const lores = db.listLoresByRealm(realm.id); for (const lore of lores) { db.deleteLore(lore.id); } } } // Import realms const realmIdMap = new Map(); // old ID -> new ID let importedRealms = 0; for (const realm of importData.realms) { setImportedCount(prev => prev + 1); // Check if realm already exists let existingRealm = db.findRealmByPath(realm.path); if (existingRealm && merge) { // Update existing realm realmIdMap.set(realm.id, existingRealm.id); } else { // Create new realm const newRealm = db.createRealm({ name: realm.name, path: realm.path, gitRemote: realm.gitRemote === null ? undefined : realm.gitRemote, isMonorepo: realm.isMonorepo, provinces: realm.provinces, }); realmIdMap.set(realm.id, newRealm.id); importedRealms++; } } // Import lores let importedLores = 0; for (const lore of importData.lores) { setImportedCount(prev => prev + 1); const newRealmId = realmIdMap.get(lore.realmId); if (!newRealmId) { console.warn(`Skipping lore: realm ${lore.realmId} not found`); continue; } const loreInput = { realmId: newRealmId, content: lore.content, type: lore.type, status: lore.status, confidence: lore.confidence, why: lore.why === null ? undefined : lore.why, provinces: lore.provinces, sigils: lore.sigils, origin: lore.origin, }; try { await db.createLore(loreInput); importedLores++; } catch (err) { console.warn(`Failed to import lore: ${err}`); } } db.close(); setSummary({ realms: importedRealms, lores: importedLores }); setStatus('success'); } catch (err) { setError(err instanceof Error ? err : new Error('Import failed')); setStatus('error'); } } performImport(); }, [inputFile, merge]); if (status === 'loading') { return React.createElement(Progress, { message: "Reading import file..." }); } if (status === 'importing') { return (React.createElement(Progress, { message: "Importing data...", current: importedCount, total: totalCount })); } if (status === 'error' && error) { return (React.createElement(ErrorMessage, { error: error, context: "Import", suggestions: [ 'Check if the import file exists and is readable', 'Ensure the file is a valid LoreHub export (JSON format)', 'Use --merge flag to add to existing data instead of replacing', ] })); } if (status === 'success' && summary) { return (React.createElement(Box, { flexDirection: "column" }, React.createElement(Text, { color: "green", bold: true }, "\u2713 Import completed successfully!"), React.createElement(Text, null, "Imported from: ", path.resolve(inputFile)), React.createElement(Box, { marginTop: 1 }, React.createElement(Text, null, "\u2022 Realms: ", summary.realms)), React.createElement(Box, null, React.createElement(Text, null, "\u2022 Lores: ", summary.lores)), merge && (React.createElement(Box, { marginTop: 1 }, React.createElement(Text, { dimColor: true }, "Mode: Merge (existing data preserved)"))))); } return null; } export async function renderImport(options) { const { waitUntilExit } = render(React.createElement(Import, { ...options })); await waitUntilExit(); } //# sourceMappingURL=import.js.map