@bobfrankston/mailx 1.0.368 → 1.0.370

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx",
3
- "version": "1.0.368",
3
+ "version": "1.0.370",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -24,7 +24,7 @@
24
24
  "@bobfrankston/iflow-node": "^0.1.7",
25
25
  "@bobfrankston/miscinfo": "^1.0.9",
26
26
  "@bobfrankston/oauthsupport": "^1.0.24",
27
- "@bobfrankston/msger": "^0.1.344",
27
+ "@bobfrankston/msger": "^0.1.345",
28
28
  "@bobfrankston/mailx-host": "^0.1.4",
29
29
  "@capacitor/android": "^8.3.0",
30
30
  "@capacitor/cli": "^8.3.0",
@@ -88,7 +88,7 @@
88
88
  "@bobfrankston/iflow-node": "^0.1.7",
89
89
  "@bobfrankston/miscinfo": "^1.0.9",
90
90
  "@bobfrankston/oauthsupport": "^1.0.24",
91
- "@bobfrankston/msger": "^0.1.344",
91
+ "@bobfrankston/msger": "^0.1.345",
92
92
  "@bobfrankston/mailx-host": "^0.1.4",
93
93
  "@capacitor/android": "^8.3.0",
94
94
  "@capacitor/cli": "^8.3.0",
@@ -654,6 +654,18 @@ export class MailxDB {
654
654
  this.db.prepare("UPDATE messages SET flags_json = ? WHERE account_id = ? AND uid = ?").run(JSON.stringify(flags), accountId, uid);
655
655
  }
656
656
  updateMessageFolder(accountId, uid, targetFolderId) {
657
+ // Idempotency: if a row already exists at (account, target_folder, uid)
658
+ // — common with Gmail's hash-synthesized UIDs across labels, or any
659
+ // case where the move was already partially applied — the UPDATE
660
+ // would fail the (acct, folder, uid) unique constraint. Treat it as
661
+ // a no-op: drop the source row, the message is already where the
662
+ // user wants it. Previously surfaced as "Mark-as-spam failed: UNIQUE
663
+ // constraint failed" — bad UX for what is logically already done.
664
+ const existingTarget = this.db.prepare("SELECT id FROM messages WHERE account_id = ? AND folder_id = ? AND uid = ?").get(accountId, targetFolderId, uid);
665
+ if (existingTarget) {
666
+ this.db.prepare("DELETE FROM messages WHERE account_id = ? AND uid = ? AND folder_id != ?").run(accountId, uid, targetFolderId);
667
+ return;
668
+ }
657
669
  this.db.prepare("UPDATE messages SET folder_id = ? WHERE account_id = ? AND uid = ?").run(targetFolderId, accountId, uid);
658
670
  }
659
671
  updateBodyPath(accountId, uid, bodyPath) {