@rapidmx/activesync-plugin 1.0.0-beta.2 → 1.0.0-beta.3

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 (201) hide show
  1. package/README.md +4 -4
  2. package/dist/lib/BaseDeviceSyncStateRoute.js +32 -0
  3. package/dist/lib/BaseDeviceSyncStateRoute.js.map +1 -1
  4. package/dist/lib/BaseEasRoute.js +91 -15
  5. package/dist/lib/BaseEasRoute.js.map +1 -1
  6. package/dist/lib/EasAuditLog.js +56 -0
  7. package/dist/lib/EasAuditLog.js.map +1 -0
  8. package/dist/lib/EasCollectionLease.js +199 -0
  9. package/dist/lib/EasCollectionLease.js.map +1 -0
  10. package/dist/lib/EasCollectionStore.js +102 -0
  11. package/dist/lib/EasCollectionStore.js.map +1 -0
  12. package/dist/lib/EasCollectionSync.js +294 -0
  13. package/dist/lib/EasCollectionSync.js.map +1 -0
  14. package/dist/lib/EasSyncKeyUtils.js +125 -62
  15. package/dist/lib/EasSyncKeyUtils.js.map +1 -1
  16. package/dist/lib/MessageMoveRules.js +100 -0
  17. package/dist/lib/MessageMoveRules.js.map +1 -0
  18. package/dist/lib/MimeHeaderUtils.js +395 -0
  19. package/dist/lib/MimeHeaderUtils.js.map +1 -0
  20. package/dist/lib/RegexPatternUtils.js +30 -0
  21. package/dist/lib/RegexPatternUtils.js.map +1 -0
  22. package/dist/lib/RestapiCompat.js +41 -0
  23. package/dist/lib/RestapiCompat.js.map +1 -0
  24. package/dist/lib/adapters/CalendarSyncAdapter.js +142 -33
  25. package/dist/lib/adapters/CalendarSyncAdapter.js.map +1 -1
  26. package/dist/lib/adapters/EmailSyncAdapter.js +114 -27
  27. package/dist/lib/adapters/EmailSyncAdapter.js.map +1 -1
  28. package/dist/lib/adapters/mongo/EmailSyncAdapterMongo.js +2 -1
  29. package/dist/lib/adapters/mongo/EmailSyncAdapterMongo.js.map +1 -1
  30. package/dist/lib/adapters/sql/EmailSyncAdapterSQL.js +2 -1
  31. package/dist/lib/adapters/sql/EmailSyncAdapterSQL.js.map +1 -1
  32. package/dist/lib/codec/WbxmlDecoder.js +86 -34
  33. package/dist/lib/codec/WbxmlDecoder.js.map +1 -1
  34. package/dist/lib/codec/WbxmlEncoder.js +103 -22
  35. package/dist/lib/codec/WbxmlEncoder.js.map +1 -1
  36. package/dist/lib/commands/ComposeMailCommand.js +105 -31
  37. package/dist/lib/commands/ComposeMailCommand.js.map +1 -1
  38. package/dist/lib/commands/FolderSyncCommand.js +67 -27
  39. package/dist/lib/commands/FolderSyncCommand.js.map +1 -1
  40. package/dist/lib/commands/GetItemEstimateCommand.js +80 -59
  41. package/dist/lib/commands/GetItemEstimateCommand.js.map +1 -1
  42. package/dist/lib/commands/ItemOperationsCommand.js +219 -56
  43. package/dist/lib/commands/ItemOperationsCommand.js.map +1 -1
  44. package/dist/lib/commands/MeetingResponseCommand.js +212 -53
  45. package/dist/lib/commands/MeetingResponseCommand.js.map +1 -1
  46. package/dist/lib/commands/MoveItemsCommand.js +54 -21
  47. package/dist/lib/commands/MoveItemsCommand.js.map +1 -1
  48. package/dist/lib/commands/PingCommand.js +288 -56
  49. package/dist/lib/commands/PingCommand.js.map +1 -1
  50. package/dist/lib/commands/ProvisionCommand.js +34 -17
  51. package/dist/lib/commands/ProvisionCommand.js.map +1 -1
  52. package/dist/lib/commands/ResolveRecipientsCommand.js +43 -5
  53. package/dist/lib/commands/ResolveRecipientsCommand.js.map +1 -1
  54. package/dist/lib/commands/SearchCommand.js +92 -17
  55. package/dist/lib/commands/SearchCommand.js.map +1 -1
  56. package/dist/lib/commands/SettingsCommand.js +2 -1
  57. package/dist/lib/commands/SettingsCommand.js.map +1 -1
  58. package/dist/lib/commands/SmartForwardCommand.js +2 -1
  59. package/dist/lib/commands/SmartForwardCommand.js.map +1 -1
  60. package/dist/lib/commands/SmartReplyCommand.js +2 -1
  61. package/dist/lib/commands/SmartReplyCommand.js.map +1 -1
  62. package/dist/lib/commands/SyncCommand.js +481 -244
  63. package/dist/lib/commands/SyncCommand.js.map +1 -1
  64. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js +6 -1
  65. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js.map +1 -1
  66. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js +3 -1
  67. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js.map +1 -1
  68. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js +2 -1
  69. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js.map +1 -1
  70. package/dist/lib/commands/mongo/PingCommandMongo.js +23 -0
  71. package/dist/lib/commands/mongo/PingCommandMongo.js.map +1 -0
  72. package/dist/lib/commands/mongo/SearchCommandMongo.js +3 -1
  73. package/dist/lib/commands/mongo/SearchCommandMongo.js.map +1 -1
  74. package/dist/lib/commands/mongo/SendMailCommandMongo.js +2 -1
  75. package/dist/lib/commands/mongo/SendMailCommandMongo.js.map +1 -1
  76. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js +2 -1
  77. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js.map +1 -1
  78. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js +2 -1
  79. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js.map +1 -1
  80. package/dist/lib/commands/mongo/SyncCommandMongo.js +7 -1
  81. package/dist/lib/commands/mongo/SyncCommandMongo.js.map +1 -1
  82. package/dist/lib/commands/mongo/index.js +1 -0
  83. package/dist/lib/commands/mongo/index.js.map +1 -1
  84. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js +6 -1
  85. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js.map +1 -1
  86. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js +3 -1
  87. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js.map +1 -1
  88. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js +2 -1
  89. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js.map +1 -1
  90. package/dist/lib/commands/sql/PingCommandSQL.js +23 -0
  91. package/dist/lib/commands/sql/PingCommandSQL.js.map +1 -0
  92. package/dist/lib/commands/sql/SearchCommandSQL.js +3 -1
  93. package/dist/lib/commands/sql/SearchCommandSQL.js.map +1 -1
  94. package/dist/lib/commands/sql/SendMailCommandSQL.js +2 -1
  95. package/dist/lib/commands/sql/SendMailCommandSQL.js.map +1 -1
  96. package/dist/lib/commands/sql/SmartForwardCommandSQL.js +2 -1
  97. package/dist/lib/commands/sql/SmartForwardCommandSQL.js.map +1 -1
  98. package/dist/lib/commands/sql/SmartReplyCommandSQL.js +2 -1
  99. package/dist/lib/commands/sql/SmartReplyCommandSQL.js.map +1 -1
  100. package/dist/lib/commands/sql/SyncCommandSQL.js +7 -1
  101. package/dist/lib/commands/sql/SyncCommandSQL.js.map +1 -1
  102. package/dist/lib/commands/sql/index.js +1 -0
  103. package/dist/lib/commands/sql/index.js.map +1 -1
  104. package/dist/lib/index.js +5 -0
  105. package/dist/lib/index.js.map +1 -1
  106. package/dist/lib/jobs/EasDeviceStateCleanupJob.js +44 -2
  107. package/dist/lib/jobs/EasDeviceStateCleanupJob.js.map +1 -1
  108. package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js +4 -0
  109. package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js.map +1 -1
  110. package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js +9 -0
  111. package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js.map +1 -1
  112. package/dist/lib/models/EasCollectionChunk.js +2 -0
  113. package/dist/lib/models/EasCollectionChunk.js.map +1 -0
  114. package/dist/lib/models/EasCollectionState.js +2 -0
  115. package/dist/lib/models/EasCollectionState.js.map +1 -0
  116. package/dist/lib/models/mongo/DeviceSyncStateMongo.js +7 -0
  117. package/dist/lib/models/mongo/DeviceSyncStateMongo.js.map +1 -1
  118. package/dist/lib/models/mongo/EasCollectionChunkMongo.js +83 -0
  119. package/dist/lib/models/mongo/EasCollectionChunkMongo.js.map +1 -0
  120. package/dist/lib/models/mongo/EasCollectionStateMongo.js +162 -0
  121. package/dist/lib/models/mongo/EasCollectionStateMongo.js.map +1 -0
  122. package/dist/lib/models/sql/DeviceSyncStateSQL.js +7 -0
  123. package/dist/lib/models/sql/DeviceSyncStateSQL.js.map +1 -1
  124. package/dist/lib/models/sql/EasCollectionChunkSQL.js +83 -0
  125. package/dist/lib/models/sql/EasCollectionChunkSQL.js.map +1 -0
  126. package/dist/lib/models/sql/EasCollectionStateSQL.js +162 -0
  127. package/dist/lib/models/sql/EasCollectionStateSQL.js.map +1 -0
  128. package/dist/lib/mongo/EasRouteMongo.js +2 -2
  129. package/dist/lib/mongo/EasRouteMongo.js.map +1 -1
  130. package/dist/lib/mongo.js +2 -0
  131. package/dist/lib/mongo.js.map +1 -1
  132. package/dist/lib/sql/EasRouteSQL.js +2 -2
  133. package/dist/lib/sql/EasRouteSQL.js.map +1 -1
  134. package/dist/lib/sql.js +2 -0
  135. package/dist/lib/sql.js.map +1 -1
  136. package/dist/types/BaseDeviceSyncStateRoute.d.ts +10 -0
  137. package/dist/types/BaseEasRoute.d.ts +15 -4
  138. package/dist/types/EasAuditLog.d.ts +47 -0
  139. package/dist/types/EasCollectionLease.d.ts +60 -0
  140. package/dist/types/EasCollectionStore.d.ts +51 -0
  141. package/dist/types/EasCollectionSync.d.ts +96 -0
  142. package/dist/types/EasCommandHandler.d.ts +7 -4
  143. package/dist/types/EasSyncKeyUtils.d.ts +73 -42
  144. package/dist/types/MessageMoveRules.d.ts +45 -0
  145. package/dist/types/MimeHeaderUtils.d.ts +73 -0
  146. package/dist/types/RegexPatternUtils.d.ts +14 -0
  147. package/dist/types/RestapiCompat.d.ts +24 -0
  148. package/dist/types/adapters/CalendarSyncAdapter.d.ts +47 -18
  149. package/dist/types/adapters/EasCollectionSyncAdapter.d.ts +18 -2
  150. package/dist/types/adapters/EmailSyncAdapter.d.ts +24 -7
  151. package/dist/types/adapters/mongo/EmailSyncAdapterMongo.d.ts +1 -0
  152. package/dist/types/adapters/sql/EmailSyncAdapterSQL.d.ts +1 -0
  153. package/dist/types/codec/WbxmlDecoder.d.ts +39 -0
  154. package/dist/types/codec/WbxmlEncoder.d.ts +36 -1
  155. package/dist/types/commands/ComposeMailCommand.d.ts +33 -15
  156. package/dist/types/commands/FolderSyncCommand.d.ts +4 -1
  157. package/dist/types/commands/GetItemEstimateCommand.d.ts +20 -15
  158. package/dist/types/commands/ItemOperationsCommand.d.ts +29 -4
  159. package/dist/types/commands/MeetingResponseCommand.d.ts +52 -13
  160. package/dist/types/commands/MoveItemsCommand.d.ts +13 -3
  161. package/dist/types/commands/PingCommand.d.ts +72 -14
  162. package/dist/types/commands/ProvisionCommand.d.ts +16 -11
  163. package/dist/types/commands/ResolveRecipientsCommand.d.ts +4 -0
  164. package/dist/types/commands/SearchCommand.d.ts +13 -1
  165. package/dist/types/commands/SyncCommand.d.ts +102 -62
  166. package/dist/types/commands/mongo/GetItemEstimateCommandMongo.d.ts +3 -0
  167. package/dist/types/commands/mongo/ItemOperationsCommandMongo.d.ts +2 -0
  168. package/dist/types/commands/mongo/MeetingResponseCommandMongo.d.ts +1 -0
  169. package/dist/types/commands/mongo/PingCommandMongo.d.ts +8 -0
  170. package/dist/types/commands/mongo/SearchCommandMongo.d.ts +2 -0
  171. package/dist/types/commands/mongo/SendMailCommandMongo.d.ts +1 -0
  172. package/dist/types/commands/mongo/SmartForwardCommandMongo.d.ts +1 -0
  173. package/dist/types/commands/mongo/SmartReplyCommandMongo.d.ts +1 -0
  174. package/dist/types/commands/mongo/SyncCommandMongo.d.ts +4 -0
  175. package/dist/types/commands/mongo/index.d.ts +1 -0
  176. package/dist/types/commands/sql/GetItemEstimateCommandSQL.d.ts +3 -0
  177. package/dist/types/commands/sql/ItemOperationsCommandSQL.d.ts +2 -0
  178. package/dist/types/commands/sql/MeetingResponseCommandSQL.d.ts +1 -0
  179. package/dist/types/commands/sql/PingCommandSQL.d.ts +8 -0
  180. package/dist/types/commands/sql/SearchCommandSQL.d.ts +2 -0
  181. package/dist/types/commands/sql/SendMailCommandSQL.d.ts +1 -0
  182. package/dist/types/commands/sql/SmartForwardCommandSQL.d.ts +1 -0
  183. package/dist/types/commands/sql/SmartReplyCommandSQL.d.ts +1 -0
  184. package/dist/types/commands/sql/SyncCommandSQL.d.ts +4 -0
  185. package/dist/types/commands/sql/index.d.ts +1 -0
  186. package/dist/types/index.d.ts +5 -0
  187. package/dist/types/jobs/EasDeviceStateCleanupJob.d.ts +15 -0
  188. package/dist/types/jobs/mongo/EasDeviceStateCleanupJobMongo.d.ts +2 -0
  189. package/dist/types/jobs/sql/EasDeviceStateCleanupJobSQL.d.ts +4 -0
  190. package/dist/types/models/DeviceSyncState.d.ts +13 -2
  191. package/dist/types/models/EasCollectionChunk.d.ts +20 -0
  192. package/dist/types/models/EasCollectionState.d.ts +79 -0
  193. package/dist/types/models/mongo/DeviceSyncStateMongo.d.ts +1 -0
  194. package/dist/types/models/mongo/EasCollectionChunkMongo.d.ts +16 -0
  195. package/dist/types/models/mongo/EasCollectionStateMongo.d.ts +27 -0
  196. package/dist/types/models/sql/DeviceSyncStateSQL.d.ts +1 -0
  197. package/dist/types/models/sql/EasCollectionChunkSQL.d.ts +16 -0
  198. package/dist/types/models/sql/EasCollectionStateSQL.d.ts +27 -0
  199. package/dist/types/mongo.d.ts +2 -0
  200. package/dist/types/sql.d.ts +2 -0
  201. package/package.json +267 -238
@@ -12,38 +12,40 @@ var __metadata = (this && this.__metadata) || function (k, v) {
12
12
  // SPDX-License-Identifier: MPL-2.0
13
13
  ///////////////////////////////////////////////////////////////////////////////
14
14
  import { ApiError, ObjectDecorators } from "@rapidrest/core";
15
- import { ACLAction, ACLUtils, ApiErrorMessages, ApiErrors } from "@rapidrest/service-core";
15
+ import { ACLAction, ACLUtils, ApiErrorMessages, ApiErrors, RepoUtils } from "@rapidrest/service-core";
16
16
  import { RecoverableRepoUtils } from "@rapidmx/restapi";
17
17
  import { WbxmlCodePage } from "../codec/WbxmlCodePages.js";
18
18
  import { childText, element, findChild, findChildren, textElement } from "../codec/WbxmlElement.js";
19
- import { computeChanges, resolveSyncKey } from "../EasSyncKeyUtils.js";
19
+ import { classForFolderType, enumerateCollection, filterPredicate, workingStateFromRow } from "../EasCollectionSync.js";
20
+ import { loadHeldSet } from "../EasCollectionStore.js";
21
+ import { MAX_SYNC_COLLECTIONS } from "./SyncCommand.js";
20
22
  const { Config, Init, Inject } = ObjectDecorators;
21
- /** Caps how many changes `computeChanges()` will actually enumerate (and therefore count) per collection for
22
- * an already-synced folder - a real estimate, not a precise unbounded count, matching the command's own name;
23
- * a folder with more pending changes than this reports exactly this many, not the true total. Deliberately
24
- * separate from `SyncCommand`'s own `mail:eas:sync_window_size` - the two commands have no reason to share one
25
- * config knob just because they happen to reuse the same underlying enumeration helper. */
23
+ /** Caps how many changes are enumerated (and therefore counted) per collection - a real estimate, not a precise
24
+ * unbounded count; a folder with more pending changes than this reports exactly this many. */
26
25
  const DEFAULT_MAX_COUNT = 512;
26
+ /** Rows read from the out-of-folder stream while estimating (mirrors `SyncCommand`). */
27
+ const MOVE_SCAN_LIMIT = 1000;
28
+ /** Held ids reconciled against the store while estimating (mirrors `SyncCommand`). */
29
+ const RECONCILE_LIMIT = 100;
27
30
  /**
28
31
  * Handles EAS `GetItemEstimate`: reports, per requested `<Collection>`, an estimated count of the
29
32
  * `Add`/`Change`/`Delete`s a subsequent `Sync` of that collection would return - read-only, it never issues or
30
33
  * consumes a `SyncKey` itself.
31
34
  *
32
35
  * The modern (14.0+) request/response reuses `WbxmlCodePage.AirSync`'s own `Collections`/`Collection`/`Class`/
33
- * `CollectionId`/`SyncKey` via `SWITCH_PAGE` rather than this page's own legacy (`Folders`/`Folder`/`FolderId`)
34
- * shape - see `WbxmlCodePages.ts`'s own doc comment on `WbxmlCodePage.ItemEstimate` for why, and
35
- * `ItemOperationsCommand.fetchMessage`'s identical cross-page-reuse precedent.
36
+ * `CollectionId`/`SyncKey` via `SWITCH_PAGE` rather than this page's own legacy (`Folders`/`Folder`/`FolderId`) shape.
36
37
  *
37
- * A `SyncKey` of `"0"` (or one this device has never synced this folder with before) reports the folder's
38
- * total live item count - what a first `Sync` would report as `Add`s. Otherwise reuses `EasSyncKeyUtils.
39
- * computeChanges()` (the same enumeration `SyncCommand` itself uses), capped at `DEFAULT_MAX_COUNT` - see its
40
- * own doc comment for why this is a real, documented approximation on a very active folder rather than a
41
- * precise unbounded count.
38
+ * The collection's `EasCollectionState` (the same per-device row `SyncCommand` keeps) decides the estimate: a
39
+ * `SyncKey` of `"0"` reports the folder's total live item count (what the first `Sync` would `Add`); the
40
+ * collection's current `SyncKey` runs `SyncCommand`'s own enumeration as a dry run (nothing persisted), capped at
41
+ * `mail:eas:item_estimate_max_count`; any other key is Status 2. A request without `Class` falls back to the class
42
+ * remembered for the collection, then to the folder's type.
42
43
  *
43
- * **ACL-checked like `Sync`**: `estimateCollection()` requires `ACLAction.READ` on the client-supplied
44
- * `CollectionId` before counting anything - without it, a crafted `CollectionId` belonging to another
45
- * mailbox's folder would return a real pending-change count for it. A denied folder is reported identically to
46
- * an unrecognized collection (`Status 2`), never distinguishable from "you don't have this collection at all".
44
+ * **Bounded like `Sync`**: at most `MAX_SYNC_COLLECTIONS` collections per request (more is a single Status 2), a
45
+ * `CollectionId` repeated within one request is estimated once, and a `SyncKey 0` count is capped at the same maximum.
46
+ *
47
+ * **ACL-checked like `Sync`**: `READ` on the client-supplied `CollectionId` is required before counting anything;
48
+ * a denied folder is reported identically to an unrecognized collection (`Status 2`).
47
49
  *
48
50
  * @author Jean-Philippe Steinmetz
49
51
  */
@@ -54,6 +56,18 @@ export class GetItemEstimateCommand {
54
56
  this.repos = new Map();
55
57
  }
56
58
  async init() {
59
+ this.folderRepo = await this._objectFactory.newInstance(RepoUtils, {
60
+ name: this.folderClass.name,
61
+ args: [this.folderClass],
62
+ });
63
+ this.collectionStateRepo = await this._objectFactory.newInstance(RepoUtils, {
64
+ name: this.collectionStateClass.name,
65
+ args: [this.collectionStateClass],
66
+ });
67
+ this.collectionChunkRepo = await this._objectFactory.newInstance(RepoUtils, {
68
+ name: this.collectionChunkClass.name,
69
+ args: [this.collectionChunkClass],
70
+ });
57
71
  for (const [collectionClass, binding] of Object.entries(this.collectionBindings)) {
58
72
  this.repos.set(collectionClass, await this._objectFactory.newInstance(RecoverableRepoUtils, {
59
73
  name: binding.entityClass.name,
@@ -62,67 +76,74 @@ export class GetItemEstimateCommand {
62
76
  }
63
77
  }
64
78
  async handle(ctx) {
65
- if (!this.aclUtils) {
79
+ if (!this.aclUtils || !this.folderRepo || !this.collectionStateRepo || !this.collectionChunkRepo) {
66
80
  throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
67
81
  }
68
82
  const collections = ctx.request ? findChild(ctx.request, "Collections") : undefined;
69
83
  const collectionEls = collections ? findChildren(collections, "Collection") : [];
70
- if (collectionEls.length === 0) {
71
- return element(WbxmlCodePage.ItemEstimate, "GetItemEstimate", [
72
- element(WbxmlCodePage.ItemEstimate, "Response", [
73
- textElement(WbxmlCodePage.ItemEstimate, "Status", "2"),
74
- ]),
75
- ]);
84
+ if (collectionEls.length === 0 || collectionEls.length > MAX_SYNC_COLLECTIONS) {
85
+ return element(WbxmlCodePage.ItemEstimate, "GetItemEstimate", [this.statusResponse("2")]);
76
86
  }
77
87
  const responses = [];
88
+ const seen = new Set();
78
89
  for (const collectionEl of collectionEls) {
90
+ const folderUid = childText(collectionEl, "CollectionId");
91
+ if (folderUid !== undefined) {
92
+ if (seen.has(folderUid)) {
93
+ continue;
94
+ }
95
+ seen.add(folderUid);
96
+ }
79
97
  responses.push(await this.estimateCollection(ctx, collectionEl));
80
98
  }
81
99
  return element(WbxmlCodePage.ItemEstimate, "GetItemEstimate", responses);
82
100
  }
101
+ statusResponse(status, extra = []) {
102
+ return element(WbxmlCodePage.ItemEstimate, "Response", [textElement(WbxmlCodePage.ItemEstimate, "Status", status), ...extra]);
103
+ }
83
104
  async estimateCollection(ctx, collectionEl) {
84
- const collectionClass = childText(collectionEl, "Class");
105
+ const requestedClass = childText(collectionEl, "Class");
85
106
  const folderUid = childText(collectionEl, "CollectionId");
86
107
  const clientSyncKey = childText(collectionEl, "SyncKey");
87
- const repo = collectionClass ? this.repos.get(collectionClass) : undefined;
88
- if (!collectionClass || !folderUid || !repo) {
89
- // Status 2 ("Invalid collection") per [MS-ASCMD] - the request named a collection this device
90
- // hasn't (or can't) sync.
91
- return element(WbxmlCodePage.ItemEstimate, "Response", [
92
- textElement(WbxmlCodePage.ItemEstimate, "Status", "2"),
93
- ]);
94
- }
95
108
  // Never count against a folder the caller can't even read - see this class's own doc comment.
96
- if (!(await this.aclUtils.hasPermission(ctx.user, folderUid, ACLAction.READ))) {
97
- return element(WbxmlCodePage.ItemEstimate, "Response", [
98
- textElement(WbxmlCodePage.ItemEstimate, "Status", "2"),
99
- ]);
109
+ if (!folderUid || !(await this.aclUtils.hasPermission(ctx.user, folderUid, ACLAction.READ))) {
110
+ return this.statusResponse("2");
100
111
  }
101
- const storedSyncKey = ctx.deviceSyncState.folderSyncKeys[folderUid];
102
- const resolution = resolveSyncKey(clientSyncKey, storedSyncKey);
103
- if (resolution.kind === "invalid") {
104
- return element(WbxmlCodePage.ItemEstimate, "Response", [
105
- textElement(WbxmlCodePage.ItemEstimate, "Status", "2"),
106
- this.collectionElement(collectionClass, folderUid, undefined),
107
- ]);
112
+ const folder = await this.folderRepo.findOne(folderUid, { ignoreACL: true });
113
+ if (!folder) {
114
+ return this.statusResponse("2");
115
+ }
116
+ const stored = (await this.collectionStateRepo.find({ mailboxUid: ctx.mailboxUid, deviceId: ctx.deviceId, folderUid }, {
117
+ ignoreACL: true,
118
+ limit: 1,
119
+ }))[0];
120
+ const collectionClass = requestedClass ?? stored?.collectionClass ?? classForFolderType(folder.type);
121
+ const repo = this.repos.get(collectionClass);
122
+ if (!repo) {
123
+ return this.statusResponse("2");
108
124
  }
109
- // A brand-new (or never-synced-by-this-device) folder: every live item would be reported as an Add on
110
- // the device's first real Sync round - a plain count() of non-deleted rows (excluded by default; see
111
- // computeChanges()'s own doc comment on this query builder behavior), not computeChanges() itself,
112
- // which would incorrectly also count this folder's entire soft-deleted history (irrelevant to a client
113
- // that has never seen any of those rows in the first place).
114
125
  let count;
115
- if (resolution.kind === "initial") {
116
- count = await repo.count({ folderUid }, { ignoreACL: true });
126
+ if (!clientSyncKey || clientSyncKey === "0") {
127
+ // Every live item would be an Add on the device's first real Sync round.
128
+ count = Math.min(await repo.count({ folderUid }, { ignoreACL: true }), this.maxCount);
129
+ }
130
+ else if (stored && clientSyncKey === stored.syncKey) {
131
+ const working = workingStateFromRow(stored, (await loadHeldSet(stored, { repo: this.collectionChunkRepo, chunkClass: this.collectionChunkClass })).ids);
132
+ const { commands } = await enumerateCollection(working, {
133
+ repo,
134
+ folderUid,
135
+ folderMailboxUid: folder.mailboxUid,
136
+ windowSize: this.maxCount,
137
+ moveScanLimit: MOVE_SCAN_LIMIT,
138
+ reconcileLimit: RECONCILE_LIMIT,
139
+ include: filterPredicate(collectionClass, working.filterType),
140
+ });
141
+ count = commands.length;
117
142
  }
118
143
  else {
119
- const changes = await computeChanges(repo, "folderUid", folderUid, resolution.key.watermark, this.maxCount);
120
- count = changes.adds.length + changes.changes.length + changes.deletes.length;
144
+ return this.statusResponse("2", [this.collectionElement(collectionClass, folderUid, undefined)]);
121
145
  }
122
- return element(WbxmlCodePage.ItemEstimate, "Response", [
123
- textElement(WbxmlCodePage.ItemEstimate, "Status", "1"),
124
- this.collectionElement(collectionClass, folderUid, count),
125
- ]);
146
+ return this.statusResponse("1", [this.collectionElement(collectionClass, folderUid, count)]);
126
147
  }
127
148
  collectionElement(collectionClass, folderUid, estimate) {
128
149
  return element(WbxmlCodePage.AirSync, "Collection", [
@@ -1 +1 @@
1
- {"version":3,"file":"GetItemEstimateCommand.js","sourceRoot":"","sources":["../../../src/commands/GetItemEstimateCommand.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GetItemEstimateCommand.js","sourceRoot":"","sources":["../../../src/commands/GetItemEstimateCommand.ts"],"names":[],"mappings":"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"}