#!/usr/bin/env node import crypto from 'node:crypto'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; import { initDatabase } from '../src/db.js'; import { maildirRootFromEnvironment } from '../src/maildir-store.js'; import { migrateInboundMessagesToMaildir } from '../src/maildir-sync.js'; import { loadMailHubEnvironment } from './import-vesta-maildir.js'; export async function runSqliteMaildirMigration({ env = process.env, output = process.stdout } = {}) { loadMailHubEnvironment({ env }); const dataDir = path.resolve(env.DATA_DIR || path.join(process.cwd(), 'data')); const maildirRoot = maildirRootFromEnvironment(env); const secret = String(env.SESSION_SECRET || crypto .createHash('sha256') .update(`${env.ADMIN_PASSWORD || 'change-this-admin-password'}:${env.API_TOKEN || ''}`) .digest('hex')); initDatabase(dataDir, secret); let lastReported = 0; const report = await migrateInboundMessagesToMaildir({ root: maildirRoot, onProgress(progress) { if (progress.processed - lastReported < 250) return; lastReported = progress.processed; output.write(`Maildir migration progress: processed=${progress.processed} written=${progress.written} reused=${progress.reused}\n`); } }); output.write(`Maildir migration complete: processed=${report.processed} written=${report.written} reused=${report.reused}\n`); return report; } function isMainModule() { const scriptPath = process.argv[1] ? path.resolve(process.argv[1]) : ''; return scriptPath && import.meta.url === pathToFileURL(scriptPath).href; } if (isMainModule()) { runSqliteMaildirMigration().catch((error) => { console.error(`Maildir migration failed: ${error.message || error}`); process.exitCode = 1; }); }