#!/usr/bin/env node
import { FastMailClient } from './src/fastmail-client.js';
import dotenv from 'dotenv';
dotenv.config({ path: '../.env' });
async function directFix() {
console.log('๐ง DIRECT FASTMAIL API - FIXING LABEL STRUCTURE\n');
// Initialize FastMail client
const client = new FastMailClient(
process.env.FASTMAIL_API_TOKEN,
'clark@clarkeverson.com',
'clark@clarkeverson.com',
'clarkeverson.com',
'https://api.fastmail.com/jmap/session'
);
try {
// Authenticate
console.log('๐ Authenticating...');
await client.authenticate();
console.log('โ
Authenticated\n');
// Get current mailboxes
const mailboxes = await client.getMailboxes();
console.log(`๐ Found ${mailboxes.length} mailboxes\n`);
// Step 1: Create Information/News (replacing News-Other/News-WSJ)
console.log('๐๏ธ Creating Information/News...');
const infoParent = mailboxes.find(mb => mb.name === 'Information');
if (infoParent) {
try {
const newsExists = mailboxes.find(mb =>
mb.parentId === infoParent.id && mb.name === 'News'
);
if (!newsExists) {
const newsMailbox = await client.createMailbox('News', infoParent.id);
console.log(`โ
Created Information/News (ID: ${newsMailbox.id})`);
// Move emails from old News folder
const oldNews = mailboxes.find(mb => mb.name === 'News' && !mb.parentId);
if (oldNews && oldNews.totalEmails > 0) {
console.log(`๐ง Moving ${oldNews.totalEmails} emails from old News folder...`);
const emails = await client.getEmails({
filter: { inMailbox: oldNews.id },
properties: ['id']
});
if (emails.length > 0) {
await client.moveEmailsToMailbox(emails.map(e => e.id), newsMailbox.id);
console.log(`โ
Moved ${emails.length} emails to Information/News`);
}
}
} else {
console.log('โ
Information/News already exists');
}
} catch (error) {
console.log(`โ Error creating Information/News: ${error.message}`);
}
}
// Step 2: Move newsletter emails to Information/Newsletters
console.log('\n๐ง Moving newsletter emails...');
const newsletters = mailboxes.find(mb =>
mb.parentId === infoParent?.id && mb.name === 'Newsletters'
);
if (newsletters) {
const newsletterFolders = ['Newsletter', 'screened-newsletters', 'Updates'];
for (const folderName of newsletterFolders) {
const folder = mailboxes.find(mb => mb.name === folderName);
if (folder && folder.totalEmails > 0) {
console.log(`๐ง Moving ${folder.totalEmails} emails from ${folderName}...`);
try {
const emails = await client.getEmails({
filter: { inMailbox: folder.id },
properties: ['id']
});
if (emails.length > 0) {
await client.moveEmailsToMailbox(emails.map(e => e.id), newsletters.id);
console.log(`โ
Moved ${emails.length} emails to Information/Newsletters`);
}
} catch (error) {
console.log(`โ Error moving from ${folderName}: ${error.message}`);
}
}
}
}
// Step 3: Delete empty problematic folders
console.log('\n๐๏ธ Deleting empty problematic folders...');
const foldersToDelete = ['News-Other', 'News-WSJ', 'Notifications'];
for (const folderName of foldersToDelete) {
const folder = mailboxes.find(mb => mb.name === folderName);
if (folder && folder.totalEmails === 0) {
try {
await client.deleteMailbox(folder.id);
console.log(`โ
Deleted ${folderName}`);
} catch (error) {
console.log(`โ Error deleting ${folderName}: ${error.message}`);
}
}
}
console.log('\n๐ DIRECT FIX COMPLETE!');
console.log('Ready to update sieve rules with clean hierarchy');
} catch (error) {
console.log('โ Error:', error.message);
console.error(error.stack);
}
}
directFix().catch(console.error);