Mailspring/packages/local-sync/src/local-sync-worker/syncback-tasks/rename-label.imap.js
Juan Tejada 4e85993957 [local-sync] syncback(Part 3): Fixup runSyncbackTasks
Summary:
Now that we don't run Send tasks outside the sync loop, we don't need
that awful hack wich required passing a `runTask` callback to
`runSyncbackTask` in order to customize how to run the task.

Instead, runSyncbackTask now knows 2 ways to run a task, either via imap, or
via smtp, depending on the resource declared by task to run. So now
SyncbackTasks declare a resource type they need to run, and that will be
passed as their second argument when running.

Depends D3894

Test Plan: manual

Reviewers: mark, halla, spang, evan

Reviewed By: halla, spang, evan

Differential Revision: https://phab.nylas.com/D3896
2017-02-13 13:07:20 -08:00

65 lines
2 KiB
JavaScript

const {Errors: {APIError}} = require('isomorphic-core')
const {SyncbackIMAPTask} = require('./syncback-task')
class RenameLabelIMAP extends SyncbackIMAPTask {
description() {
return `RenameLabel`;
}
affectsImapMessageUIDs() {
return false
}
async run(db, imap) {
const {sequelize, accountId, Label} = db
const {labelId, newLabelName} = this.syncbackRequestObject().props
const oldLabel = await Label.findById(labelId)
await imap.renameBox(oldLabel.name, newLabelName);
// After IMAP succeeds, update the db
const newId = Label.hash({boxName: newLabelName, accountId})
let newLabel;
await sequelize.transaction(async (transaction) => {
newLabel = await Label.create({
id: newId,
accountId,
name: newLabelName,
}, {transaction})
// We can't do batch updates because we need to generate deltas for each
// message and thread
const messages = await oldLabel.getMessages({
transaction,
attributes: ['id'],
include: [{model: Label, as: 'labels', attributes: ['id']}],
})
await Promise.all(messages.map(async (m) => {
const nextLabels = [
newLabel,
...m.labels.filter(l => l.id !== oldLabel.id),
]
await m.setLabels(nextLabels, {transaction})
await m.save({transaction})
}))
const threads = await oldLabel.getThreads({
transaction,
attributes: ['id'],
include: [{model: Label, as: 'labels', attributes: ['id']}],
})
await Promise.all(threads.map(async (t) => {
const nextLabels = [
newLabel,
...t.labels.filter(l => l.id !== oldLabel.id),
]
await t.setLabels(nextLabels, {transaction})
await t.save({transaction})
}))
await oldLabel.destroy({transaction})
})
if (!newLabel) {
throw new APIError(`Error renaming label - can't save to database`)
}
return newLabel.toJSON()
}
}
module.exports = RenameLabelIMAP