gmail-to-exchange365
Version:
Complete Gmail to Exchange 365 migration tool with UI - Migrate emails, attachments, and folders seamlessly
138 lines • 5.66 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Migrator = void 0;
exports.migrateUser = migrateUser;
const gmailFetcher_1 = require("./gmailFetcher");
const exchangePusher_1 = require("./exchangePusher");
const folderMapper_1 = require("./folderMapper");
class Migrator {
constructor(gToken, msToken, options = {}) {
this.gToken = gToken;
this.msToken = msToken;
this.options = options;
this.progress = {
current: 0,
total: 0,
status: 'idle'
};
this.shouldPause = false;
this.shouldStop = false;
this.options = {
batchSize: options.batchSize || 10,
delayBetweenBatches: options.delayBetweenBatches || 1000,
retryAttempts: options.retryAttempts || 3,
retryDelay: options.retryDelay || 5000
};
}
onProgress(callback) {
this.onProgressCallback = callback;
}
pause() {
this.shouldPause = true;
this.progress.status = 'paused';
this.notifyProgress();
}
resume() {
this.shouldPause = false;
this.progress.status = 'running';
this.notifyProgress();
}
stop() {
this.shouldStop = true;
this.progress.status = 'idle';
this.notifyProgress();
}
notifyProgress() {
if (this.onProgressCallback) {
this.onProgressCallback({ ...this.progress });
}
}
async waitIfPaused() {
while (this.shouldPause && !this.shouldStop) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
async migrate() {
this.progress.status = 'running';
this.progress.current = 0;
this.shouldStop = false;
this.shouldPause = false;
try {
this.progress.message = "Fetching emails from Gmail...";
this.notifyProgress();
const emails = await (0, gmailFetcher_1.fetchAllEmails)(this.gToken);
this.progress.total = emails.length;
this.progress.message = `Found ${emails.length} emails. Starting migration...`;
this.notifyProgress();
const client = (0, exchangePusher_1.getGraphClient)(this.msToken);
// Fetch and map folders
const labels = await (0, gmailFetcher_1.fetchGmailLabels)(this.gToken);
const folderMappings = await (0, folderMapper_1.mapGmailLabelsToFolders)(client, labels);
let successful = 0;
let failed = 0;
const batchSize = this.options.batchSize;
for (let i = 0; i < emails.length; i += batchSize) {
if (this.shouldStop) {
this.progress.message = "Migration stopped by user";
this.progress.status = 'idle';
this.notifyProgress();
break;
}
await this.waitIfPaused();
const batch = emails.slice(i, i + batchSize);
for (const email of batch) {
if (this.shouldStop)
break;
await this.waitIfPaused();
const folderId = (0, folderMapper_1.getFolderIdForLabel)(folderMappings, email.labels || []);
let retries = 0;
let success = false;
while (retries < this.options.retryAttempts && !success) {
try {
await (0, exchangePusher_1.uploadEmail)(client, email, folderId);
successful++;
success = true;
}
catch (error) {
retries++;
if (retries >= this.options.retryAttempts) {
console.error(`Failed to migrate email ${email.id} after ${retries} attempts:`, error.message);
failed++;
}
else {
await new Promise(resolve => setTimeout(resolve, this.options.retryDelay));
}
}
}
this.progress.current = i + batch.indexOf(email) + 1;
this.progress.message = `Migrated ${this.progress.current}/${this.progress.total} emails`;
this.notifyProgress();
}
// Delay between batches to avoid rate limiting
if (i + batchSize < emails.length) {
await new Promise(resolve => setTimeout(resolve, this.options.delayBetweenBatches));
}
}
this.progress.status = 'completed';
this.progress.message = `Migration completed! ${successful} successful, ${failed} failed`;
this.notifyProgress();
return { total: emails.length, successful, failed };
}
catch (error) {
this.progress.status = 'error';
this.progress.error = error.message;
this.progress.message = `Migration failed: ${error.message}`;
this.notifyProgress();
throw error;
}
}
}
exports.Migrator = Migrator;
async function migrateUser(gToken, msToken, onProgress, options) {
const migrator = new Migrator(gToken, msToken, options);
migrator.onProgress((progress) => {
onProgress(progress.current, progress.total, progress.message);
});
return await migrator.migrate();
}
//# sourceMappingURL=migrator.js.map