@rapidmx/activesync-plugin 1.0.0-beta.2

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.
Files changed (225) hide show
  1. package/LICENSE +382 -0
  2. package/README.md +57 -0
  3. package/dist/lib/BaseDeviceSyncStateRoute.js +90 -0
  4. package/dist/lib/BaseDeviceSyncStateRoute.js.map +1 -0
  5. package/dist/lib/BaseEasRoute.js +213 -0
  6. package/dist/lib/BaseEasRoute.js.map +1 -0
  7. package/dist/lib/CompactDateTime.js +43 -0
  8. package/dist/lib/CompactDateTime.js.map +1 -0
  9. package/dist/lib/EasCommandHandler.js +2 -0
  10. package/dist/lib/EasCommandHandler.js.map +1 -0
  11. package/dist/lib/EasSyncKeyUtils.js +119 -0
  12. package/dist/lib/EasSyncKeyUtils.js.map +1 -0
  13. package/dist/lib/adapters/CalendarSyncAdapter.js +255 -0
  14. package/dist/lib/adapters/CalendarSyncAdapter.js.map +1 -0
  15. package/dist/lib/adapters/ContactsSyncAdapter.js +164 -0
  16. package/dist/lib/adapters/ContactsSyncAdapter.js.map +1 -0
  17. package/dist/lib/adapters/EasCollectionSyncAdapter.js +2 -0
  18. package/dist/lib/adapters/EasCollectionSyncAdapter.js.map +1 -0
  19. package/dist/lib/adapters/EmailSyncAdapter.js +269 -0
  20. package/dist/lib/adapters/EmailSyncAdapter.js.map +1 -0
  21. package/dist/lib/adapters/TasksSyncAdapter.js +100 -0
  22. package/dist/lib/adapters/TasksSyncAdapter.js.map +1 -0
  23. package/dist/lib/adapters/mongo/EmailSyncAdapterMongo.js +16 -0
  24. package/dist/lib/adapters/mongo/EmailSyncAdapterMongo.js.map +1 -0
  25. package/dist/lib/adapters/mongo/index.js +6 -0
  26. package/dist/lib/adapters/mongo/index.js.map +1 -0
  27. package/dist/lib/adapters/sql/EmailSyncAdapterSQL.js +16 -0
  28. package/dist/lib/adapters/sql/EmailSyncAdapterSQL.js.map +1 -0
  29. package/dist/lib/adapters/sql/index.js +6 -0
  30. package/dist/lib/adapters/sql/index.js.map +1 -0
  31. package/dist/lib/codec/WbxmlCodePages.js +706 -0
  32. package/dist/lib/codec/WbxmlCodePages.js.map +1 -0
  33. package/dist/lib/codec/WbxmlDecoder.js +154 -0
  34. package/dist/lib/codec/WbxmlDecoder.js.map +1 -0
  35. package/dist/lib/codec/WbxmlElement.js +31 -0
  36. package/dist/lib/codec/WbxmlElement.js.map +1 -0
  37. package/dist/lib/codec/WbxmlEncoder.js +88 -0
  38. package/dist/lib/codec/WbxmlEncoder.js.map +1 -0
  39. package/dist/lib/commands/ComposeMailCommand.js +187 -0
  40. package/dist/lib/commands/ComposeMailCommand.js.map +1 -0
  41. package/dist/lib/commands/FolderSyncCommand.js +155 -0
  42. package/dist/lib/commands/FolderSyncCommand.js.map +1 -0
  43. package/dist/lib/commands/GetItemEstimateCommand.js +149 -0
  44. package/dist/lib/commands/GetItemEstimateCommand.js.map +1 -0
  45. package/dist/lib/commands/ItemOperationsCommand.js +337 -0
  46. package/dist/lib/commands/ItemOperationsCommand.js.map +1 -0
  47. package/dist/lib/commands/MeetingResponseCommand.js +120 -0
  48. package/dist/lib/commands/MeetingResponseCommand.js.map +1 -0
  49. package/dist/lib/commands/MoveItemsCommand.js +103 -0
  50. package/dist/lib/commands/MoveItemsCommand.js.map +1 -0
  51. package/dist/lib/commands/PingCommand.js +145 -0
  52. package/dist/lib/commands/PingCommand.js.map +1 -0
  53. package/dist/lib/commands/ProvisionCommand.js +164 -0
  54. package/dist/lib/commands/ProvisionCommand.js.map +1 -0
  55. package/dist/lib/commands/ResolveRecipientsCommand.js +123 -0
  56. package/dist/lib/commands/ResolveRecipientsCommand.js.map +1 -0
  57. package/dist/lib/commands/SearchCommand.js +234 -0
  58. package/dist/lib/commands/SearchCommand.js.map +1 -0
  59. package/dist/lib/commands/SendMailCommand.js +18 -0
  60. package/dist/lib/commands/SendMailCommand.js.map +1 -0
  61. package/dist/lib/commands/SettingsCommand.js +138 -0
  62. package/dist/lib/commands/SettingsCommand.js.map +1 -0
  63. package/dist/lib/commands/SmartForwardCommand.js +22 -0
  64. package/dist/lib/commands/SmartForwardCommand.js.map +1 -0
  65. package/dist/lib/commands/SmartReplyCommand.js +22 -0
  66. package/dist/lib/commands/SmartReplyCommand.js.map +1 -0
  67. package/dist/lib/commands/SyncCommand.js +406 -0
  68. package/dist/lib/commands/SyncCommand.js.map +1 -0
  69. package/dist/lib/commands/mongo/FolderSyncCommandMongo.js +16 -0
  70. package/dist/lib/commands/mongo/FolderSyncCommandMongo.js.map +1 -0
  71. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js +21 -0
  72. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js.map +1 -0
  73. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js +18 -0
  74. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js.map +1 -0
  75. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js +17 -0
  76. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js.map +1 -0
  77. package/dist/lib/commands/mongo/MoveItemsCommandMongo.js +17 -0
  78. package/dist/lib/commands/mongo/MoveItemsCommandMongo.js.map +1 -0
  79. package/dist/lib/commands/mongo/ResolveRecipientsCommandMongo.js +16 -0
  80. package/dist/lib/commands/mongo/ResolveRecipientsCommandMongo.js.map +1 -0
  81. package/dist/lib/commands/mongo/SearchCommandMongo.js +19 -0
  82. package/dist/lib/commands/mongo/SearchCommandMongo.js.map +1 -0
  83. package/dist/lib/commands/mongo/SendMailCommandMongo.js +17 -0
  84. package/dist/lib/commands/mongo/SendMailCommandMongo.js.map +1 -0
  85. package/dist/lib/commands/mongo/SettingsCommandMongo.js +16 -0
  86. package/dist/lib/commands/mongo/SettingsCommandMongo.js.map +1 -0
  87. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js +17 -0
  88. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js.map +1 -0
  89. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js +17 -0
  90. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js.map +1 -0
  91. package/dist/lib/commands/mongo/SyncCommandMongo.js +26 -0
  92. package/dist/lib/commands/mongo/SyncCommandMongo.js.map +1 -0
  93. package/dist/lib/commands/mongo/index.js +14 -0
  94. package/dist/lib/commands/mongo/index.js.map +1 -0
  95. package/dist/lib/commands/sql/FolderSyncCommandSQL.js +16 -0
  96. package/dist/lib/commands/sql/FolderSyncCommandSQL.js.map +1 -0
  97. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js +21 -0
  98. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js.map +1 -0
  99. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js +18 -0
  100. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js.map +1 -0
  101. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js +17 -0
  102. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js.map +1 -0
  103. package/dist/lib/commands/sql/MoveItemsCommandSQL.js +17 -0
  104. package/dist/lib/commands/sql/MoveItemsCommandSQL.js.map +1 -0
  105. package/dist/lib/commands/sql/ResolveRecipientsCommandSQL.js +16 -0
  106. package/dist/lib/commands/sql/ResolveRecipientsCommandSQL.js.map +1 -0
  107. package/dist/lib/commands/sql/SearchCommandSQL.js +19 -0
  108. package/dist/lib/commands/sql/SearchCommandSQL.js.map +1 -0
  109. package/dist/lib/commands/sql/SendMailCommandSQL.js +17 -0
  110. package/dist/lib/commands/sql/SendMailCommandSQL.js.map +1 -0
  111. package/dist/lib/commands/sql/SettingsCommandSQL.js +16 -0
  112. package/dist/lib/commands/sql/SettingsCommandSQL.js.map +1 -0
  113. package/dist/lib/commands/sql/SmartForwardCommandSQL.js +17 -0
  114. package/dist/lib/commands/sql/SmartForwardCommandSQL.js.map +1 -0
  115. package/dist/lib/commands/sql/SmartReplyCommandSQL.js +17 -0
  116. package/dist/lib/commands/sql/SmartReplyCommandSQL.js.map +1 -0
  117. package/dist/lib/commands/sql/SyncCommandSQL.js +26 -0
  118. package/dist/lib/commands/sql/SyncCommandSQL.js.map +1 -0
  119. package/dist/lib/commands/sql/index.js +14 -0
  120. package/dist/lib/commands/sql/index.js.map +1 -0
  121. package/dist/lib/index.js +58 -0
  122. package/dist/lib/index.js.map +1 -0
  123. package/dist/lib/jobs/EasDeviceStateCleanupJob.js +101 -0
  124. package/dist/lib/jobs/EasDeviceStateCleanupJob.js.map +1 -0
  125. package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js +13 -0
  126. package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js.map +1 -0
  127. package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js +13 -0
  128. package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js.map +1 -0
  129. package/dist/lib/models/DeviceSyncState.js +2 -0
  130. package/dist/lib/models/DeviceSyncState.js.map +1 -0
  131. package/dist/lib/models/mongo/DeviceSyncStateMongo.js +130 -0
  132. package/dist/lib/models/mongo/DeviceSyncStateMongo.js.map +1 -0
  133. package/dist/lib/models/sql/DeviceSyncStateSQL.js +130 -0
  134. package/dist/lib/models/sql/DeviceSyncStateSQL.js.map +1 -0
  135. package/dist/lib/mongo/DeviceSyncStateRouteMongo.js +28 -0
  136. package/dist/lib/mongo/DeviceSyncStateRouteMongo.js.map +1 -0
  137. package/dist/lib/mongo/EasRouteMongo.js +63 -0
  138. package/dist/lib/mongo/EasRouteMongo.js.map +1 -0
  139. package/dist/lib/mongo/index.js +9 -0
  140. package/dist/lib/mongo/index.js.map +1 -0
  141. package/dist/lib/mongo.js +15 -0
  142. package/dist/lib/mongo.js.map +1 -0
  143. package/dist/lib/sql/DeviceSyncStateRouteSQL.js +28 -0
  144. package/dist/lib/sql/DeviceSyncStateRouteSQL.js.map +1 -0
  145. package/dist/lib/sql/EasRouteSQL.js +63 -0
  146. package/dist/lib/sql/EasRouteSQL.js.map +1 -0
  147. package/dist/lib/sql/index.js +9 -0
  148. package/dist/lib/sql/index.js.map +1 -0
  149. package/dist/lib/sql.js +15 -0
  150. package/dist/lib/sql.js.map +1 -0
  151. package/dist/types/BaseDeviceSyncStateRoute.d.ts +34 -0
  152. package/dist/types/BaseEasRoute.d.ts +65 -0
  153. package/dist/types/CompactDateTime.d.ts +22 -0
  154. package/dist/types/EasCommandHandler.d.ts +59 -0
  155. package/dist/types/EasSyncKeyUtils.d.ts +89 -0
  156. package/dist/types/adapters/CalendarSyncAdapter.d.ts +52 -0
  157. package/dist/types/adapters/ContactsSyncAdapter.d.ts +33 -0
  158. package/dist/types/adapters/EasCollectionSyncAdapter.d.ts +55 -0
  159. package/dist/types/adapters/EmailSyncAdapter.d.ts +71 -0
  160. package/dist/types/adapters/TasksSyncAdapter.d.ts +32 -0
  161. package/dist/types/adapters/mongo/EmailSyncAdapterMongo.d.ts +7 -0
  162. package/dist/types/adapters/mongo/index.d.ts +1 -0
  163. package/dist/types/adapters/sql/EmailSyncAdapterSQL.d.ts +7 -0
  164. package/dist/types/adapters/sql/index.d.ts +1 -0
  165. package/dist/types/codec/WbxmlCodePages.d.ts +45 -0
  166. package/dist/types/codec/WbxmlDecoder.d.ts +33 -0
  167. package/dist/types/codec/WbxmlElement.d.ts +43 -0
  168. package/dist/types/codec/WbxmlEncoder.d.ts +20 -0
  169. package/dist/types/commands/ComposeMailCommand.d.ts +50 -0
  170. package/dist/types/commands/FolderSyncCommand.d.ts +25 -0
  171. package/dist/types/commands/GetItemEstimateCommand.d.ts +43 -0
  172. package/dist/types/commands/ItemOperationsCommand.d.ts +72 -0
  173. package/dist/types/commands/MeetingResponseCommand.d.ts +32 -0
  174. package/dist/types/commands/MoveItemsCommand.d.ts +29 -0
  175. package/dist/types/commands/PingCommand.d.ts +33 -0
  176. package/dist/types/commands/ProvisionCommand.d.ts +54 -0
  177. package/dist/types/commands/ResolveRecipientsCommand.d.ts +36 -0
  178. package/dist/types/commands/SearchCommand.d.ts +60 -0
  179. package/dist/types/commands/SendMailCommand.d.ts +10 -0
  180. package/dist/types/commands/SettingsCommand.d.ts +37 -0
  181. package/dist/types/commands/SmartForwardCommand.d.ts +17 -0
  182. package/dist/types/commands/SmartReplyCommand.d.ts +17 -0
  183. package/dist/types/commands/SyncCommand.d.ts +100 -0
  184. package/dist/types/commands/mongo/FolderSyncCommandMongo.d.ts +8 -0
  185. package/dist/types/commands/mongo/GetItemEstimateCommandMongo.d.ts +7 -0
  186. package/dist/types/commands/mongo/ItemOperationsCommandMongo.d.ts +9 -0
  187. package/dist/types/commands/mongo/MeetingResponseCommandMongo.d.ts +8 -0
  188. package/dist/types/commands/mongo/MoveItemsCommandMongo.d.ts +8 -0
  189. package/dist/types/commands/mongo/ResolveRecipientsCommandMongo.d.ts +7 -0
  190. package/dist/types/commands/mongo/SearchCommandMongo.d.ts +9 -0
  191. package/dist/types/commands/mongo/SendMailCommandMongo.d.ts +8 -0
  192. package/dist/types/commands/mongo/SettingsCommandMongo.d.ts +7 -0
  193. package/dist/types/commands/mongo/SmartForwardCommandMongo.d.ts +8 -0
  194. package/dist/types/commands/mongo/SmartReplyCommandMongo.d.ts +8 -0
  195. package/dist/types/commands/mongo/SyncCommandMongo.d.ts +8 -0
  196. package/dist/types/commands/mongo/index.d.ts +9 -0
  197. package/dist/types/commands/sql/FolderSyncCommandSQL.d.ts +8 -0
  198. package/dist/types/commands/sql/GetItemEstimateCommandSQL.d.ts +7 -0
  199. package/dist/types/commands/sql/ItemOperationsCommandSQL.d.ts +9 -0
  200. package/dist/types/commands/sql/MeetingResponseCommandSQL.d.ts +8 -0
  201. package/dist/types/commands/sql/MoveItemsCommandSQL.d.ts +8 -0
  202. package/dist/types/commands/sql/ResolveRecipientsCommandSQL.d.ts +7 -0
  203. package/dist/types/commands/sql/SearchCommandSQL.d.ts +9 -0
  204. package/dist/types/commands/sql/SendMailCommandSQL.d.ts +8 -0
  205. package/dist/types/commands/sql/SettingsCommandSQL.d.ts +7 -0
  206. package/dist/types/commands/sql/SmartForwardCommandSQL.d.ts +8 -0
  207. package/dist/types/commands/sql/SmartReplyCommandSQL.d.ts +8 -0
  208. package/dist/types/commands/sql/SyncCommandSQL.d.ts +8 -0
  209. package/dist/types/commands/sql/index.d.ts +9 -0
  210. package/dist/types/index.d.ts +53 -0
  211. package/dist/types/jobs/EasDeviceStateCleanupJob.d.ts +26 -0
  212. package/dist/types/jobs/mongo/EasDeviceStateCleanupJobMongo.d.ts +5 -0
  213. package/dist/types/jobs/sql/EasDeviceStateCleanupJobSQL.d.ts +5 -0
  214. package/dist/types/models/DeviceSyncState.d.ts +30 -0
  215. package/dist/types/models/mongo/DeviceSyncStateMongo.d.ts +22 -0
  216. package/dist/types/models/sql/DeviceSyncStateSQL.d.ts +22 -0
  217. package/dist/types/mongo/DeviceSyncStateRouteMongo.d.ts +8 -0
  218. package/dist/types/mongo/EasRouteMongo.d.ts +14 -0
  219. package/dist/types/mongo/index.d.ts +4 -0
  220. package/dist/types/mongo.d.ts +10 -0
  221. package/dist/types/sql/DeviceSyncStateRouteSQL.d.ts +8 -0
  222. package/dist/types/sql/EasRouteSQL.d.ts +14 -0
  223. package/dist/types/sql/index.d.ts +4 -0
  224. package/dist/types/sql.d.ts +10 -0
  225. package/package.json +238 -0
@@ -0,0 +1,269 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ ///////////////////////////////////////////////////////////////////////////////
11
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
12
+ // SPDX-License-Identifier: MPL-2.0
13
+ ///////////////////////////////////////////////////////////////////////////////
14
+ import * as crypto from "crypto";
15
+ import { ObjectDecorators } from "@rapidrest/core";
16
+ import { RepoUtils } from "@rapidrest/service-core";
17
+ import { WbxmlCodePage } from "../codec/WbxmlCodePages.js";
18
+ import { childText, element, findChild, opaqueElement, textElement } from "../codec/WbxmlElement.js";
19
+ import { MessageImportance, RecipientType } from "@rapidmx/restapi";
20
+ const { Init, Inject } = ObjectDecorators;
21
+ /** MS-ASEMAIL `Importance`: 0=Low, 1=Normal, 2=High. */
22
+ const IMPORTANCE_CODES = {
23
+ [MessageImportance.LOW]: "0",
24
+ [MessageImportance.NORMAL]: "1",
25
+ [MessageImportance.HIGH]: "2",
26
+ };
27
+ const IMPORTANCE_BY_CODE = {
28
+ "0": MessageImportance.LOW,
29
+ "1": MessageImportance.NORMAL,
30
+ "2": MessageImportance.HIGH,
31
+ };
32
+ /** MS-ASAIRSYNCBASE `Body.Type`: 1 = plain text, 2 = HTML, 3 = RTF, 4 = MIME. */
33
+ const BODY_TYPE_PLAIN_TEXT = "1";
34
+ /**
35
+ * Maps `Message` to/from the EAS `Sync` `Email` collection class (MS-ASEMAIL). Only a plain-text preview of the
36
+ * body is included here (`Message.bodyPreview`, always already loaded on the entity, `Truncated: 1`) rather
37
+ * than the full sanitized HTML body from the `BlobStore` - a real device fetches the full body on demand via
38
+ * `ItemOperations`' `Fetch` (see the architecture plan's command table), the same two-step "list, then fetch
39
+ * body" flow every real EAS client already implements for exactly this reason (bodies can be large; a sync
40
+ * window's Add/Change list shouldn't have to pull every one of them from blob storage up front).
41
+ *
42
+ * Also handles client-originated `Add`/`Change` for Drafts (`SyncCommand`'s own doc comment covers why this is
43
+ * the only `Email` write EAS itself allows) - a plain-text-only pragmatic subset: no HTML body, no attachments
44
+ * (mirrors `ComposeMailCommand`'s own already-documented attachment gap). `To`/`Cc`/`Bcc` (the latter MS-ASEMAIL2's
45
+ * own `Bcc` tag) are ghosted independently per recipient type, not as one combined group - a `Change` touching
46
+ * only one of them leaves the others untouched, carried over from `existing.recipients`.
47
+ *
48
+ * Emits MS-ASEMAIL2's `Email2:ConversationId` (read-only - no `fromApplicationData` handling, since EAS itself
49
+ * never lets a client set it) whenever `Message.conversationId` is populated, so a device's threaded-view UI can
50
+ * group messages the same way `BaseMessageRoute.conversations()` does server-side. See `encodeConversationId`'s
51
+ * own doc comment for the wire encoding, and `ItemOperationsCommand`'s `Move` handling for the one place this
52
+ * gets decoded back.
53
+ *
54
+ * Emits MS-ASEMAIL's `Categories`/`Category` (also read-only) from `Message.labelUids`, resolved against the
55
+ * `Label` repo to real display names - a stale `labelUids` entry (the label was since deleted) is silently
56
+ * dropped rather than surfacing as an error, the same "tolerate a dangling reference" stance `SearchCommand`
57
+ * already takes for a stale search-index entry. Deliberately not writable: unlike `Contact.categories` (a
58
+ * plain free-form string array with no separate entity behind it), a `Label` is a real mailbox-scoped entity
59
+ * referenced by uid - a write path would need to resolve category name strings back to `Label`s and create new
60
+ * ones on the fly for names that don't exist yet, real added scope this pragmatic subset defers. One `find()`
61
+ * per message that actually has labels (most won't, since labels are opt-in) - not batched across a whole Sync
62
+ * page/search result set, a documented, modest N+1 tradeoff rather than widening this adapter's own interface
63
+ * further to let a caller pre-resolve names for a whole batch.
64
+ *
65
+ * `labelClass` is supplied by the Mongo/SQL concrete subclasses.
66
+ *
67
+ * @author Jean-Philippe Steinmetz
68
+ */
69
+ export class EmailSyncAdapter {
70
+ constructor() {
71
+ this.collectionClass = "Email";
72
+ }
73
+ async init() {
74
+ this.labelRepo = await this._objectFactory.newInstance(RepoUtils, {
75
+ name: this.labelClass.name,
76
+ args: [this.labelClass],
77
+ });
78
+ }
79
+ async toApplicationData(message) {
80
+ const to = message.recipients.filter((r) => r.type === RecipientType.TO).map((r) => r.address);
81
+ const cc = message.recipients.filter((r) => r.type === RecipientType.CC).map((r) => r.address);
82
+ const bcc = message.recipients.filter((r) => r.type === RecipientType.BCC).map((r) => r.address);
83
+ const categories = await this.resolveLabelNames(message);
84
+ return element(WbxmlCodePage.AirSync, "ApplicationData", [
85
+ textElement(WbxmlCodePage.Email, "Subject", message.subject),
86
+ textElement(WbxmlCodePage.Email, "From", formatAddress(message.from.address, message.from.displayName)),
87
+ ...(to.length > 0 ? [textElement(WbxmlCodePage.Email, "To", to.join("; "))] : []),
88
+ ...(cc.length > 0 ? [textElement(WbxmlCodePage.Email, "Cc", cc.join("; "))] : []),
89
+ ...(bcc.length > 0 ? [textElement(WbxmlCodePage.Email2, "Bcc", bcc.join("; "))] : []),
90
+ textElement(WbxmlCodePage.Email, "DateReceived", message.receivedDate.toISOString()),
91
+ textElement(WbxmlCodePage.Email, "Importance", IMPORTANCE_CODES[message.importance]),
92
+ textElement(WbxmlCodePage.Email, "Read", message.flags.read ? "1" : "0"),
93
+ textElement(WbxmlCodePage.Email, "Flag", message.flags.flagged ? "1" : "0"),
94
+ element(WbxmlCodePage.AirSyncBase, "Body", [
95
+ textElement(WbxmlCodePage.AirSyncBase, "Type", BODY_TYPE_PLAIN_TEXT),
96
+ textElement(WbxmlCodePage.AirSyncBase, "EstimatedDataSize", String(Buffer.byteLength(message.bodyPreview, "utf8"))),
97
+ textElement(WbxmlCodePage.AirSyncBase, "Truncated", "1"),
98
+ textElement(WbxmlCodePage.AirSyncBase, "Data", message.bodyPreview),
99
+ ]),
100
+ ...(message.conversationId ? [opaqueElement(WbxmlCodePage.Email2, "ConversationId", encodeConversationId(message.conversationId))] : []),
101
+ ...(categories.length > 0
102
+ ? [
103
+ element(WbxmlCodePage.Email, "Categories", categories.map((name) => textElement(WbxmlCodePage.Email, "Category", name))),
104
+ ]
105
+ : []),
106
+ ]);
107
+ }
108
+ async resolveLabelNames(message) {
109
+ if (!message.labelUids || message.labelUids.length === 0) {
110
+ return [];
111
+ }
112
+ const labels = await this.labelRepo.find({ mailboxUid: message.mailboxUid, uid: `in(${message.labelUids.join(",")})` }, { ignoreACL: true });
113
+ return labels.map((label) => label.name);
114
+ }
115
+ /**
116
+ * `Message.bodyBlobKey` is documented (see the `Message` interface itself) as holding raw MIME "unmodified
117
+ * from ingestion/send" - `ItemOperationsCommand.fetchMessage` parses it with `simpleParser` unconditionally
118
+ * for every message, Draft or not. A Draft's plain-text body is therefore wrapped in a minimal valid
119
+ * RFC 5322 message here (via `buildPlainTextMime`) rather than stored as bare text, so that contract holds
120
+ * for every consumer, not just this write path - a Draft created/edited via `Sync` must `Fetch` correctly
121
+ * the same way any other message does.
122
+ */
123
+ async fromApplicationData(el, existing) {
124
+ const partial = {};
125
+ const subject = childText(el, "Subject");
126
+ if (subject !== undefined)
127
+ partial.subject = subject;
128
+ const to = childText(el, "To");
129
+ const cc = childText(el, "Cc");
130
+ const bcc = childText(el, "Bcc");
131
+ if (to !== undefined || cc !== undefined || bcc !== undefined) {
132
+ // Ghosted per-recipient-type, not as one combined group: a `Change` touching only `To` must leave
133
+ // any existing `Cc`/`Bcc` recipients alone, so untouched types are carried over from `existing`
134
+ // rather than the whole `recipients` array being rebuilt from just what's present in `el`.
135
+ const untouched = (existing?.recipients ?? []).filter((r) => (r.type !== RecipientType.TO || to === undefined) &&
136
+ (r.type !== RecipientType.CC || cc === undefined) &&
137
+ (r.type !== RecipientType.BCC || bcc === undefined));
138
+ partial.recipients = [
139
+ ...untouched,
140
+ ...(to !== undefined ? parseAddressList(to, RecipientType.TO) : []),
141
+ ...(cc !== undefined ? parseAddressList(cc, RecipientType.CC) : []),
142
+ ...(bcc !== undefined ? parseAddressList(bcc, RecipientType.BCC) : []),
143
+ ];
144
+ }
145
+ const importance = childText(el, "Importance");
146
+ if (importance !== undefined) {
147
+ partial.importance = IMPORTANCE_BY_CODE[importance] ?? MessageImportance.NORMAL;
148
+ }
149
+ const read = childText(el, "Read");
150
+ const flag = childText(el, "Flag");
151
+ if (read !== undefined || flag !== undefined) {
152
+ const baseFlags = existing?.flags ?? { read: false, flagged: false, answered: false, forwarded: false };
153
+ partial.flags = {
154
+ ...baseFlags,
155
+ ...(read !== undefined ? { read: read === "1" } : {}),
156
+ ...(flag !== undefined ? { flagged: flag === "1" } : {}),
157
+ };
158
+ }
159
+ const bodyEl = findChild(el, "Body");
160
+ if (bodyEl) {
161
+ const text = childText(bodyEl, "Data") ?? "";
162
+ // Reuse the existing blob key on a Change (overwriting its content) rather than minting a new one
163
+ // - a fresh key is only needed the first time a body is set (a bare `existing.bodyBlobKey` of ""
164
+ // means an earlier Add never included a Body element at all).
165
+ const bodyBlobKey = existing?.bodyBlobKey || `bodies/${crypto.randomUUID()}`;
166
+ const mime = buildPlainTextMime({
167
+ subject: partial.subject ?? existing?.subject ?? "",
168
+ from: existing?.from,
169
+ recipients: partial.recipients ?? existing?.recipients ?? [],
170
+ date: existing?.sentDate ?? new Date(),
171
+ text,
172
+ });
173
+ await this.blobStore.put(bodyBlobKey, Buffer.from(mime, "utf-8"), { contentType: "message/rfc822" });
174
+ partial.bodyBlobKey = bodyBlobKey;
175
+ partial.bodyPreview = text.slice(0, 200);
176
+ }
177
+ return partial;
178
+ }
179
+ /** Defaults for a brand-new Draft created via a client-originated `Add` - `from` is the caller's own
180
+ * mailbox address, per `ComposeMailCommand`'s identical `{ address, type: RecipientType.TO }` shape
181
+ * convention for a `from` field (the `Recipient` struct's `type` is only meaningful for real recipients;
182
+ * it's reused here as a harmless placeholder). */
183
+ newEntityDefaults(mailbox) {
184
+ return {
185
+ messageId: `<${crypto.randomUUID()}@eas>`,
186
+ subject: "",
187
+ from: { address: mailbox.primarySmtpAddress, displayName: mailbox.displayName, type: RecipientType.TO },
188
+ recipients: [],
189
+ sentDate: new Date(),
190
+ receivedDate: new Date(),
191
+ bodyBlobKey: "",
192
+ bodyPreview: "",
193
+ flags: { read: true, flagged: false, answered: false, forwarded: false },
194
+ importance: MessageImportance.NORMAL,
195
+ references: [],
196
+ hasAttachments: false,
197
+ };
198
+ }
199
+ }
200
+ __decorate([
201
+ Inject("BlobStore"),
202
+ __metadata("design:type", Object)
203
+ ], EmailSyncAdapter.prototype, "blobStore", void 0);
204
+ __decorate([
205
+ Init,
206
+ __metadata("design:type", Function),
207
+ __metadata("design:paramtypes", []),
208
+ __metadata("design:returntype", Promise)
209
+ ], EmailSyncAdapter.prototype, "init", null);
210
+ /** Encodes `Message.conversationId` (an internal string uid) into the opaque binary blob MS-ASEMAIL2's
211
+ * `Email2:ConversationId` carries on the wire. The spec never mandates any particular binary format for this
212
+ * value - a real Exchange server mints a GUID, but a client only ever compares/echoes it byte-for-byte, never
213
+ * interprets it - so encoding the uid's own UTF-8 bytes directly (rather than hashing into a 16-byte GUID
214
+ * shape) is a valid, simpler choice that `decodeConversationId` can invert exactly, which `ItemOperationsCommand`
215
+ * relies on to resolve an `ItemOperations` `Move`'s `ConversationId` back into this same uid. */
216
+ export function encodeConversationId(conversationId) {
217
+ return Buffer.from(conversationId, "utf8");
218
+ }
219
+ /** Reverse of `encodeConversationId`. */
220
+ export function decodeConversationId(opaque) {
221
+ return opaque.toString("utf8");
222
+ }
223
+ function formatAddress(address, displayName) {
224
+ return displayName ? `${displayName} <${address}>` : address;
225
+ }
226
+ /** Parses a `;`/`,`-separated address list (`"Name <a@x.com>; b@y.com"`, or the bare-address-only form this
227
+ * adapter's own `toApplicationData` emits) into `Recipient`s of `type`. */
228
+ function parseAddressList(value, type) {
229
+ return value
230
+ .split(/[;,]/)
231
+ .map((part) => part.trim())
232
+ .filter((part) => part.length > 0)
233
+ .map((part) => {
234
+ const match = /^(.*)<(.+)>$/.exec(part);
235
+ return match
236
+ ? { address: match[2].trim(), displayName: match[1].trim() || undefined, type }
237
+ : { address: part, type };
238
+ });
239
+ }
240
+ /** Strips CR/LF from a value about to be interpolated into a single RFC 5322 header line. `Subject`/`To`/`Cc`
241
+ * arrive from client-controlled WBXML inline strings (`WbxmlDecoder.readCString()`, which terminates only on a
242
+ * NUL byte - literal `\r`/`\n` bytes pass through untouched), so without this a crafted value like
243
+ * `"Hi\r\nBcc: attacker@evil.com"` would inject an arbitrary extra header line (or, via a blank line, a forged
244
+ * second message) into the constructed MIME below. Folds onto a single line rather than rejecting outright -
245
+ * a real device is never expected to send this, but a header value silently losing its embedded newlines is
246
+ * safer than the request failing outright over what a client will never notice either way. */
247
+ function sanitizeHeaderValue(value) {
248
+ return value.replace(/[\r\n]+/g, " ");
249
+ }
250
+ /** Builds a minimal, valid RFC 5322 plain-text message - just enough structure for `simpleParser` (used by
251
+ * `ItemOperationsCommand.fetchMessage`) to read it back correctly. No multipart/HTML/attachments - matches this
252
+ * adapter's own documented pragmatic-subset scope. */
253
+ function buildPlainTextMime(parts) {
254
+ const to = parts.recipients.filter((r) => r.type === RecipientType.TO).map((r) => formatAddress(r.address, r.displayName));
255
+ const cc = parts.recipients.filter((r) => r.type === RecipientType.CC).map((r) => formatAddress(r.address, r.displayName));
256
+ const bcc = parts.recipients.filter((r) => r.type === RecipientType.BCC).map((r) => formatAddress(r.address, r.displayName));
257
+ const headers = [
258
+ ...(parts.from ? [`From: ${sanitizeHeaderValue(formatAddress(parts.from.address, parts.from.displayName))}`] : []),
259
+ ...(to.length > 0 ? [`To: ${sanitizeHeaderValue(to.join(", "))}`] : []),
260
+ ...(cc.length > 0 ? [`Cc: ${sanitizeHeaderValue(cc.join(", "))}`] : []),
261
+ ...(bcc.length > 0 ? [`Bcc: ${sanitizeHeaderValue(bcc.join(", "))}`] : []),
262
+ `Subject: ${sanitizeHeaderValue(parts.subject)}`,
263
+ `Date: ${parts.date.toUTCString()}`,
264
+ "MIME-Version: 1.0",
265
+ "Content-Type: text/plain; charset=utf-8",
266
+ ];
267
+ return `${headers.join("\r\n")}\r\n\r\n${parts.text}`;
268
+ }
269
+ //# sourceMappingURL=EmailSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailSyncAdapter.js","sourceRoot":"","sources":["../../../src/adapters/EmailSyncAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import { WbxmlCodePage } from "../codec/WbxmlCodePages.js";
6
+ import { childText, element, findChild, textElement } from "../codec/WbxmlElement.js";
7
+ import { fromCompactDateTime, toCompactDateTime } from "../CompactDateTime.js";
8
+ import { TaskPriority } from "@rapidmx/restapi";
9
+ /** MS-ASTASK `Importance` reuses the same 0/1/2 scale as MS-ASEMAIL's `Importance` (see `EmailSyncAdapter`'s
10
+ * own identical table) - Low/Normal/High. */
11
+ const IMPORTANCE_CODES = {
12
+ [TaskPriority.LOW]: "0",
13
+ [TaskPriority.NORMAL]: "1",
14
+ [TaskPriority.HIGH]: "2",
15
+ };
16
+ const IMPORTANCE_FROM_CODE = Object.fromEntries(Object.entries(IMPORTANCE_CODES).map(([k, v]) => [v, k]));
17
+ /**
18
+ * Maps `Task` to/from the EAS `Sync` `Tasks` collection class (MS-ASTASK).
19
+ *
20
+ * **Pragmatic subset**: only the `Utc*` (UTC Compact DateTime) variant of each date field is emitted, not the
21
+ * paired local-time variant MS-ASTASK also defines (`DueDate`/`StartDate` alongside `UtcDueDate`/
22
+ * `UtcStartDate`) - this library doesn't track a per-task timezone to correctly localize the non-UTC variant,
23
+ * and a real device already treats the `Utc*` field as authoritative. Recurring tasks are not synced (a task's
24
+ * `Recurrence` element mirrors Calendar's, itself already a pragmatic subset there - deferred further here).
25
+ *
26
+ * @author Jean-Philippe Steinmetz
27
+ */
28
+ export class TasksSyncAdapter {
29
+ constructor() {
30
+ this.collectionClass = "Tasks";
31
+ }
32
+ toApplicationData(task) {
33
+ return element(WbxmlCodePage.AirSync, "ApplicationData", [
34
+ textElement(WbxmlCodePage.Tasks, "Subject", task.title),
35
+ textElement(WbxmlCodePage.Tasks, "Complete", task.completed ? "1" : "0"),
36
+ ...(task.completed ? [textElement(WbxmlCodePage.Tasks, "DateCompleted", toCompactDateTime(task.dateModified))] : []),
37
+ ...(task.dueDate ? [textElement(WbxmlCodePage.Tasks, "UtcDueDate", toCompactDateTime(task.dueDate))] : []),
38
+ textElement(WbxmlCodePage.Tasks, "Importance", IMPORTANCE_CODES[task.priority]),
39
+ textElement(WbxmlCodePage.Tasks, "Sensitivity", "0"),
40
+ textElement(WbxmlCodePage.Tasks, "ReminderSet", task.reminderDate ? "1" : "0"),
41
+ ...(task.reminderDate ? [textElement(WbxmlCodePage.Tasks, "ReminderTime", toCompactDateTime(task.reminderDate))] : []),
42
+ ...(task.body
43
+ ? [
44
+ element(WbxmlCodePage.AirSyncBase, "Body", [
45
+ textElement(WbxmlCodePage.AirSyncBase, "Type", "1"),
46
+ textElement(WbxmlCodePage.AirSyncBase, "EstimatedDataSize", String(Buffer.byteLength(task.body, "utf8"))),
47
+ textElement(WbxmlCodePage.AirSyncBase, "Data", task.body),
48
+ ]),
49
+ ]
50
+ : []),
51
+ ]);
52
+ }
53
+ /**
54
+ * Reverse of `toApplicationData`. `DateCompleted` is never parsed back - it's `task.dateModified` echoed
55
+ * out, not an independent field this library's own `Task` model has room to store separately, so a client
56
+ * setting `Complete` is enough on its own. `ReminderSet="0"` (with no `ReminderTime`) is treated as an
57
+ * explicit "clear the reminder" signal (`reminderDate: null` in the returned partial, which - unlike
58
+ * simply omitting the key - does override an existing reminder when merged onto `existing` for a `Change`)
59
+ * since MS-ASTASK gives no other way to express removing a reminder; `UtcDueDate` has no equivalent
60
+ * explicit-clear signal and so can only be set, never cleared, via `Sync` - a real, narrower gap than
61
+ * `reminderDate`'s, documented here rather than silently accepted. `null`, not `undefined`: TypeORM's
62
+ * `UpdateQueryBuilder` silently drops any `undefined`-valued key from the generated SQL `SET` clause
63
+ * (confirmed by reading its source), so `undefined` here would leave a stale `reminderDate` in place on
64
+ * the SQL backend while correctly clearing it on Mongo - `null` clears it on both.
65
+ */
66
+ fromApplicationData(el) {
67
+ const partial = {};
68
+ const subject = childText(el, "Subject");
69
+ if (subject !== undefined)
70
+ partial.title = subject;
71
+ const complete = childText(el, "Complete");
72
+ if (complete !== undefined)
73
+ partial.completed = complete === "1";
74
+ const utcDueDate = childText(el, "UtcDueDate");
75
+ if (utcDueDate !== undefined)
76
+ partial.dueDate = fromCompactDateTime(utcDueDate);
77
+ const importance = childText(el, "Importance");
78
+ if (importance !== undefined) {
79
+ const mapped = IMPORTANCE_FROM_CODE[importance];
80
+ if (!mapped) {
81
+ throw new Error(`Unrecognized Importance value: '${importance}'`);
82
+ }
83
+ partial.priority = mapped;
84
+ }
85
+ const reminderSet = childText(el, "ReminderSet");
86
+ const reminderTime = childText(el, "ReminderTime");
87
+ if (reminderTime !== undefined) {
88
+ partial.reminderDate = fromCompactDateTime(reminderTime);
89
+ }
90
+ else if (reminderSet === "0") {
91
+ partial.reminderDate = null;
92
+ }
93
+ const bodyEl = findChild(el, "Body");
94
+ const body = bodyEl ? childText(bodyEl, "Data") : undefined;
95
+ if (body !== undefined)
96
+ partial.body = body;
97
+ return partial;
98
+ }
99
+ }
100
+ //# sourceMappingURL=TasksSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TasksSyncAdapter.js","sourceRoot":"","sources":["../../../src/adapters/TasksSyncAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import { LabelMongo } from "@rapidmx/restapi/mongo";
6
+ import { EmailSyncAdapter } from "../EmailSyncAdapter.js";
7
+ /**
8
+ * @author Jean-Philippe Steinmetz
9
+ */
10
+ export class EmailSyncAdapterMongo extends EmailSyncAdapter {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.labelClass = LabelMongo;
14
+ }
15
+ }
16
+ //# sourceMappingURL=EmailSyncAdapterMongo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailSyncAdapterMongo.js","sourceRoot":"","sources":["../../../../src/adapters/mongo/EmailSyncAdapterMongo.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,gBAAgB;IAA3D;;QACc,eAAU,GAAQ,UAAU,CAAC;IAC3C,CAAC;CAAA"}
@@ -0,0 +1,6 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ export * from "./EmailSyncAdapterMongo.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapters/mongo/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,16 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import { LabelSQL } from "@rapidmx/restapi/sql";
6
+ import { EmailSyncAdapter } from "../EmailSyncAdapter.js";
7
+ /**
8
+ * @author Jean-Philippe Steinmetz
9
+ */
10
+ export class EmailSyncAdapterSQL extends EmailSyncAdapter {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.labelClass = LabelSQL;
14
+ }
15
+ }
16
+ //# sourceMappingURL=EmailSyncAdapterSQL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailSyncAdapterSQL.js","sourceRoot":"","sources":["../../../../src/adapters/sql/EmailSyncAdapterSQL.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,gBAAgB;IAAzD;;QACc,eAAU,GAAQ,QAAQ,CAAC;IACzC,CAAC;CAAA"}
@@ -0,0 +1,6 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ export * from "./EmailSyncAdapterSQL.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapters/sql/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,cAAc,0BAA0B,CAAC"}