@rapidmx/activesync 1.0.0-beta.0

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 (195) 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 +230 -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/codec/WbxmlCodePages.js +706 -0
  24. package/dist/lib/codec/WbxmlCodePages.js.map +1 -0
  25. package/dist/lib/codec/WbxmlDecoder.js +154 -0
  26. package/dist/lib/codec/WbxmlDecoder.js.map +1 -0
  27. package/dist/lib/codec/WbxmlElement.js +31 -0
  28. package/dist/lib/codec/WbxmlElement.js.map +1 -0
  29. package/dist/lib/codec/WbxmlEncoder.js +88 -0
  30. package/dist/lib/codec/WbxmlEncoder.js.map +1 -0
  31. package/dist/lib/commands/ComposeMailCommand.js +187 -0
  32. package/dist/lib/commands/ComposeMailCommand.js.map +1 -0
  33. package/dist/lib/commands/FolderSyncCommand.js +150 -0
  34. package/dist/lib/commands/FolderSyncCommand.js.map +1 -0
  35. package/dist/lib/commands/GetItemEstimateCommand.js +149 -0
  36. package/dist/lib/commands/GetItemEstimateCommand.js.map +1 -0
  37. package/dist/lib/commands/ItemOperationsCommand.js +337 -0
  38. package/dist/lib/commands/ItemOperationsCommand.js.map +1 -0
  39. package/dist/lib/commands/MeetingResponseCommand.js +120 -0
  40. package/dist/lib/commands/MeetingResponseCommand.js.map +1 -0
  41. package/dist/lib/commands/MoveItemsCommand.js +103 -0
  42. package/dist/lib/commands/MoveItemsCommand.js.map +1 -0
  43. package/dist/lib/commands/PingCommand.js +145 -0
  44. package/dist/lib/commands/PingCommand.js.map +1 -0
  45. package/dist/lib/commands/ProvisionCommand.js +164 -0
  46. package/dist/lib/commands/ProvisionCommand.js.map +1 -0
  47. package/dist/lib/commands/ResolveRecipientsCommand.js +124 -0
  48. package/dist/lib/commands/ResolveRecipientsCommand.js.map +1 -0
  49. package/dist/lib/commands/SearchCommand.js +137 -0
  50. package/dist/lib/commands/SearchCommand.js.map +1 -0
  51. package/dist/lib/commands/SendMailCommand.js +18 -0
  52. package/dist/lib/commands/SendMailCommand.js.map +1 -0
  53. package/dist/lib/commands/SettingsCommand.js +138 -0
  54. package/dist/lib/commands/SettingsCommand.js.map +1 -0
  55. package/dist/lib/commands/SmartForwardCommand.js +22 -0
  56. package/dist/lib/commands/SmartForwardCommand.js.map +1 -0
  57. package/dist/lib/commands/SmartReplyCommand.js +22 -0
  58. package/dist/lib/commands/SmartReplyCommand.js.map +1 -0
  59. package/dist/lib/commands/SyncCommand.js +406 -0
  60. package/dist/lib/commands/SyncCommand.js.map +1 -0
  61. package/dist/lib/commands/mongo/FolderSyncCommandMongo.js +16 -0
  62. package/dist/lib/commands/mongo/FolderSyncCommandMongo.js.map +1 -0
  63. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js +21 -0
  64. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js.map +1 -0
  65. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js +18 -0
  66. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js.map +1 -0
  67. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js +17 -0
  68. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js.map +1 -0
  69. package/dist/lib/commands/mongo/MoveItemsCommandMongo.js +17 -0
  70. package/dist/lib/commands/mongo/MoveItemsCommandMongo.js.map +1 -0
  71. package/dist/lib/commands/mongo/ResolveRecipientsCommandMongo.js +20 -0
  72. package/dist/lib/commands/mongo/ResolveRecipientsCommandMongo.js.map +1 -0
  73. package/dist/lib/commands/mongo/SearchCommandMongo.js +20 -0
  74. package/dist/lib/commands/mongo/SearchCommandMongo.js.map +1 -0
  75. package/dist/lib/commands/mongo/SendMailCommandMongo.js +17 -0
  76. package/dist/lib/commands/mongo/SendMailCommandMongo.js.map +1 -0
  77. package/dist/lib/commands/mongo/SettingsCommandMongo.js +16 -0
  78. package/dist/lib/commands/mongo/SettingsCommandMongo.js.map +1 -0
  79. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js +17 -0
  80. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js.map +1 -0
  81. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js +17 -0
  82. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js.map +1 -0
  83. package/dist/lib/commands/mongo/SyncCommandMongo.js +26 -0
  84. package/dist/lib/commands/mongo/SyncCommandMongo.js.map +1 -0
  85. package/dist/lib/commands/mongo/index.js +14 -0
  86. package/dist/lib/commands/mongo/index.js.map +1 -0
  87. package/dist/lib/commands/sql/FolderSyncCommandSQL.js +16 -0
  88. package/dist/lib/commands/sql/FolderSyncCommandSQL.js.map +1 -0
  89. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js +21 -0
  90. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js.map +1 -0
  91. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js +18 -0
  92. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js.map +1 -0
  93. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js +17 -0
  94. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js.map +1 -0
  95. package/dist/lib/commands/sql/MoveItemsCommandSQL.js +17 -0
  96. package/dist/lib/commands/sql/MoveItemsCommandSQL.js.map +1 -0
  97. package/dist/lib/commands/sql/ResolveRecipientsCommandSQL.js +20 -0
  98. package/dist/lib/commands/sql/ResolveRecipientsCommandSQL.js.map +1 -0
  99. package/dist/lib/commands/sql/SearchCommandSQL.js +20 -0
  100. package/dist/lib/commands/sql/SearchCommandSQL.js.map +1 -0
  101. package/dist/lib/commands/sql/SendMailCommandSQL.js +17 -0
  102. package/dist/lib/commands/sql/SendMailCommandSQL.js.map +1 -0
  103. package/dist/lib/commands/sql/SettingsCommandSQL.js +16 -0
  104. package/dist/lib/commands/sql/SettingsCommandSQL.js.map +1 -0
  105. package/dist/lib/commands/sql/SmartForwardCommandSQL.js +17 -0
  106. package/dist/lib/commands/sql/SmartForwardCommandSQL.js.map +1 -0
  107. package/dist/lib/commands/sql/SmartReplyCommandSQL.js +17 -0
  108. package/dist/lib/commands/sql/SmartReplyCommandSQL.js.map +1 -0
  109. package/dist/lib/commands/sql/SyncCommandSQL.js +26 -0
  110. package/dist/lib/commands/sql/SyncCommandSQL.js.map +1 -0
  111. package/dist/lib/commands/sql/index.js +14 -0
  112. package/dist/lib/commands/sql/index.js.map +1 -0
  113. package/dist/lib/index.js +56 -0
  114. package/dist/lib/index.js.map +1 -0
  115. package/dist/lib/mongo/DeviceSyncStateRouteMongo.js +16 -0
  116. package/dist/lib/mongo/DeviceSyncStateRouteMongo.js.map +1 -0
  117. package/dist/lib/mongo/EasRouteMongo.js +51 -0
  118. package/dist/lib/mongo/EasRouteMongo.js.map +1 -0
  119. package/dist/lib/mongo/index.js +8 -0
  120. package/dist/lib/mongo/index.js.map +1 -0
  121. package/dist/lib/mongo.js +6 -0
  122. package/dist/lib/mongo.js.map +1 -0
  123. package/dist/lib/sql/DeviceSyncStateRouteSQL.js +16 -0
  124. package/dist/lib/sql/DeviceSyncStateRouteSQL.js.map +1 -0
  125. package/dist/lib/sql/EasRouteSQL.js +50 -0
  126. package/dist/lib/sql/EasRouteSQL.js.map +1 -0
  127. package/dist/lib/sql/index.js +8 -0
  128. package/dist/lib/sql/index.js.map +1 -0
  129. package/dist/lib/sql.js +6 -0
  130. package/dist/lib/sql.js.map +1 -0
  131. package/dist/types/BaseDeviceSyncStateRoute.d.ts +34 -0
  132. package/dist/types/BaseEasRoute.d.ts +64 -0
  133. package/dist/types/CompactDateTime.d.ts +22 -0
  134. package/dist/types/EasCommandHandler.d.ts +59 -0
  135. package/dist/types/EasSyncKeyUtils.d.ts +89 -0
  136. package/dist/types/adapters/CalendarSyncAdapter.d.ts +52 -0
  137. package/dist/types/adapters/ContactsSyncAdapter.d.ts +33 -0
  138. package/dist/types/adapters/EasCollectionSyncAdapter.d.ts +52 -0
  139. package/dist/types/adapters/EmailSyncAdapter.d.ts +53 -0
  140. package/dist/types/adapters/TasksSyncAdapter.d.ts +32 -0
  141. package/dist/types/codec/WbxmlCodePages.d.ts +45 -0
  142. package/dist/types/codec/WbxmlDecoder.d.ts +33 -0
  143. package/dist/types/codec/WbxmlElement.d.ts +43 -0
  144. package/dist/types/codec/WbxmlEncoder.d.ts +20 -0
  145. package/dist/types/commands/ComposeMailCommand.d.ts +50 -0
  146. package/dist/types/commands/FolderSyncCommand.d.ts +25 -0
  147. package/dist/types/commands/GetItemEstimateCommand.d.ts +43 -0
  148. package/dist/types/commands/ItemOperationsCommand.d.ts +72 -0
  149. package/dist/types/commands/MeetingResponseCommand.d.ts +32 -0
  150. package/dist/types/commands/MoveItemsCommand.d.ts +29 -0
  151. package/dist/types/commands/PingCommand.d.ts +33 -0
  152. package/dist/types/commands/ProvisionCommand.d.ts +54 -0
  153. package/dist/types/commands/ResolveRecipientsCommand.d.ts +34 -0
  154. package/dist/types/commands/SearchCommand.d.ts +39 -0
  155. package/dist/types/commands/SendMailCommand.d.ts +10 -0
  156. package/dist/types/commands/SettingsCommand.d.ts +37 -0
  157. package/dist/types/commands/SmartForwardCommand.d.ts +17 -0
  158. package/dist/types/commands/SmartReplyCommand.d.ts +17 -0
  159. package/dist/types/commands/SyncCommand.d.ts +100 -0
  160. package/dist/types/commands/mongo/FolderSyncCommandMongo.d.ts +8 -0
  161. package/dist/types/commands/mongo/GetItemEstimateCommandMongo.d.ts +7 -0
  162. package/dist/types/commands/mongo/ItemOperationsCommandMongo.d.ts +9 -0
  163. package/dist/types/commands/mongo/MeetingResponseCommandMongo.d.ts +8 -0
  164. package/dist/types/commands/mongo/MoveItemsCommandMongo.d.ts +8 -0
  165. package/dist/types/commands/mongo/ResolveRecipientsCommandMongo.d.ts +8 -0
  166. package/dist/types/commands/mongo/SearchCommandMongo.d.ts +8 -0
  167. package/dist/types/commands/mongo/SendMailCommandMongo.d.ts +8 -0
  168. package/dist/types/commands/mongo/SettingsCommandMongo.d.ts +7 -0
  169. package/dist/types/commands/mongo/SmartForwardCommandMongo.d.ts +8 -0
  170. package/dist/types/commands/mongo/SmartReplyCommandMongo.d.ts +8 -0
  171. package/dist/types/commands/mongo/SyncCommandMongo.d.ts +8 -0
  172. package/dist/types/commands/mongo/index.d.ts +9 -0
  173. package/dist/types/commands/sql/FolderSyncCommandSQL.d.ts +8 -0
  174. package/dist/types/commands/sql/GetItemEstimateCommandSQL.d.ts +7 -0
  175. package/dist/types/commands/sql/ItemOperationsCommandSQL.d.ts +9 -0
  176. package/dist/types/commands/sql/MeetingResponseCommandSQL.d.ts +8 -0
  177. package/dist/types/commands/sql/MoveItemsCommandSQL.d.ts +8 -0
  178. package/dist/types/commands/sql/ResolveRecipientsCommandSQL.d.ts +8 -0
  179. package/dist/types/commands/sql/SearchCommandSQL.d.ts +8 -0
  180. package/dist/types/commands/sql/SendMailCommandSQL.d.ts +8 -0
  181. package/dist/types/commands/sql/SettingsCommandSQL.d.ts +7 -0
  182. package/dist/types/commands/sql/SmartForwardCommandSQL.d.ts +8 -0
  183. package/dist/types/commands/sql/SmartReplyCommandSQL.d.ts +8 -0
  184. package/dist/types/commands/sql/SyncCommandSQL.d.ts +8 -0
  185. package/dist/types/commands/sql/index.d.ts +9 -0
  186. package/dist/types/index.d.ts +51 -0
  187. package/dist/types/mongo/DeviceSyncStateRouteMongo.d.ts +8 -0
  188. package/dist/types/mongo/EasRouteMongo.d.ts +14 -0
  189. package/dist/types/mongo/index.d.ts +3 -0
  190. package/dist/types/mongo.d.ts +1 -0
  191. package/dist/types/sql/DeviceSyncStateRouteSQL.d.ts +8 -0
  192. package/dist/types/sql/EasRouteSQL.d.ts +13 -0
  193. package/dist/types/sql/index.d.ts +3 -0
  194. package/dist/types/sql.d.ts +1 -0
  195. package/package.json +94 -0
@@ -0,0 +1,255 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import * as crypto from "crypto";
6
+ import { WbxmlCodePage } from "../codec/WbxmlCodePages.js";
7
+ import { childText, element, findChild, textElement } from "../codec/WbxmlElement.js";
8
+ import { fromCompactDateTime, toCompactDateTime } from "../CompactDateTime.js";
9
+ import { AttendeeResponseStatus, AttendeeRole, BusyStatus, RecurrenceFrequency, RecipientType, } from "@rapidmx/restapi";
10
+ /** Builds the reverse of a forward code-table once at module load, rather than re-deriving it per call. */
11
+ function invert(table) {
12
+ return Object.fromEntries(Object.entries(table).map(([k, v]) => [v, k]));
13
+ }
14
+ /** MS-ASCAL `BusyStatus`: 0=Free, 1=Tentative, 2=Busy, 3=Out of Office. Confirmed against the published
15
+ * MS-ASCAL spec, not assumed - note the value order does not match this library's own `BusyStatus` enum
16
+ * declaration order, so an identity/positional mapping would have been silently wrong. */
17
+ const BUSY_STATUS_CODES = {
18
+ [BusyStatus.FREE]: "0",
19
+ [BusyStatus.TENTATIVE]: "1",
20
+ [BusyStatus.BUSY]: "2",
21
+ [BusyStatus.OUT_OF_OFFICE]: "3",
22
+ };
23
+ /** MS-ASCAL `AttendeeStatus`: 0=Response unknown, 2=Tentative, 3=Accept, 4=Decline, 5=Not responded. This
24
+ * library's own `AttendeeResponseStatus.NEEDS_ACTION` maps to 0 (unknown) rather than 5 (not responded) - both
25
+ * are defensible for "no response yet", and 0 is the spec's own documented fallback/default value. */
26
+ const ATTENDEE_STATUS_CODES = {
27
+ [AttendeeResponseStatus.NEEDS_ACTION]: "0",
28
+ [AttendeeResponseStatus.TENTATIVE]: "2",
29
+ [AttendeeResponseStatus.ACCEPTED]: "3",
30
+ [AttendeeResponseStatus.DECLINED]: "4",
31
+ };
32
+ /** MS-ASCAL `AttendeeType`: 1=Required, 2=Optional, 3=Resource. */
33
+ const ATTENDEE_TYPE_CODES = {
34
+ [AttendeeRole.REQUIRED]: "1",
35
+ [AttendeeRole.OPTIONAL]: "2",
36
+ [AttendeeRole.RESOURCE]: "3",
37
+ };
38
+ /** MS-ASCAL `Recurrence.Type`: 0=Daily, 1=Weekly, 2=Monthly, 5=Yearly (3="monthly on the nth day" and
39
+ * 6="yearly on the nth day" - patterns keyed by an ordinal weekday, e.g. "the 2nd Tuesday" - are a documented,
40
+ * out-of-scope gap for this pragmatic subset; `RecurrenceRule` has no ordinal-weekday field to source them
41
+ * from anyway, only plain day-of-month/day-of-week lists). */
42
+ const RECURRENCE_TYPE_CODES = {
43
+ [RecurrenceFrequency.DAILY]: "0",
44
+ [RecurrenceFrequency.WEEKLY]: "1",
45
+ [RecurrenceFrequency.MONTHLY]: "2",
46
+ [RecurrenceFrequency.YEARLY]: "5",
47
+ };
48
+ /** MS-ASCAL `DayOfWeek` bitmask: Sunday=1, Monday=2, Tuesday=4, Wednesday=8, Thursday=16, Friday=32,
49
+ * Saturday=64 - summed when a recurrence applies to more than one day. `RecurrenceRule.byDay` uses RFC 5545's
50
+ * two-letter day codes. */
51
+ const DAY_OF_WEEK_BITS = { SU: 1, MO: 2, TU: 4, WE: 8, TH: 16, FR: 32, SA: 64 };
52
+ const BUSY_STATUS_FROM_CODE = invert(BUSY_STATUS_CODES);
53
+ const ATTENDEE_STATUS_FROM_CODE = invert(ATTENDEE_STATUS_CODES);
54
+ const ATTENDEE_TYPE_FROM_CODE = invert(ATTENDEE_TYPE_CODES);
55
+ const RECURRENCE_FREQUENCY_FROM_CODE = invert(RECURRENCE_TYPE_CODES);
56
+ /**
57
+ * Maps `CalendarEvent` to/from the EAS `Sync` `Calendar` collection class (MS-ASCAL).
58
+ *
59
+ * **Pragmatic subset, deliberately not the full MS-ASCAL semantics**:
60
+ * - `TimeZone` is not emitted - the real element is a base64-encoded binary Win32 `TIME_ZONE_INFORMATION`
61
+ * structure, not a plain IANA string; `CalendarEvent.timezone` (an IANA identifier) can't be losslessly
62
+ * re-encoded into that format without a full IANA-to-Windows zone mapping table, and a real device would
63
+ * rather see no `TimeZone` element (falling back to its own default) than a malformed one.
64
+ * - `Sensitivity` is always reported `0` (Normal) - this library's `CalendarEvent` has no privacy dimension of
65
+ * its own to source a real value from.
66
+ * - Recurrence patterns keyed by an ordinal weekday (MS-ASCAL `Type` 3/6, e.g. "the 2nd Tuesday of the month")
67
+ * are not emitted - see `RECURRENCE_TYPE_CODES`'s own doc comment.
68
+ * - Recurrence exceptions (individually modified/cancelled occurrences of a recurring series) are not synced -
69
+ * deferred, matching this library's "pragmatic subset" precedent elsewhere (e.g. `FolderSyncCommand`'s SyncKey
70
+ * replay-protection gap).
71
+ *
72
+ * @author Jean-Philippe Steinmetz
73
+ */
74
+ export class CalendarSyncAdapter {
75
+ constructor() {
76
+ this.collectionClass = "Calendar";
77
+ }
78
+ toApplicationData(event) {
79
+ const hasAttendees = event.attendees.length > 0;
80
+ return element(WbxmlCodePage.AirSync, "ApplicationData", [
81
+ textElement(WbxmlCodePage.Calendar, "Subject", event.title),
82
+ ...(event.location ? [textElement(WbxmlCodePage.Calendar, "Location", event.location)] : []),
83
+ textElement(WbxmlCodePage.Calendar, "StartTime", toCompactDateTime(event.startDate)),
84
+ textElement(WbxmlCodePage.Calendar, "EndTime", toCompactDateTime(event.endDate)),
85
+ textElement(WbxmlCodePage.Calendar, "AllDayEvent", event.allDay ? "1" : "0"),
86
+ textElement(WbxmlCodePage.Calendar, "DtStamp", toCompactDateTime(event.dateModified)),
87
+ textElement(WbxmlCodePage.Calendar, "BusyStatus", BUSY_STATUS_CODES[event.busyStatus]),
88
+ textElement(WbxmlCodePage.Calendar, "Sensitivity", "0"),
89
+ textElement(WbxmlCodePage.Calendar, "MeetingStatus", hasAttendees ? "1" : "0"),
90
+ textElement(WbxmlCodePage.Calendar, "OrganizerEmail", event.organizer.address),
91
+ ...(event.organizer.displayName
92
+ ? [textElement(WbxmlCodePage.Calendar, "OrganizerName", event.organizer.displayName)]
93
+ : []),
94
+ ...(hasAttendees
95
+ ? [
96
+ element(WbxmlCodePage.Calendar, "Attendees", event.attendees.map((attendee) => element(WbxmlCodePage.Calendar, "Attendee", [
97
+ textElement(WbxmlCodePage.Calendar, "Email", attendee.address),
98
+ ...(attendee.displayName
99
+ ? [textElement(WbxmlCodePage.Calendar, "Name", attendee.displayName)]
100
+ : []),
101
+ textElement(WbxmlCodePage.Calendar, "AttendeeType", ATTENDEE_TYPE_CODES[attendee.role]),
102
+ textElement(WbxmlCodePage.Calendar, "AttendeeStatus", ATTENDEE_STATUS_CODES[attendee.responseStatus]),
103
+ ]))),
104
+ ]
105
+ : []),
106
+ // `!= null` (not `!== undefined`) deliberately - TypeORM hydrates an unset nullable SQL column as
107
+ // `null`, not `undefined` (confirmed by a real test failure against the SQL backend: `undefined`
108
+ // survives a Mongo round-trip for a genuinely-absent field, but SQL hands back `null` instead, and
109
+ // a strict `!== undefined` check would then wrongly treat that "absent" value as present).
110
+ ...(event.reminderMinutesBeforeStart != null
111
+ ? [textElement(WbxmlCodePage.Calendar, "Reminder", String(event.reminderMinutesBeforeStart))]
112
+ : []),
113
+ ...(event.recurrenceRule ? [this.recurrenceElement(event.recurrenceRule, event.startDate)] : []),
114
+ ]);
115
+ }
116
+ recurrenceElement(rule, startDate) {
117
+ const dayOfWeekBits = (rule.byDay ?? []).reduce((sum, day) => sum + (DAY_OF_WEEK_BITS[day] ?? 0), 0);
118
+ return element(WbxmlCodePage.Calendar, "Recurrence", [
119
+ textElement(WbxmlCodePage.Calendar, "Type", RECURRENCE_TYPE_CODES[rule.freq]),
120
+ textElement(WbxmlCodePage.Calendar, "Interval", String(rule.interval)),
121
+ ...(rule.freq === RecurrenceFrequency.WEEKLY && dayOfWeekBits > 0
122
+ ? [textElement(WbxmlCodePage.Calendar, "DayOfWeek", String(dayOfWeekBits))]
123
+ : []),
124
+ ...(rule.freq === RecurrenceFrequency.MONTHLY || rule.freq === RecurrenceFrequency.YEARLY
125
+ ? [textElement(WbxmlCodePage.Calendar, "DayOfMonth", String(rule.byMonthDay?.[0] ?? startDate.getUTCDate()))]
126
+ : []),
127
+ ...(rule.freq === RecurrenceFrequency.YEARLY
128
+ ? [textElement(WbxmlCodePage.Calendar, "MonthOfYear", String(rule.byMonth?.[0] ?? startDate.getUTCMonth() + 1))]
129
+ : []),
130
+ ...(rule.until ? [textElement(WbxmlCodePage.Calendar, "Until", toCompactDateTime(rule.until))] : []),
131
+ // See the identical `!= null` reasoning on `reminderMinutesBeforeStart` above.
132
+ ...(rule.count != null ? [textElement(WbxmlCodePage.Calendar, "Occurrences", String(rule.count))] : []),
133
+ ]);
134
+ }
135
+ /**
136
+ * Reverse of `toApplicationData`. `timezone`/`status`/`sequence`/`icalUid` have no wire representation at
137
+ * all (see this class's own "pragmatic subset" doc comment for `timezone`; the other three are purely
138
+ * server-managed identifiers/state a client was never sent in the first place) and are never included in
139
+ * the returned partial - `newEntityDefaults()` below supplies `icalUid`/`sequence` for a brand new event
140
+ * (`status`/`timezone` are left at the model's own constructor defaults), and `applyChange` leaves all four
141
+ * untouched by construction (merging onto `existing`).
142
+ *
143
+ * `OrganizerEmail` is required for a new event (there is nowhere else to default it from - this adapter
144
+ * has no mailbox context of its own) - a real calendar client always sends it regardless, since it already
145
+ * knows its own account's address. Omitting it on an `Add` throws, which `SyncCommand.applyAdd` turns into
146
+ * Status `6` ("client has sent a malformed or invalid item"), the spec's own designated code for exactly
147
+ * this case.
148
+ *
149
+ * `Attendees`/`Recurrence` are ghosted as a whole element, like `ContactsSyncAdapter`'s arrays: present at
150
+ * all -> rebuilt entirely from what's there; absent -> left untouched on a `Change`.
151
+ */
152
+ fromApplicationData(el) {
153
+ const partial = {};
154
+ const subject = childText(el, "Subject");
155
+ if (subject !== undefined)
156
+ partial.title = subject;
157
+ const location = childText(el, "Location");
158
+ if (location !== undefined)
159
+ partial.location = location;
160
+ const startTime = childText(el, "StartTime");
161
+ if (startTime !== undefined)
162
+ partial.startDate = fromCompactDateTime(startTime);
163
+ const endTime = childText(el, "EndTime");
164
+ if (endTime !== undefined)
165
+ partial.endDate = fromCompactDateTime(endTime);
166
+ const allDayEvent = childText(el, "AllDayEvent");
167
+ if (allDayEvent !== undefined)
168
+ partial.allDay = allDayEvent === "1";
169
+ const busyStatus = childText(el, "BusyStatus");
170
+ if (busyStatus !== undefined) {
171
+ const mapped = BUSY_STATUS_FROM_CODE[busyStatus];
172
+ if (!mapped) {
173
+ throw new Error(`Unrecognized BusyStatus value: '${busyStatus}'`);
174
+ }
175
+ partial.busyStatus = mapped;
176
+ }
177
+ const organizerEmail = childText(el, "OrganizerEmail");
178
+ if (organizerEmail !== undefined) {
179
+ partial.organizer = {
180
+ address: organizerEmail,
181
+ displayName: childText(el, "OrganizerName"),
182
+ type: RecipientType.TO,
183
+ };
184
+ }
185
+ const reminder = childText(el, "Reminder");
186
+ if (reminder !== undefined)
187
+ partial.reminderMinutesBeforeStart = Number(reminder);
188
+ const attendeesEl = findChild(el, "Attendees");
189
+ if (attendeesEl) {
190
+ partial.attendees = attendeesEl.children
191
+ .filter((child) => child.tag === "Attendee")
192
+ .map((attendeeEl) => this.attendeeFromElement(attendeeEl));
193
+ }
194
+ const recurrenceEl = findChild(el, "Recurrence");
195
+ if (recurrenceEl) {
196
+ partial.recurrenceRule = this.recurrenceRuleFromElement(recurrenceEl);
197
+ }
198
+ return partial;
199
+ }
200
+ /** `icalUid`/`sequence` have no wire representation on `Add` (see `fromApplicationData`'s own doc comment)
201
+ * - without this, every Sync-created event would fall back to `CalendarEventMongo`/`CalendarEventSQL`'s own
202
+ * constructor default of `icalUid: ""`, violating RFC 5545's uniqueness expectation for `UID`. Mirrors
203
+ * MAPI's identical `RopSaveChangesMessageHandler` pattern (`${crypto.randomUUID()}@mapi`), `@eas` suffix
204
+ * instead. */
205
+ newEntityDefaults() {
206
+ return { icalUid: `${crypto.randomUUID()}@eas`, sequence: 0 };
207
+ }
208
+ attendeeFromElement(el) {
209
+ const address = childText(el, "Email");
210
+ if (!address) {
211
+ throw new Error("Attendee element is missing its required Email child.");
212
+ }
213
+ const attendeeType = childText(el, "AttendeeType");
214
+ const attendeeStatus = childText(el, "AttendeeStatus");
215
+ return {
216
+ address,
217
+ displayName: childText(el, "Name"),
218
+ role: (attendeeType && ATTENDEE_TYPE_FROM_CODE[attendeeType]) || AttendeeRole.REQUIRED,
219
+ responseStatus: (attendeeStatus && ATTENDEE_STATUS_FROM_CODE[attendeeStatus]) || AttendeeResponseStatus.NEEDS_ACTION,
220
+ isOrganizer: false,
221
+ };
222
+ }
223
+ recurrenceRuleFromElement(el) {
224
+ const type = childText(el, "Type");
225
+ const freq = type && RECURRENCE_FREQUENCY_FROM_CODE[type];
226
+ if (!freq) {
227
+ throw new Error(`Unrecognized or unsupported Recurrence Type value: '${type}'`);
228
+ }
229
+ const interval = childText(el, "Interval");
230
+ const dayOfWeek = childText(el, "DayOfWeek");
231
+ const dayOfMonth = childText(el, "DayOfMonth");
232
+ const monthOfYear = childText(el, "MonthOfYear");
233
+ const until = childText(el, "Until");
234
+ const occurrences = childText(el, "Occurrences");
235
+ const byDay = [];
236
+ if (dayOfWeek !== undefined) {
237
+ const bits = Number(dayOfWeek);
238
+ for (const [code, bit] of Object.entries(DAY_OF_WEEK_BITS)) {
239
+ if ((bits & bit) !== 0)
240
+ byDay.push(code);
241
+ }
242
+ }
243
+ return {
244
+ freq,
245
+ interval: interval !== undefined ? Number(interval) : 1,
246
+ ...(byDay.length > 0 ? { byDay } : {}),
247
+ ...(dayOfMonth !== undefined ? { byMonthDay: [Number(dayOfMonth)] } : {}),
248
+ ...(monthOfYear !== undefined ? { byMonth: [Number(monthOfYear)] } : {}),
249
+ ...(until !== undefined ? { until: fromCompactDateTime(until) } : {}),
250
+ ...(occurrences !== undefined ? { count: Number(occurrences) } : {}),
251
+ exceptions: [],
252
+ };
253
+ }
254
+ }
255
+ //# sourceMappingURL=CalendarSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarSyncAdapter.js","sourceRoot":"","sources":["../../../src/adapters/CalendarSyncAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
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, findChildren, textElement } from "../codec/WbxmlElement.js";
7
+ import { ContactAddressKind } from "@rapidmx/restapi";
8
+ /** MS-ASCMD only has three positional email slots (`Email1Address`/`Email2Address`/`Email3Address`) - unlike
9
+ * `ContactEmail.type`, EAS doesn't distinguish a "kind" per address, only position. Extra addresses beyond the
10
+ * third are dropped, matching this library's "pragmatic subset" precedent elsewhere. */
11
+ const EMAIL_TAGS = ["Email1Address", "Email2Address", "Email3Address"];
12
+ /** MS-ASCONTACTS street/city/state/postalCode/country tag prefixes, keyed by `ContactAddressKind`. There is no
13
+ * generic "OtherPhoneNumber"-equivalent tag family gap here (Home/Business/Other all exist for addresses,
14
+ * unlike phone numbers below), so all three kinds round-trip. */
15
+ const ADDRESS_PREFIX = {
16
+ [ContactAddressKind.HOME]: "Home",
17
+ [ContactAddressKind.WORK]: "Business",
18
+ [ContactAddressKind.OTHER]: "Other",
19
+ };
20
+ /** MS-ASCONTACTS has no `OtherPhoneNumber`-equivalent tag - only Home/Business phone numbers exist as plain
21
+ * single-value tags (plus several Home2/Business2/Car/Radio/Pager/Fax variants this pragmatic subset doesn't
22
+ * use). A phone tagged `OTHER` in this library's model has nowhere to go and is dropped, documented here rather
23
+ * than silently - matching `FolderSyncCommand`'s own precedent for this kind of unavoidable field-count gap. */
24
+ const PHONE_TAG = {
25
+ [ContactAddressKind.HOME]: "HomePhoneNumber",
26
+ [ContactAddressKind.WORK]: "BusinessPhoneNumber",
27
+ };
28
+ /**
29
+ * Maps `Contact` to/from the EAS `Sync` `Contacts` collection class (MS-ASCONTACTS/MS-ASCNTC2). Contacts are
30
+ * also this library's GAL source (see the architecture note on `Contact` itself), but that's `SearchCommand`'s
31
+ * concern, not this adapter's.
32
+ *
33
+ * @author Jean-Philippe Steinmetz
34
+ */
35
+ export class ContactsSyncAdapter {
36
+ constructor() {
37
+ this.collectionClass = "Contacts";
38
+ }
39
+ toApplicationData(contact) {
40
+ const children = [
41
+ textElement(WbxmlCodePage.Contacts, "FileAs", contact.displayName),
42
+ ...(contact.givenName ? [textElement(WbxmlCodePage.Contacts, "FirstName", contact.givenName)] : []),
43
+ ...(contact.surname ? [textElement(WbxmlCodePage.Contacts, "LastName", contact.surname)] : []),
44
+ ...(contact.company ? [textElement(WbxmlCodePage.Contacts, "CompanyName", contact.company)] : []),
45
+ ...(contact.jobTitle ? [textElement(WbxmlCodePage.Contacts, "JobTitle", contact.jobTitle)] : []),
46
+ ];
47
+ contact.emails.slice(0, EMAIL_TAGS.length).forEach((email, i) => {
48
+ children.push(textElement(WbxmlCodePage.Contacts, EMAIL_TAGS[i], email.address));
49
+ });
50
+ for (const phone of contact.phones) {
51
+ const tag = PHONE_TAG[phone.type];
52
+ if (tag) {
53
+ children.push(textElement(WbxmlCodePage.Contacts, tag, phone.phoneNumber));
54
+ }
55
+ }
56
+ for (const address of contact.addresses) {
57
+ children.push(...this.addressElements(address));
58
+ }
59
+ if (contact.notes) {
60
+ children.push(element(WbxmlCodePage.AirSyncBase, "Body", [
61
+ textElement(WbxmlCodePage.AirSyncBase, "Type", "1"),
62
+ textElement(WbxmlCodePage.AirSyncBase, "EstimatedDataSize", String(Buffer.byteLength(contact.notes, "utf8"))),
63
+ textElement(WbxmlCodePage.AirSyncBase, "Data", contact.notes),
64
+ ]));
65
+ }
66
+ if (contact.categories && contact.categories.length > 0) {
67
+ children.push(element(WbxmlCodePage.Contacts, "Categories", contact.categories.map((category) => textElement(WbxmlCodePage.Contacts, "Category", category))));
68
+ }
69
+ return element(WbxmlCodePage.AirSync, "ApplicationData", children);
70
+ }
71
+ addressElements(address) {
72
+ const prefix = ADDRESS_PREFIX[address.type];
73
+ const parts = [
74
+ [`${prefix}Street`, address.street],
75
+ [`${prefix}City`, address.city],
76
+ [`${prefix}State`, address.state],
77
+ [`${prefix}PostalCode`, address.postalCode],
78
+ [`${prefix}Country`, address.country],
79
+ ];
80
+ return parts
81
+ .filter((part) => part[1] !== undefined)
82
+ .map(([tag, value]) => textElement(WbxmlCodePage.Contacts, tag, value));
83
+ }
84
+ /**
85
+ * Reverse of `toApplicationData`. Scalar fields (`FileAs`/`FirstName`/.../`JobTitle`, and the `Body`
86
+ * `notes`) are properly ghosted - a field's own tag missing from `el` leaves that `Contact` field
87
+ * untouched. `emails`/`phones`/`addresses` are ghosted only as a **whole group**, not per slot: if *none*
88
+ * of a group's tags are present the group is left untouched, but if *any* one is, the entire group is
89
+ * rebuilt from just what's present in `el` (a real client's own Contacts edit UI typically resends every
90
+ * field it manages anyway, so this only under-preserves data for a client that deliberately sends a
91
+ * single-slot partial update within one of these groups - a documented simplification, not silent data
92
+ * loss for the common case). Emails lose their original `type` on any round trip through a `Change`
93
+ * (rebuilt as `ContactAddressKind.OTHER`) since EAS's own `Email1/2/3Address` tags carry no kind at all,
94
+ * matching `toApplicationData`'s own already-documented encode-side loss of the same information.
95
+ * `categories` is ghosted as its own whole group (same rule as `emails`/`phones`/`addresses`): an absent
96
+ * `Categories` element leaves `Contact.categories` untouched, while a present one - even `<Categories/>`
97
+ * with no `Category` children - rebuilds it from scratch (an empty array clears it).
98
+ */
99
+ fromApplicationData(el) {
100
+ const partial = {};
101
+ const fileAs = childText(el, "FileAs");
102
+ if (fileAs !== undefined)
103
+ partial.displayName = fileAs;
104
+ const firstName = childText(el, "FirstName");
105
+ if (firstName !== undefined)
106
+ partial.givenName = firstName;
107
+ const lastName = childText(el, "LastName");
108
+ if (lastName !== undefined)
109
+ partial.surname = lastName;
110
+ const companyName = childText(el, "CompanyName");
111
+ if (companyName !== undefined)
112
+ partial.company = companyName;
113
+ const jobTitle = childText(el, "JobTitle");
114
+ if (jobTitle !== undefined)
115
+ partial.jobTitle = jobTitle;
116
+ if (EMAIL_TAGS.some((tag) => findChild(el, tag))) {
117
+ partial.emails = EMAIL_TAGS.map((tag) => childText(el, tag))
118
+ .filter((address) => !!address)
119
+ .map((address) => ({ address, type: ContactAddressKind.OTHER }));
120
+ }
121
+ const phoneEntries = Object.entries(PHONE_TAG);
122
+ if (phoneEntries.some(([, tag]) => findChild(el, tag))) {
123
+ partial.phones = phoneEntries
124
+ .map(([type, tag]) => ({ type, phoneNumber: childText(el, tag) }))
125
+ .filter((phone) => !!phone.phoneNumber);
126
+ }
127
+ const addressKinds = Object.values(ContactAddressKind);
128
+ const touchedKinds = addressKinds.filter((kind) => this.addressTags(kind).some((tag) => findChild(el, tag)));
129
+ if (touchedKinds.length > 0) {
130
+ partial.addresses = touchedKinds
131
+ .map((kind) => this.parseAddress(el, kind))
132
+ .filter((address) => address !== undefined);
133
+ }
134
+ const bodyEl = findChild(el, "Body");
135
+ const notes = bodyEl ? childText(bodyEl, "Data") : undefined;
136
+ if (notes !== undefined)
137
+ partial.notes = notes;
138
+ const categoriesEl = findChild(el, "Categories");
139
+ if (categoriesEl) {
140
+ partial.categories = findChildren(categoriesEl, "Category")
141
+ .map((category) => category.text)
142
+ .filter((category) => !!category);
143
+ }
144
+ return partial;
145
+ }
146
+ addressTags(kind) {
147
+ const prefix = ADDRESS_PREFIX[kind];
148
+ return [`${prefix}Street`, `${prefix}City`, `${prefix}State`, `${prefix}PostalCode`, `${prefix}Country`];
149
+ }
150
+ parseAddress(el, kind) {
151
+ const prefix = ADDRESS_PREFIX[kind];
152
+ const address = {
153
+ type: kind,
154
+ street: childText(el, `${prefix}Street`),
155
+ city: childText(el, `${prefix}City`),
156
+ state: childText(el, `${prefix}State`),
157
+ postalCode: childText(el, `${prefix}PostalCode`),
158
+ country: childText(el, `${prefix}Country`),
159
+ };
160
+ const hasAnyField = address.street || address.city || address.state || address.postalCode || address.country;
161
+ return hasAnyField ? address : undefined;
162
+ }
163
+ }
164
+ //# sourceMappingURL=ContactsSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContactsSyncAdapter.js","sourceRoot":"","sources":["../../../src/adapters/ContactsSyncAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=EasCollectionSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EasCollectionSyncAdapter.js","sourceRoot":"","sources":["../../../src/adapters/EasCollectionSyncAdapter.ts"],"names":[],"mappings":""}