@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,706 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /**
6
+ * WBXML code page index -> namespace name, per MS-ASWBXML §2.1.2.1 ("List of Code Pages"). A code page is
7
+ * WBXML's mechanism for reusing the single-byte tag-token space across many XML namespaces: a `SWITCH_PAGE`
8
+ * global token changes which of these tables subsequent tag bytes are looked up against.
9
+ *
10
+ * @author Jean-Philippe Steinmetz
11
+ */
12
+ export var WbxmlCodePage;
13
+ (function (WbxmlCodePage) {
14
+ WbxmlCodePage[WbxmlCodePage["AirSync"] = 0] = "AirSync";
15
+ WbxmlCodePage[WbxmlCodePage["Contacts"] = 1] = "Contacts";
16
+ WbxmlCodePage[WbxmlCodePage["Email"] = 2] = "Email";
17
+ WbxmlCodePage[WbxmlCodePage["AirNotification"] = 3] = "AirNotification";
18
+ WbxmlCodePage[WbxmlCodePage["Calendar"] = 4] = "Calendar";
19
+ WbxmlCodePage[WbxmlCodePage["Move"] = 5] = "Move";
20
+ WbxmlCodePage[WbxmlCodePage["ItemEstimate"] = 6] = "ItemEstimate";
21
+ WbxmlCodePage[WbxmlCodePage["FolderHierarchy"] = 7] = "FolderHierarchy";
22
+ WbxmlCodePage[WbxmlCodePage["MeetingResponse"] = 8] = "MeetingResponse";
23
+ WbxmlCodePage[WbxmlCodePage["Tasks"] = 9] = "Tasks";
24
+ WbxmlCodePage[WbxmlCodePage["ResolveRecipients"] = 10] = "ResolveRecipients";
25
+ WbxmlCodePage[WbxmlCodePage["ValidateCert"] = 11] = "ValidateCert";
26
+ WbxmlCodePage[WbxmlCodePage["Contacts2"] = 12] = "Contacts2";
27
+ WbxmlCodePage[WbxmlCodePage["Ping"] = 13] = "Ping";
28
+ WbxmlCodePage[WbxmlCodePage["Provision"] = 14] = "Provision";
29
+ WbxmlCodePage[WbxmlCodePage["Search"] = 15] = "Search";
30
+ WbxmlCodePage[WbxmlCodePage["Gal"] = 16] = "Gal";
31
+ WbxmlCodePage[WbxmlCodePage["AirSyncBase"] = 17] = "AirSyncBase";
32
+ WbxmlCodePage[WbxmlCodePage["Settings"] = 18] = "Settings";
33
+ WbxmlCodePage[WbxmlCodePage["DocumentLibrary"] = 19] = "DocumentLibrary";
34
+ WbxmlCodePage[WbxmlCodePage["ItemOperations"] = 20] = "ItemOperations";
35
+ WbxmlCodePage[WbxmlCodePage["ComposeMail"] = 21] = "ComposeMail";
36
+ WbxmlCodePage[WbxmlCodePage["Email2"] = 22] = "Email2";
37
+ WbxmlCodePage[WbxmlCodePage["Notes"] = 23] = "Notes";
38
+ WbxmlCodePage[WbxmlCodePage["RightsManagement"] = 24] = "RightsManagement";
39
+ WbxmlCodePage[WbxmlCodePage["Find"] = 25] = "Find";
40
+ })(WbxmlCodePage || (WbxmlCodePage = {}));
41
+ /**
42
+ * Tag name -> token (byte, before the content/attribute flag bits are applied) tables, one per code page
43
+ * actually touched by this library's pragmatic command subset (`Provision`/`FolderSync`/`Sync`/`SendMail`/
44
+ * `SmartForward`/`SmartReply`/`ItemOperations`/`Ping`/`Search`/`MeetingResponse`/`Settings`/`GetItemEstimate`/
45
+ * `MoveItems`/`ResolveRecipients`). Deferred pages (`AirNotification`, `ValidateCert`, `DocumentLibrary`,
46
+ * `Notes`, `RightsManagement`, `Find`) are registered in `WbxmlCodePage` above (so `SWITCH_PAGE` decoding never
47
+ * fails outright on them) but have no tag table here — nothing in this library's supported command set ever
48
+ * needs to encode/decode a tag from one of them.
49
+ *
50
+ * Values for `AirSync` (0) and `FolderHierarchy` (7) are transcribed directly from the published
51
+ * [MS-ASWBXML] tables (`Code Page 0: AirSync`, `Code Page 7: FolderHierarchy`, learn.microsoft.com). Every
52
+ * other page's values come from Z-Push's `wbxmldefs.php` (github.com/Z-Hub/Z-Push,
53
+ * `src/lib/wbxml/wbxmldefs.php`) — a production, real-device-tested open-source ActiveSync server whose
54
+ * numeric token tables are necessarily byte-exact against the wire protocol (a handful of its internal PHP
55
+ * array-key names were normalized here to the tag names used elsewhere in the public spec/blog examples,
56
+ * e.g. `Synchronize`->`Sync`, `Replies`->`Responses`, `Modify`->`Change`, `Remove`->`Delete` on page 0; the
57
+ * numeric token values themselves were not changed). A handful of legacy/deprecated token slots absent from
58
+ * the *current* published MS-ASWBXML tables but still present in Z-Push (e.g. AirSync `0x11 Version`, `0x1A
59
+ * RtfTruncation`, `0x1F NotifyGUID`) are kept so this codec can still decode older real-world traffic that
60
+ * may use them; they are marked `deprecated` in the table below and are never emitted by this library's own
61
+ * encoder.
62
+ */
63
+ const TAGS_BY_PAGE = {
64
+ [WbxmlCodePage.AirSync]: {
65
+ 0x05: "Sync",
66
+ 0x06: "Responses",
67
+ 0x07: "Add",
68
+ 0x08: "Change",
69
+ 0x09: "Delete",
70
+ 0x0a: "Fetch",
71
+ 0x0b: "SyncKey",
72
+ 0x0c: "ClientId",
73
+ 0x0d: "ServerId",
74
+ 0x0e: "Status",
75
+ 0x0f: "Collection",
76
+ 0x10: "Class",
77
+ 0x11: "Version", // deprecated
78
+ 0x12: "CollectionId",
79
+ 0x13: "GetChanges",
80
+ 0x14: "MoreAvailable",
81
+ 0x15: "WindowSize",
82
+ 0x16: "Commands",
83
+ 0x17: "Options",
84
+ 0x18: "FilterType",
85
+ 0x19: "Truncation", // 2.5 only
86
+ 0x1a: "RtfTruncation", // deprecated
87
+ 0x1b: "Conflict",
88
+ 0x1c: "Collections",
89
+ 0x1d: "ApplicationData",
90
+ 0x1e: "DeletesAsMoves",
91
+ 0x1f: "NotifyGUID", // deprecated
92
+ 0x20: "Supported",
93
+ 0x21: "SoftDelete",
94
+ 0x22: "MIMESupport",
95
+ 0x23: "MIMETruncation",
96
+ 0x24: "Wait",
97
+ 0x25: "Limit",
98
+ 0x26: "Partial",
99
+ 0x27: "ConversationMode",
100
+ 0x28: "MaxItems",
101
+ 0x29: "HeartbeatInterval",
102
+ },
103
+ [WbxmlCodePage.Contacts]: {
104
+ 0x05: "Anniversary",
105
+ 0x06: "AssistantName",
106
+ 0x07: "AssistantTelephoneNumber",
107
+ 0x08: "Birthday",
108
+ 0x09: "Body", // legacy (2.5); AirSyncBase Body used since 12.0
109
+ 0x0a: "BodySize",
110
+ 0x0b: "BodyTruncated",
111
+ 0x0c: "Business2PhoneNumber",
112
+ 0x0d: "BusinessCity",
113
+ 0x0e: "BusinessCountry",
114
+ 0x0f: "BusinessPostalCode",
115
+ 0x10: "BusinessState",
116
+ 0x11: "BusinessStreet",
117
+ 0x12: "BusinessFaxNumber",
118
+ 0x13: "BusinessPhoneNumber",
119
+ 0x14: "CarPhoneNumber",
120
+ 0x15: "Categories",
121
+ 0x16: "Category",
122
+ 0x17: "Children",
123
+ 0x18: "Child",
124
+ 0x19: "CompanyName",
125
+ 0x1a: "Department",
126
+ 0x1b: "Email1Address",
127
+ 0x1c: "Email2Address",
128
+ 0x1d: "Email3Address",
129
+ 0x1e: "FileAs",
130
+ 0x1f: "FirstName",
131
+ 0x20: "Home2PhoneNumber",
132
+ 0x21: "HomeCity",
133
+ 0x22: "HomeCountry",
134
+ 0x23: "HomePostalCode",
135
+ 0x24: "HomeState",
136
+ 0x25: "HomeStreet",
137
+ 0x26: "HomeFaxNumber",
138
+ 0x27: "HomePhoneNumber",
139
+ 0x28: "JobTitle",
140
+ 0x29: "LastName",
141
+ 0x2a: "MiddleName",
142
+ 0x2b: "MobilePhoneNumber",
143
+ 0x2c: "OfficeLocation",
144
+ 0x2d: "OtherCity",
145
+ 0x2e: "OtherCountry",
146
+ 0x2f: "OtherPostalCode",
147
+ 0x30: "OtherState",
148
+ 0x31: "OtherStreet",
149
+ 0x32: "PagerNumber",
150
+ 0x33: "RadioPhoneNumber",
151
+ 0x34: "Spouse",
152
+ 0x35: "Suffix",
153
+ 0x36: "Title",
154
+ 0x37: "WebPage",
155
+ 0x38: "YomiCompanyName",
156
+ 0x39: "YomiFirstName",
157
+ 0x3a: "YomiLastName",
158
+ 0x3b: "CompressedRTF", // deprecated
159
+ 0x3c: "Picture",
160
+ 0x3d: "Alias",
161
+ 0x3e: "WeightedRank",
162
+ },
163
+ [WbxmlCodePage.Email]: {
164
+ 0x05: "Attachment", // legacy; AirSyncBase Attachments used since 12.0
165
+ 0x06: "Attachments",
166
+ 0x07: "AttName",
167
+ 0x08: "AttSize",
168
+ 0x09: "AttOid",
169
+ 0x0a: "AttMethod",
170
+ 0x0b: "AttRemoved",
171
+ 0x0c: "Body",
172
+ 0x0d: "BodySize",
173
+ 0x0e: "BodyTruncated",
174
+ 0x0f: "DateReceived",
175
+ 0x10: "DisplayTo",
176
+ 0x11: "DisplayCc",
177
+ 0x12: "Importance",
178
+ 0x13: "MessageClass",
179
+ 0x14: "Subject",
180
+ 0x15: "Read",
181
+ 0x16: "To",
182
+ 0x17: "Cc",
183
+ 0x18: "From",
184
+ 0x19: "ReplyTo",
185
+ 0x1a: "AllDayEvent",
186
+ 0x1b: "Categories",
187
+ 0x1c: "Category",
188
+ 0x1d: "DtStamp",
189
+ 0x1e: "EndTime",
190
+ 0x1f: "InstanceType",
191
+ 0x20: "BusyStatus",
192
+ 0x21: "Location",
193
+ 0x22: "MeetingRequest",
194
+ 0x23: "Organizer",
195
+ 0x24: "RecurrenceId",
196
+ 0x25: "Reminder",
197
+ 0x26: "ResponseRequested",
198
+ 0x27: "Recurrences",
199
+ 0x28: "Recurrence",
200
+ 0x29: "Type",
201
+ 0x2a: "Until",
202
+ 0x2b: "Occurrences",
203
+ 0x2c: "Interval",
204
+ 0x2d: "DayOfWeek",
205
+ 0x2e: "DayOfMonth",
206
+ 0x2f: "WeekOfMonth",
207
+ 0x30: "MonthOfYear",
208
+ 0x31: "StartTime",
209
+ 0x32: "Sensitivity",
210
+ 0x33: "TimeZone",
211
+ 0x34: "GlobalObjId",
212
+ 0x35: "ThreadTopic",
213
+ 0x36: "MIMEData", // 2.5, deprecated
214
+ 0x37: "MIMETruncated",
215
+ 0x38: "MIMESize",
216
+ 0x39: "InternetCPID",
217
+ 0x3a: "Flag",
218
+ 0x3b: "FlagStatus",
219
+ 0x3c: "ContentClass",
220
+ 0x3d: "FlagType",
221
+ 0x3e: "CompleteTime",
222
+ 0x3f: "DisallowNewTimeProposal",
223
+ },
224
+ [WbxmlCodePage.Calendar]: {
225
+ 0x05: "Timezone",
226
+ 0x06: "AllDayEvent",
227
+ 0x07: "Attendees",
228
+ 0x08: "Attendee",
229
+ 0x09: "Email",
230
+ 0x0a: "Name",
231
+ 0x0b: "Body",
232
+ 0x0c: "BodyTruncated",
233
+ 0x0d: "BusyStatus",
234
+ 0x0e: "Categories",
235
+ 0x0f: "Category",
236
+ 0x10: "CompressedRTF", // deprecated
237
+ 0x11: "DtStamp",
238
+ 0x12: "EndTime",
239
+ 0x13: "Exception",
240
+ 0x14: "Exceptions",
241
+ 0x15: "Deleted",
242
+ 0x16: "ExceptionStartTime",
243
+ 0x17: "Location",
244
+ 0x18: "MeetingStatus",
245
+ 0x19: "OrganizerEmail",
246
+ 0x1a: "OrganizerName",
247
+ 0x1b: "Recurrence",
248
+ 0x1c: "Type",
249
+ 0x1d: "Until",
250
+ 0x1e: "Occurrences",
251
+ 0x1f: "Interval",
252
+ 0x20: "DayOfWeek",
253
+ 0x21: "DayOfMonth",
254
+ 0x22: "WeekOfMonth",
255
+ 0x23: "MonthOfYear",
256
+ 0x24: "Reminder",
257
+ 0x25: "Sensitivity",
258
+ 0x26: "Subject",
259
+ 0x27: "StartTime",
260
+ 0x28: "UID",
261
+ 0x29: "AttendeeStatus",
262
+ 0x2a: "AttendeeType",
263
+ 0x2b: "Attachment", // deprecated
264
+ 0x2c: "Attachments", // deprecated
265
+ 0x2d: "AttName", // deprecated
266
+ 0x2e: "AttSize", // deprecated
267
+ 0x2f: "AttOid", // deprecated
268
+ 0x30: "AttMethod", // deprecated
269
+ 0x31: "AttRemoved", // deprecated
270
+ 0x32: "DisplayName", // deprecated
271
+ 0x33: "DisallowNewTimeProposal",
272
+ 0x34: "ResponseRequested",
273
+ 0x35: "AppointmentReplyTime",
274
+ 0x36: "ResponseType",
275
+ 0x37: "CalendarType",
276
+ 0x38: "IsLeapMonth",
277
+ 0x39: "FirstDayOfWeek",
278
+ 0x3a: "OnlineMeetingConfLink",
279
+ 0x3b: "OnlineMeetingExternalLink",
280
+ 0x3c: "ClientUid",
281
+ },
282
+ [WbxmlCodePage.Move]: {
283
+ 0x05: "MoveItems",
284
+ 0x06: "Move",
285
+ 0x07: "SrcMsgId",
286
+ 0x08: "SrcFldId",
287
+ 0x09: "DstFldId",
288
+ 0x0a: "Response",
289
+ 0x0b: "Status",
290
+ 0x0c: "DstMsgId",
291
+ },
292
+ [WbxmlCodePage.ItemEstimate]: {
293
+ 0x05: "GetItemEstimate",
294
+ 0x06: "Version", // deprecated
295
+ // 0x07-0x0a ("Folders"/"Folder"/"FolderType"/"FolderId") are the pre-12.0 legacy request/response shape
296
+ // - the modern (14.0+) GetItemEstimate this library actually implements reuses `WbxmlCodePage.AirSync`'s
297
+ // own `Collections`/`Collection`/`Class`/`CollectionId`/`SyncKey` via SWITCH_PAGE instead (the same
298
+ // cross-page-reuse pattern `ItemOperationsCommand.fetchMessage` already uses) - kept decodable here for
299
+ // completeness, never emitted by `GetItemEstimateCommand`.
300
+ 0x07: "Folders", // deprecated (legacy pre-12.0 shape)
301
+ 0x08: "Folder", // deprecated
302
+ 0x09: "FolderType", // deprecated
303
+ 0x0a: "FolderId", // deprecated
304
+ 0x0b: "DateTime", // deprecated
305
+ 0x0c: "Estimate",
306
+ 0x0d: "Response",
307
+ 0x0e: "Status",
308
+ },
309
+ [WbxmlCodePage.FolderHierarchy]: {
310
+ 0x05: "Folders", // legacy (2.5, 12.0, 12.1)
311
+ 0x06: "Folder", // legacy
312
+ 0x07: "DisplayName",
313
+ 0x08: "ServerId",
314
+ 0x09: "ParentId",
315
+ 0x0a: "Type",
316
+ 0x0b: "Response", // deprecated
317
+ 0x0c: "Status",
318
+ 0x0d: "ContentClass", // deprecated
319
+ 0x0e: "Changes",
320
+ 0x0f: "Add",
321
+ 0x10: "Delete",
322
+ 0x11: "Update",
323
+ 0x12: "SyncKey",
324
+ 0x13: "FolderCreate",
325
+ 0x14: "FolderDelete",
326
+ 0x15: "FolderUpdate",
327
+ 0x16: "FolderSync",
328
+ 0x17: "Count",
329
+ 0x18: "Version", // deprecated
330
+ },
331
+ [WbxmlCodePage.MeetingResponse]: {
332
+ 0x05: "CalendarId",
333
+ 0x06: "CollectionId",
334
+ 0x07: "MeetingResponse",
335
+ 0x08: "RequestId",
336
+ 0x09: "Request",
337
+ 0x0a: "Result",
338
+ 0x0b: "Status",
339
+ 0x0c: "UserResponse",
340
+ 0x0d: "Version", // deprecated
341
+ 0x0e: "InstanceId",
342
+ 0x10: "ProposedStartTime",
343
+ 0x11: "ProposedEndTime",
344
+ 0x12: "SendResponse",
345
+ },
346
+ [WbxmlCodePage.ResolveRecipients]: {
347
+ 0x05: "ResolveRecipients",
348
+ 0x06: "Response",
349
+ 0x07: "Status",
350
+ 0x08: "Type",
351
+ 0x09: "Recipient",
352
+ 0x0a: "DisplayName",
353
+ 0x0b: "EmailAddress",
354
+ 0x0c: "Certificates",
355
+ 0x0d: "Certificate",
356
+ 0x0e: "MiniCertificate",
357
+ 0x0f: "Options",
358
+ 0x10: "To",
359
+ 0x11: "CertificateRetrieval",
360
+ 0x12: "RecipientCount",
361
+ 0x13: "MaxCertificates",
362
+ 0x14: "MaxAmbiguousRecipients",
363
+ 0x15: "CertificateCount",
364
+ 0x16: "Availability",
365
+ 0x17: "StartTime",
366
+ 0x18: "EndTime",
367
+ 0x19: "MergedFreeBusy",
368
+ 0x1a: "Picture",
369
+ 0x1b: "MaxSize",
370
+ 0x1c: "Data",
371
+ 0x1d: "MaxPictures",
372
+ },
373
+ [WbxmlCodePage.Tasks]: {
374
+ 0x05: "Body",
375
+ 0x06: "BodySize",
376
+ 0x07: "BodyTruncated",
377
+ 0x08: "Categories",
378
+ 0x09: "Category",
379
+ 0x0a: "Complete",
380
+ 0x0b: "DateCompleted",
381
+ 0x0c: "DueDate",
382
+ 0x0d: "UtcDueDate",
383
+ 0x0e: "Importance",
384
+ 0x0f: "Recurrence",
385
+ 0x10: "Type",
386
+ 0x11: "Start",
387
+ 0x12: "Until",
388
+ 0x13: "Occurrences",
389
+ 0x14: "Interval",
390
+ 0x15: "DayOfMonth",
391
+ 0x16: "DayOfWeek",
392
+ 0x17: "WeekOfMonth",
393
+ 0x18: "MonthOfYear",
394
+ 0x19: "Regenerate",
395
+ 0x1a: "DeadOccur",
396
+ 0x1b: "ReminderSet",
397
+ 0x1c: "ReminderTime",
398
+ 0x1d: "Sensitivity",
399
+ 0x1e: "StartDate",
400
+ 0x1f: "UtcStartDate",
401
+ 0x20: "Subject",
402
+ 0x21: "CompressedRTF", // deprecated
403
+ 0x22: "OrdinalDate",
404
+ 0x23: "SubOrdinalDate",
405
+ 0x24: "CalendarType",
406
+ 0x25: "IsLeapMonth",
407
+ 0x26: "FirstDayOfWeek",
408
+ },
409
+ [WbxmlCodePage.Contacts2]: {
410
+ 0x05: "CustomerId",
411
+ 0x06: "GovernmentId",
412
+ 0x07: "IMAddress",
413
+ 0x08: "IMAddress2",
414
+ 0x09: "IMAddress3",
415
+ 0x0a: "ManagerName",
416
+ 0x0b: "CompanyMainPhone",
417
+ 0x0c: "AccountName",
418
+ 0x0d: "NickName",
419
+ 0x0e: "MMS",
420
+ },
421
+ [WbxmlCodePage.Ping]: {
422
+ 0x05: "Ping",
423
+ 0x06: "AutdState", // not used by the protocol
424
+ 0x07: "Status",
425
+ 0x08: "HeartbeatInterval",
426
+ 0x09: "Folders",
427
+ 0x0a: "Folder",
428
+ 0x0b: "ServerId",
429
+ 0x0c: "Class",
430
+ 0x0d: "MaxFolders",
431
+ 0x0e: "Version", // deprecated
432
+ },
433
+ [WbxmlCodePage.Provision]: {
434
+ 0x05: "Provision",
435
+ 0x06: "Policies",
436
+ 0x07: "Policy",
437
+ 0x08: "PolicyType",
438
+ 0x09: "PolicyKey",
439
+ 0x0a: "Data",
440
+ 0x0b: "Status",
441
+ 0x0c: "RemoteWipe",
442
+ 0x0d: "EASProvisionDoc",
443
+ 0x0e: "DevicePasswordEnabled",
444
+ 0x0f: "AlphanumericDevicePasswordRequired",
445
+ 0x10: "DeviceEncryptionEnabled",
446
+ 0x11: "PasswordRecoveryEnabled",
447
+ 0x12: "DocumentBrowseEnabled", // deprecated
448
+ 0x13: "AttachmentsEnabled",
449
+ 0x14: "MinDevicePasswordLength",
450
+ 0x15: "MaxInactivityTimeDeviceLock",
451
+ 0x16: "MaxDevicePasswordFailedAttempts",
452
+ 0x17: "MaxAttachmentSize",
453
+ 0x18: "AllowSimpleDevicePassword",
454
+ 0x19: "DevicePasswordExpiration",
455
+ 0x1a: "DevicePasswordHistory",
456
+ 0x1b: "AllowStorageCard",
457
+ 0x1c: "AllowCamera",
458
+ 0x1d: "RequireDeviceEncryption",
459
+ 0x1e: "AllowUnsignedApplications",
460
+ 0x1f: "AllowUnsignedInstallationPackages",
461
+ 0x20: "MinDevicePasswordComplexCharacters",
462
+ 0x21: "AllowWiFi",
463
+ 0x22: "AllowTextMessaging",
464
+ 0x23: "AllowPOPIMAPEmail",
465
+ 0x24: "AllowBluetooth",
466
+ 0x25: "AllowIrDA",
467
+ 0x26: "RequireManualSyncWhenRoaming",
468
+ 0x27: "AllowDesktopSync",
469
+ 0x28: "MaxCalendarAgeFilter",
470
+ 0x29: "AllowHTMLEmail",
471
+ 0x2a: "MaxEmailAgeFilter",
472
+ 0x2b: "MaxEmailBodyTruncationSize",
473
+ 0x2c: "MaxEmailHTMLBodyTruncationSize",
474
+ 0x2d: "RequireSignedSMIMEMessages",
475
+ 0x2e: "RequireEncryptedSMIMEMessages",
476
+ 0x2f: "RequireSignedSMIMEAlgorithm",
477
+ 0x30: "RequireEncryptionSMIMEAlgorithm",
478
+ 0x31: "AllowSMIMEEncryptionAlgorithmNegotiation",
479
+ 0x32: "AllowSMIMESoftCerts",
480
+ 0x33: "AllowBrowser",
481
+ 0x34: "AllowConsumerEmail",
482
+ 0x35: "AllowRemoteDesktop",
483
+ 0x36: "AllowInternetSharing",
484
+ 0x37: "UnapprovedInROMApplicationList",
485
+ 0x38: "ApplicationName",
486
+ 0x39: "ApprovedApplicationList",
487
+ 0x3a: "Hash",
488
+ 0x3b: "AccountOnlyRemoteWipe",
489
+ },
490
+ [WbxmlCodePage.Search]: {
491
+ 0x05: "Search",
492
+ 0x07: "Store",
493
+ 0x08: "Name",
494
+ 0x09: "Query",
495
+ 0x0a: "Options",
496
+ 0x0b: "Range",
497
+ 0x0c: "Status",
498
+ 0x0d: "Response",
499
+ 0x0e: "Result",
500
+ 0x0f: "Properties",
501
+ 0x10: "Total",
502
+ 0x11: "EqualTo",
503
+ 0x12: "Value",
504
+ 0x13: "And",
505
+ 0x14: "Or",
506
+ 0x15: "FreeText",
507
+ 0x17: "DeepTraversal",
508
+ 0x18: "LongId",
509
+ 0x19: "RebuildResults",
510
+ 0x1a: "LessThan",
511
+ 0x1b: "GreaterThan",
512
+ 0x1c: "Schema",
513
+ 0x1d: "Supported",
514
+ 0x1e: "UserName",
515
+ 0x1f: "Password",
516
+ 0x20: "ConversationId",
517
+ 0x21: "Picture",
518
+ 0x22: "MaxSize",
519
+ 0x23: "MaxPictures",
520
+ },
521
+ [WbxmlCodePage.Gal]: {
522
+ 0x05: "DisplayName",
523
+ 0x06: "Phone",
524
+ 0x07: "Office",
525
+ 0x08: "Title",
526
+ 0x09: "Company",
527
+ 0x0a: "Alias",
528
+ 0x0b: "FirstName",
529
+ 0x0c: "LastName",
530
+ 0x0d: "HomePhone",
531
+ 0x0e: "MobilePhone",
532
+ 0x0f: "EmailAddress",
533
+ 0x10: "Picture",
534
+ 0x11: "Status",
535
+ 0x12: "Data",
536
+ },
537
+ [WbxmlCodePage.AirSyncBase]: {
538
+ 0x05: "BodyPreference",
539
+ 0x06: "Type",
540
+ 0x07: "TruncationSize",
541
+ 0x08: "AllOrNone",
542
+ 0x0a: "Body",
543
+ 0x0b: "Data",
544
+ 0x0c: "EstimatedDataSize",
545
+ 0x0d: "Truncated",
546
+ 0x0e: "Attachments",
547
+ 0x0f: "Attachment",
548
+ 0x10: "DisplayName",
549
+ 0x11: "FileReference",
550
+ 0x12: "Method",
551
+ 0x13: "ContentId",
552
+ 0x14: "ContentLocation",
553
+ 0x15: "IsInline",
554
+ 0x16: "NativeBodyType",
555
+ 0x17: "ContentType",
556
+ 0x18: "Preview",
557
+ 0x19: "BodyPartPreference",
558
+ 0x1a: "BodyPart",
559
+ 0x1b: "Status",
560
+ 0x1c: "Add",
561
+ 0x1d: "Delete",
562
+ 0x1e: "ClientId",
563
+ 0x1f: "Content",
564
+ 0x20: "Location",
565
+ 0x21: "Annotation",
566
+ 0x22: "Street",
567
+ 0x23: "City",
568
+ 0x24: "State",
569
+ 0x25: "Country",
570
+ 0x26: "PostalCode",
571
+ 0x27: "Latitude",
572
+ 0x28: "Longitude",
573
+ 0x29: "Accuracy",
574
+ 0x2a: "Altitude",
575
+ 0x2b: "AltitudeAccuracy",
576
+ 0x2c: "LocationUri",
577
+ 0x2d: "InstanceId",
578
+ },
579
+ [WbxmlCodePage.Settings]: {
580
+ 0x05: "Settings",
581
+ 0x06: "Status",
582
+ 0x07: "Get",
583
+ 0x08: "Set",
584
+ 0x09: "Oof",
585
+ 0x0a: "OofState",
586
+ 0x0b: "StartTime",
587
+ 0x0c: "EndTime",
588
+ 0x0d: "OofMessage",
589
+ 0x0e: "AppliesToInternal",
590
+ 0x0f: "AppliesToExternalKnown",
591
+ 0x10: "AppliesToExternalUnknown",
592
+ 0x11: "Enabled",
593
+ 0x12: "ReplyMessage",
594
+ 0x13: "BodyType",
595
+ 0x14: "DevicePassword",
596
+ 0x15: "Password",
597
+ 0x16: "DeviceInformation",
598
+ 0x17: "Model",
599
+ 0x18: "IMEI",
600
+ 0x19: "FriendlyName",
601
+ 0x1a: "OS",
602
+ 0x1b: "OSLanguage",
603
+ 0x1c: "PhoneNumber",
604
+ 0x1d: "UserInformation",
605
+ 0x1e: "EmailAddresses",
606
+ 0x1f: "SmtpAddress",
607
+ 0x20: "UserAgent",
608
+ 0x21: "EnableOutboundSMS",
609
+ 0x22: "MobileOperator",
610
+ 0x23: "PrimarySmtpAddress",
611
+ 0x24: "Accounts",
612
+ 0x25: "Account",
613
+ 0x26: "AccountId",
614
+ 0x27: "AccountName",
615
+ 0x28: "UserDisplayName",
616
+ 0x29: "SendDisabled",
617
+ 0x2b: "RightsManagementInformation",
618
+ },
619
+ [WbxmlCodePage.ItemOperations]: {
620
+ 0x05: "ItemOperations",
621
+ 0x06: "Fetch",
622
+ 0x07: "Store",
623
+ 0x08: "Options",
624
+ 0x09: "Range",
625
+ 0x0a: "Total",
626
+ 0x0b: "Properties",
627
+ 0x0c: "Data",
628
+ 0x0d: "Status",
629
+ 0x0e: "Response",
630
+ 0x0f: "Version",
631
+ 0x10: "Schema",
632
+ 0x11: "Part",
633
+ 0x12: "EmptyFolderContents",
634
+ 0x13: "DeleteSubFolders",
635
+ 0x14: "UserName",
636
+ 0x15: "Password",
637
+ 0x16: "Move",
638
+ 0x17: "DstFldId",
639
+ 0x18: "ConversationId",
640
+ 0x19: "MoveAlways",
641
+ },
642
+ [WbxmlCodePage.ComposeMail]: {
643
+ 0x05: "SendMail",
644
+ 0x06: "SmartForward",
645
+ 0x07: "SmartReply",
646
+ 0x08: "SaveInSentItems",
647
+ 0x09: "ReplaceMime",
648
+ 0x0a: "Type", // not used
649
+ 0x0b: "Source",
650
+ 0x0c: "FolderId",
651
+ 0x0d: "ItemId",
652
+ 0x0e: "LongId",
653
+ 0x0f: "InstanceId",
654
+ 0x10: "MIME",
655
+ 0x11: "ClientId",
656
+ 0x12: "Status",
657
+ 0x13: "AccountId",
658
+ 0x15: "Forwardees",
659
+ 0x16: "Forwardee",
660
+ 0x17: "Name",
661
+ 0x18: "Email",
662
+ },
663
+ [WbxmlCodePage.Email2]: {
664
+ 0x05: "UmCallerID",
665
+ 0x06: "UmUserNotes",
666
+ 0x07: "UmAttDuration",
667
+ 0x08: "UmAttOrder",
668
+ 0x09: "ConversationId",
669
+ 0x0a: "ConversationIndex",
670
+ 0x0b: "LastVerbExecuted",
671
+ 0x0c: "LastVerbExecutionTime",
672
+ 0x0d: "ReceivedAsBcc",
673
+ 0x0e: "Sender",
674
+ 0x0f: "CalendarType",
675
+ 0x10: "IsLeapMonth",
676
+ 0x11: "AccountId",
677
+ 0x12: "FirstDayOfWeek",
678
+ 0x13: "MeetingMessageType",
679
+ 0x15: "IsDraft",
680
+ 0x16: "Bcc",
681
+ 0x17: "Send",
682
+ },
683
+ };
684
+ const CODES_BY_PAGE = Object.fromEntries(Object.entries(TAGS_BY_PAGE).map(([page, tags]) => [
685
+ Number(page),
686
+ Object.fromEntries(Object.entries(tags).map(([code, name]) => [name, Number(code)])),
687
+ ]));
688
+ /** Resolves a decoded tag byte's low 6 bits back into its tag name for the given code page. Falls back to a
689
+ * synthetic `"Unknown0x.."` name (rather than throwing) for a page/code this table doesn't recognize - a
690
+ * still-decodable, debuggable placeholder for a deferred code page or a future protocol version's new field,
691
+ * rather than failing the entire document over one unrecognized tag. */
692
+ export function tagNameForCode(page, code) {
693
+ return TAGS_BY_PAGE[page]?.[code] ?? `Unknown0x${code.toString(16).padStart(2, "0")}`;
694
+ }
695
+ /** Resolves a tag name to its token byte (low 6 bits, before the content-flag bit is applied) for the given
696
+ * code page. Unlike `tagNameForCode()`, this throws on an unknown pair - encoding a tag this table has no
697
+ * token for is always a genuine programming error (an unregistered/deferred field), never legitimate input to
698
+ * tolerate. */
699
+ export function codeForTagName(page, tag) {
700
+ const code = CODES_BY_PAGE[page]?.[tag];
701
+ if (code === undefined) {
702
+ throw new Error(`WbxmlCodePages: no token registered for tag "${tag}" on code page ${page}`);
703
+ }
704
+ return code;
705
+ }
706
+ //# sourceMappingURL=WbxmlCodePages.js.map