@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.
- package/LICENSE +382 -0
- package/README.md +57 -0
- package/dist/lib/BaseDeviceSyncStateRoute.js +90 -0
- package/dist/lib/BaseDeviceSyncStateRoute.js.map +1 -0
- package/dist/lib/BaseEasRoute.js +213 -0
- package/dist/lib/BaseEasRoute.js.map +1 -0
- package/dist/lib/CompactDateTime.js +43 -0
- package/dist/lib/CompactDateTime.js.map +1 -0
- package/dist/lib/EasCommandHandler.js +2 -0
- package/dist/lib/EasCommandHandler.js.map +1 -0
- package/dist/lib/EasSyncKeyUtils.js +119 -0
- package/dist/lib/EasSyncKeyUtils.js.map +1 -0
- package/dist/lib/adapters/CalendarSyncAdapter.js +255 -0
- package/dist/lib/adapters/CalendarSyncAdapter.js.map +1 -0
- package/dist/lib/adapters/ContactsSyncAdapter.js +164 -0
- package/dist/lib/adapters/ContactsSyncAdapter.js.map +1 -0
- package/dist/lib/adapters/EasCollectionSyncAdapter.js +2 -0
- package/dist/lib/adapters/EasCollectionSyncAdapter.js.map +1 -0
- package/dist/lib/adapters/EmailSyncAdapter.js +230 -0
- package/dist/lib/adapters/EmailSyncAdapter.js.map +1 -0
- package/dist/lib/adapters/TasksSyncAdapter.js +100 -0
- package/dist/lib/adapters/TasksSyncAdapter.js.map +1 -0
- package/dist/lib/codec/WbxmlCodePages.js +706 -0
- package/dist/lib/codec/WbxmlCodePages.js.map +1 -0
- package/dist/lib/codec/WbxmlDecoder.js +154 -0
- package/dist/lib/codec/WbxmlDecoder.js.map +1 -0
- package/dist/lib/codec/WbxmlElement.js +31 -0
- package/dist/lib/codec/WbxmlElement.js.map +1 -0
- package/dist/lib/codec/WbxmlEncoder.js +88 -0
- package/dist/lib/codec/WbxmlEncoder.js.map +1 -0
- package/dist/lib/commands/ComposeMailCommand.js +187 -0
- package/dist/lib/commands/ComposeMailCommand.js.map +1 -0
- package/dist/lib/commands/FolderSyncCommand.js +150 -0
- package/dist/lib/commands/FolderSyncCommand.js.map +1 -0
- package/dist/lib/commands/GetItemEstimateCommand.js +149 -0
- package/dist/lib/commands/GetItemEstimateCommand.js.map +1 -0
- package/dist/lib/commands/ItemOperationsCommand.js +337 -0
- package/dist/lib/commands/ItemOperationsCommand.js.map +1 -0
- package/dist/lib/commands/MeetingResponseCommand.js +120 -0
- package/dist/lib/commands/MeetingResponseCommand.js.map +1 -0
- package/dist/lib/commands/MoveItemsCommand.js +103 -0
- package/dist/lib/commands/MoveItemsCommand.js.map +1 -0
- package/dist/lib/commands/PingCommand.js +145 -0
- package/dist/lib/commands/PingCommand.js.map +1 -0
- package/dist/lib/commands/ProvisionCommand.js +164 -0
- package/dist/lib/commands/ProvisionCommand.js.map +1 -0
- package/dist/lib/commands/ResolveRecipientsCommand.js +124 -0
- package/dist/lib/commands/ResolveRecipientsCommand.js.map +1 -0
- package/dist/lib/commands/SearchCommand.js +137 -0
- package/dist/lib/commands/SearchCommand.js.map +1 -0
- package/dist/lib/commands/SendMailCommand.js +18 -0
- package/dist/lib/commands/SendMailCommand.js.map +1 -0
- package/dist/lib/commands/SettingsCommand.js +138 -0
- package/dist/lib/commands/SettingsCommand.js.map +1 -0
- package/dist/lib/commands/SmartForwardCommand.js +22 -0
- package/dist/lib/commands/SmartForwardCommand.js.map +1 -0
- package/dist/lib/commands/SmartReplyCommand.js +22 -0
- package/dist/lib/commands/SmartReplyCommand.js.map +1 -0
- package/dist/lib/commands/SyncCommand.js +406 -0
- package/dist/lib/commands/SyncCommand.js.map +1 -0
- package/dist/lib/commands/mongo/FolderSyncCommandMongo.js +16 -0
- package/dist/lib/commands/mongo/FolderSyncCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js +21 -0
- package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js +18 -0
- package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js +17 -0
- package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/MoveItemsCommandMongo.js +17 -0
- package/dist/lib/commands/mongo/MoveItemsCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/ResolveRecipientsCommandMongo.js +20 -0
- package/dist/lib/commands/mongo/ResolveRecipientsCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/SearchCommandMongo.js +20 -0
- package/dist/lib/commands/mongo/SearchCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/SendMailCommandMongo.js +17 -0
- package/dist/lib/commands/mongo/SendMailCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/SettingsCommandMongo.js +16 -0
- package/dist/lib/commands/mongo/SettingsCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/SmartForwardCommandMongo.js +17 -0
- package/dist/lib/commands/mongo/SmartForwardCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/SmartReplyCommandMongo.js +17 -0
- package/dist/lib/commands/mongo/SmartReplyCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/SyncCommandMongo.js +26 -0
- package/dist/lib/commands/mongo/SyncCommandMongo.js.map +1 -0
- package/dist/lib/commands/mongo/index.js +14 -0
- package/dist/lib/commands/mongo/index.js.map +1 -0
- package/dist/lib/commands/sql/FolderSyncCommandSQL.js +16 -0
- package/dist/lib/commands/sql/FolderSyncCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js +21 -0
- package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/ItemOperationsCommandSQL.js +18 -0
- package/dist/lib/commands/sql/ItemOperationsCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/MeetingResponseCommandSQL.js +17 -0
- package/dist/lib/commands/sql/MeetingResponseCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/MoveItemsCommandSQL.js +17 -0
- package/dist/lib/commands/sql/MoveItemsCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/ResolveRecipientsCommandSQL.js +20 -0
- package/dist/lib/commands/sql/ResolveRecipientsCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/SearchCommandSQL.js +20 -0
- package/dist/lib/commands/sql/SearchCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/SendMailCommandSQL.js +17 -0
- package/dist/lib/commands/sql/SendMailCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/SettingsCommandSQL.js +16 -0
- package/dist/lib/commands/sql/SettingsCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/SmartForwardCommandSQL.js +17 -0
- package/dist/lib/commands/sql/SmartForwardCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/SmartReplyCommandSQL.js +17 -0
- package/dist/lib/commands/sql/SmartReplyCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/SyncCommandSQL.js +26 -0
- package/dist/lib/commands/sql/SyncCommandSQL.js.map +1 -0
- package/dist/lib/commands/sql/index.js +14 -0
- package/dist/lib/commands/sql/index.js.map +1 -0
- package/dist/lib/index.js +56 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/mongo/DeviceSyncStateRouteMongo.js +16 -0
- package/dist/lib/mongo/DeviceSyncStateRouteMongo.js.map +1 -0
- package/dist/lib/mongo/EasRouteMongo.js +51 -0
- package/dist/lib/mongo/EasRouteMongo.js.map +1 -0
- package/dist/lib/mongo/index.js +8 -0
- package/dist/lib/mongo/index.js.map +1 -0
- package/dist/lib/mongo.js +6 -0
- package/dist/lib/mongo.js.map +1 -0
- package/dist/lib/sql/DeviceSyncStateRouteSQL.js +16 -0
- package/dist/lib/sql/DeviceSyncStateRouteSQL.js.map +1 -0
- package/dist/lib/sql/EasRouteSQL.js +50 -0
- package/dist/lib/sql/EasRouteSQL.js.map +1 -0
- package/dist/lib/sql/index.js +8 -0
- package/dist/lib/sql/index.js.map +1 -0
- package/dist/lib/sql.js +6 -0
- package/dist/lib/sql.js.map +1 -0
- package/dist/types/BaseDeviceSyncStateRoute.d.ts +34 -0
- package/dist/types/BaseEasRoute.d.ts +64 -0
- package/dist/types/CompactDateTime.d.ts +22 -0
- package/dist/types/EasCommandHandler.d.ts +59 -0
- package/dist/types/EasSyncKeyUtils.d.ts +89 -0
- package/dist/types/adapters/CalendarSyncAdapter.d.ts +52 -0
- package/dist/types/adapters/ContactsSyncAdapter.d.ts +33 -0
- package/dist/types/adapters/EasCollectionSyncAdapter.d.ts +52 -0
- package/dist/types/adapters/EmailSyncAdapter.d.ts +53 -0
- package/dist/types/adapters/TasksSyncAdapter.d.ts +32 -0
- package/dist/types/codec/WbxmlCodePages.d.ts +45 -0
- package/dist/types/codec/WbxmlDecoder.d.ts +33 -0
- package/dist/types/codec/WbxmlElement.d.ts +43 -0
- package/dist/types/codec/WbxmlEncoder.d.ts +20 -0
- package/dist/types/commands/ComposeMailCommand.d.ts +50 -0
- package/dist/types/commands/FolderSyncCommand.d.ts +25 -0
- package/dist/types/commands/GetItemEstimateCommand.d.ts +43 -0
- package/dist/types/commands/ItemOperationsCommand.d.ts +72 -0
- package/dist/types/commands/MeetingResponseCommand.d.ts +32 -0
- package/dist/types/commands/MoveItemsCommand.d.ts +29 -0
- package/dist/types/commands/PingCommand.d.ts +33 -0
- package/dist/types/commands/ProvisionCommand.d.ts +54 -0
- package/dist/types/commands/ResolveRecipientsCommand.d.ts +34 -0
- package/dist/types/commands/SearchCommand.d.ts +39 -0
- package/dist/types/commands/SendMailCommand.d.ts +10 -0
- package/dist/types/commands/SettingsCommand.d.ts +37 -0
- package/dist/types/commands/SmartForwardCommand.d.ts +17 -0
- package/dist/types/commands/SmartReplyCommand.d.ts +17 -0
- package/dist/types/commands/SyncCommand.d.ts +100 -0
- package/dist/types/commands/mongo/FolderSyncCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/GetItemEstimateCommandMongo.d.ts +7 -0
- package/dist/types/commands/mongo/ItemOperationsCommandMongo.d.ts +9 -0
- package/dist/types/commands/mongo/MeetingResponseCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/MoveItemsCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/ResolveRecipientsCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/SearchCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/SendMailCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/SettingsCommandMongo.d.ts +7 -0
- package/dist/types/commands/mongo/SmartForwardCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/SmartReplyCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/SyncCommandMongo.d.ts +8 -0
- package/dist/types/commands/mongo/index.d.ts +9 -0
- package/dist/types/commands/sql/FolderSyncCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/GetItemEstimateCommandSQL.d.ts +7 -0
- package/dist/types/commands/sql/ItemOperationsCommandSQL.d.ts +9 -0
- package/dist/types/commands/sql/MeetingResponseCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/MoveItemsCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/ResolveRecipientsCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/SearchCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/SendMailCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/SettingsCommandSQL.d.ts +7 -0
- package/dist/types/commands/sql/SmartForwardCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/SmartReplyCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/SyncCommandSQL.d.ts +8 -0
- package/dist/types/commands/sql/index.d.ts +9 -0
- package/dist/types/index.d.ts +51 -0
- package/dist/types/mongo/DeviceSyncStateRouteMongo.d.ts +8 -0
- package/dist/types/mongo/EasRouteMongo.d.ts +14 -0
- package/dist/types/mongo/index.d.ts +3 -0
- package/dist/types/mongo.d.ts +1 -0
- package/dist/types/sql/DeviceSyncStateRouteSQL.d.ts +8 -0
- package/dist/types/sql/EasRouteSQL.d.ts +13 -0
- package/dist/types/sql/index.d.ts +3 -0
- package/dist/types/sql.d.ts +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
11
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
12
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
13
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
14
|
+
import { ApiError, ObjectDecorators } from "@rapidrest/core";
|
|
15
|
+
import { ApiErrorMessages, ApiErrors, RepoUtils } from "@rapidrest/service-core";
|
|
16
|
+
import { WbxmlCodePage } from "../codec/WbxmlCodePages.js";
|
|
17
|
+
import { childText, element, textElement } from "../codec/WbxmlElement.js";
|
|
18
|
+
import { computeChanges, formatSyncKey, persistDeviceSyncState, resolveSyncKey } from "../EasSyncKeyUtils.js";
|
|
19
|
+
import { FolderType } from "@rapidmx/restapi";
|
|
20
|
+
const { Config, Init } = ObjectDecorators;
|
|
21
|
+
/** Maps this library's `FolderType` to the closest MS-ASCMD folder type code. Several of this app's types
|
|
22
|
+
* collapse onto the spec's "default well-known folder" codes rather than distinguishing a default folder from
|
|
23
|
+
* a second, user-created folder of the same content type (e.g. a second calendar also reports as `8`) - a
|
|
24
|
+
* deliberate pragmatic-subset simplification, not an oversight; see `BaseFolderRoute`'s own precedent for
|
|
25
|
+
* this library's general stance on this kind of gap. */
|
|
26
|
+
const FOLDER_TYPE_CODES = {
|
|
27
|
+
[FolderType.INBOX]: "2",
|
|
28
|
+
[FolderType.DRAFTS]: "3",
|
|
29
|
+
[FolderType.DELETED_ITEMS]: "4",
|
|
30
|
+
[FolderType.SENT_ITEMS]: "5",
|
|
31
|
+
[FolderType.OUTBOX]: "6",
|
|
32
|
+
[FolderType.TASKS]: "7",
|
|
33
|
+
[FolderType.CALENDAR]: "8",
|
|
34
|
+
[FolderType.CONTACTS]: "9",
|
|
35
|
+
[FolderType.NOTES]: "10",
|
|
36
|
+
[FolderType.JUNK]: "12",
|
|
37
|
+
[FolderType.USER]: "12",
|
|
38
|
+
};
|
|
39
|
+
/** EAS represents "no parent" (a top-level folder) as the literal string `"0"`, not an absent element. */
|
|
40
|
+
const ROOT_PARENT_ID = "0";
|
|
41
|
+
/** The (somewhat arbitrary, since `FolderSync` covers the whole mailbox's folder hierarchy rather than one
|
|
42
|
+
* particular folder) key `DeviceSyncState.folderSyncKeys` is stored under for this cursor - distinct from any
|
|
43
|
+
* real `Folder.uid`, which is exactly why using the mailbox's own uid here would be ambiguous. */
|
|
44
|
+
const FOLDER_HIERARCHY_CURSOR_KEY = "$foldersync";
|
|
45
|
+
/** Caps how many folder changes are enumerated per round - real mailboxes rarely have more than a few dozen
|
|
46
|
+
* folders, so this is generous, not a real-world binding constraint; it exists so `computeChanges()`'s
|
|
47
|
+
* `MoreAvailable` mechanism is exercised the same way it will be for `SyncCommand`'s much larger item
|
|
48
|
+
* collections. */
|
|
49
|
+
const DEFAULT_WINDOW_SIZE = 512;
|
|
50
|
+
/**
|
|
51
|
+
* Handles EAS `FolderSync`: enumerates `Add`/`Update`/`Delete`s for the caller's mailbox's `Folder` hierarchy
|
|
52
|
+
* since the device's last `FolderSync`, using the shared watermark-based cursor mechanism in
|
|
53
|
+
* `EasSyncKeyUtils.ts` (scoped by `mailboxUid` over the `Folder` collection, rather than `folderUid` over a
|
|
54
|
+
* per-folder item collection the way `SyncCommand` will be).
|
|
55
|
+
*
|
|
56
|
+
* `folderClass` is supplied by the Mongo/SQL concrete subclasses, following the exact one-line-per-backend
|
|
57
|
+
* pattern used throughout this library's other routes/jobs.
|
|
58
|
+
*
|
|
59
|
+
* @author Jean-Philippe Steinmetz
|
|
60
|
+
*/
|
|
61
|
+
export class FolderSyncCommand {
|
|
62
|
+
constructor() {
|
|
63
|
+
this.command = "FolderSync";
|
|
64
|
+
this.windowSize = DEFAULT_WINDOW_SIZE;
|
|
65
|
+
}
|
|
66
|
+
async init() {
|
|
67
|
+
this.folderRepo = await this._objectFactory.newInstance(RepoUtils, {
|
|
68
|
+
name: this.folderClass.name,
|
|
69
|
+
args: [this.folderClass],
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async handle(ctx) {
|
|
73
|
+
if (!this.folderRepo) {
|
|
74
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
75
|
+
}
|
|
76
|
+
const clientSyncKey = ctx.request ? childText(ctx.request, "SyncKey") : undefined;
|
|
77
|
+
const storedSyncKey = ctx.deviceSyncState.folderSyncKeys[FOLDER_HIERARCHY_CURSOR_KEY];
|
|
78
|
+
const resolution = resolveSyncKey(clientSyncKey, storedSyncKey);
|
|
79
|
+
if (resolution.kind === "invalid") {
|
|
80
|
+
return element(WbxmlCodePage.FolderHierarchy, "FolderSync", [
|
|
81
|
+
textElement(WbxmlCodePage.FolderHierarchy, "Status", "3"),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
if (resolution.kind === "initial") {
|
|
85
|
+
// Per spec: the first response to SyncKey "0" never returns items itself, only establishes a
|
|
86
|
+
// cursor - but that cursor's watermark must be the epoch, not "now": the client's *next* request
|
|
87
|
+
// (with this key) is its true first full sync and must report every existing folder as an Add,
|
|
88
|
+
// including ones that existed and were last modified long before this handshake ever started.
|
|
89
|
+
// Watermarking at "now" here would silently skip all of those (an epoch-old folder never appears
|
|
90
|
+
// as "modified after now"), which is exactly backwards for a brand-new device's first sync.
|
|
91
|
+
const newKey = formatSyncKey({ generation: 1, watermark: new Date(0) });
|
|
92
|
+
await this.persistSyncKey(ctx, newKey);
|
|
93
|
+
return element(WbxmlCodePage.FolderHierarchy, "FolderSync", [
|
|
94
|
+
textElement(WbxmlCodePage.FolderHierarchy, "Status", "1"),
|
|
95
|
+
textElement(WbxmlCodePage.FolderHierarchy, "SyncKey", newKey),
|
|
96
|
+
]);
|
|
97
|
+
}
|
|
98
|
+
const changes = await computeChanges(this.folderRepo, "mailboxUid", ctx.mailboxUid, resolution.key.watermark, this.windowSize);
|
|
99
|
+
const newKey = formatSyncKey({ generation: resolution.key.generation + 1, watermark: changes.newWatermark });
|
|
100
|
+
await this.persistSyncKey(ctx, newKey);
|
|
101
|
+
const totalChanges = changes.adds.length + changes.changes.length + changes.deletes.length;
|
|
102
|
+
if (totalChanges === 0) {
|
|
103
|
+
return element(WbxmlCodePage.FolderHierarchy, "FolderSync", [
|
|
104
|
+
textElement(WbxmlCodePage.FolderHierarchy, "Status", "1"),
|
|
105
|
+
textElement(WbxmlCodePage.FolderHierarchy, "SyncKey", newKey),
|
|
106
|
+
]);
|
|
107
|
+
}
|
|
108
|
+
const changeElements = [
|
|
109
|
+
...changes.adds.map((folder) => this.folderToChangeElement("Add", folder)),
|
|
110
|
+
...changes.changes.map((folder) => this.folderToChangeElement("Update", folder)),
|
|
111
|
+
...changes.deletes.map((folder) => element(WbxmlCodePage.FolderHierarchy, "Delete", [
|
|
112
|
+
textElement(WbxmlCodePage.FolderHierarchy, "ServerId", folder.uid),
|
|
113
|
+
])),
|
|
114
|
+
];
|
|
115
|
+
return element(WbxmlCodePage.FolderHierarchy, "FolderSync", [
|
|
116
|
+
textElement(WbxmlCodePage.FolderHierarchy, "Status", "1"),
|
|
117
|
+
textElement(WbxmlCodePage.FolderHierarchy, "SyncKey", newKey),
|
|
118
|
+
element(WbxmlCodePage.FolderHierarchy, "Changes", [
|
|
119
|
+
textElement(WbxmlCodePage.FolderHierarchy, "Count", String(totalChanges)),
|
|
120
|
+
...changeElements,
|
|
121
|
+
]),
|
|
122
|
+
]);
|
|
123
|
+
}
|
|
124
|
+
folderToChangeElement(kind, folder) {
|
|
125
|
+
return element(WbxmlCodePage.FolderHierarchy, kind, [
|
|
126
|
+
textElement(WbxmlCodePage.FolderHierarchy, "ServerId", folder.uid),
|
|
127
|
+
textElement(WbxmlCodePage.FolderHierarchy, "ParentId", folder.parentFolderUid ?? ROOT_PARENT_ID),
|
|
128
|
+
textElement(WbxmlCodePage.FolderHierarchy, "DisplayName", folder.name),
|
|
129
|
+
/* v8 ignore next -- unreachable via real data: FOLDER_TYPE_CODES has an entry for every FolderType
|
|
130
|
+
enum value, so the `??` fallback only guards a future enum member added to one without the
|
|
131
|
+
other; `folder.type` can never carry a value outside the enum. */
|
|
132
|
+
textElement(WbxmlCodePage.FolderHierarchy, "Type", FOLDER_TYPE_CODES[folder.type] ?? FOLDER_TYPE_CODES[FolderType.USER]),
|
|
133
|
+
]);
|
|
134
|
+
}
|
|
135
|
+
async persistSyncKey(ctx, newKey) {
|
|
136
|
+
const folderSyncKeys = { ...ctx.deviceSyncState.folderSyncKeys, [FOLDER_HIERARCHY_CURSOR_KEY]: newKey };
|
|
137
|
+
await persistDeviceSyncState(ctx.deviceSyncState, ctx.deviceSyncStateRepo, { folderSyncKeys });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
__decorate([
|
|
141
|
+
Config("mail:eas:foldersync_window_size", DEFAULT_WINDOW_SIZE),
|
|
142
|
+
__metadata("design:type", Number)
|
|
143
|
+
], FolderSyncCommand.prototype, "windowSize", void 0);
|
|
144
|
+
__decorate([
|
|
145
|
+
Init,
|
|
146
|
+
__metadata("design:type", Function),
|
|
147
|
+
__metadata("design:paramtypes", []),
|
|
148
|
+
__metadata("design:returntype", Promise)
|
|
149
|
+
], FolderSyncCommand.prototype, "init", null);
|
|
150
|
+
//# sourceMappingURL=FolderSyncCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FolderSyncCommand.js","sourceRoot":"","sources":["../../../src/commands/FolderSyncCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
11
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
12
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
13
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
14
|
+
import { ApiError, ObjectDecorators } from "@rapidrest/core";
|
|
15
|
+
import { ACLAction, ACLUtils, ApiErrorMessages, ApiErrors } from "@rapidrest/service-core";
|
|
16
|
+
import { RecoverableRepoUtils } from "@rapidmx/restapi";
|
|
17
|
+
import { WbxmlCodePage } from "../codec/WbxmlCodePages.js";
|
|
18
|
+
import { childText, element, findChild, findChildren, textElement } from "../codec/WbxmlElement.js";
|
|
19
|
+
import { computeChanges, resolveSyncKey } from "../EasSyncKeyUtils.js";
|
|
20
|
+
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. */
|
|
26
|
+
const DEFAULT_MAX_COUNT = 512;
|
|
27
|
+
/**
|
|
28
|
+
* Handles EAS `GetItemEstimate`: reports, per requested `<Collection>`, an estimated count of the
|
|
29
|
+
* `Add`/`Change`/`Delete`s a subsequent `Sync` of that collection would return - read-only, it never issues or
|
|
30
|
+
* consumes a `SyncKey` itself.
|
|
31
|
+
*
|
|
32
|
+
* 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
|
+
*
|
|
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.
|
|
42
|
+
*
|
|
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".
|
|
47
|
+
*
|
|
48
|
+
* @author Jean-Philippe Steinmetz
|
|
49
|
+
*/
|
|
50
|
+
export class GetItemEstimateCommand {
|
|
51
|
+
constructor() {
|
|
52
|
+
this.command = "GetItemEstimate";
|
|
53
|
+
this.maxCount = DEFAULT_MAX_COUNT;
|
|
54
|
+
this.repos = new Map();
|
|
55
|
+
}
|
|
56
|
+
async init() {
|
|
57
|
+
for (const [collectionClass, binding] of Object.entries(this.collectionBindings)) {
|
|
58
|
+
this.repos.set(collectionClass, await this._objectFactory.newInstance(RecoverableRepoUtils, {
|
|
59
|
+
name: binding.entityClass.name,
|
|
60
|
+
args: [binding.entityClass],
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async handle(ctx) {
|
|
65
|
+
if (!this.aclUtils) {
|
|
66
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
67
|
+
}
|
|
68
|
+
const collections = ctx.request ? findChild(ctx.request, "Collections") : undefined;
|
|
69
|
+
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
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
const responses = [];
|
|
78
|
+
for (const collectionEl of collectionEls) {
|
|
79
|
+
responses.push(await this.estimateCollection(ctx, collectionEl));
|
|
80
|
+
}
|
|
81
|
+
return element(WbxmlCodePage.ItemEstimate, "GetItemEstimate", responses);
|
|
82
|
+
}
|
|
83
|
+
async estimateCollection(ctx, collectionEl) {
|
|
84
|
+
const collectionClass = childText(collectionEl, "Class");
|
|
85
|
+
const folderUid = childText(collectionEl, "CollectionId");
|
|
86
|
+
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
|
+
// 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
|
+
]);
|
|
100
|
+
}
|
|
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
|
+
]);
|
|
108
|
+
}
|
|
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
|
+
let count;
|
|
115
|
+
if (resolution.kind === "initial") {
|
|
116
|
+
count = await repo.count({ folderUid }, { ignoreACL: true });
|
|
117
|
+
}
|
|
118
|
+
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;
|
|
121
|
+
}
|
|
122
|
+
return element(WbxmlCodePage.ItemEstimate, "Response", [
|
|
123
|
+
textElement(WbxmlCodePage.ItemEstimate, "Status", "1"),
|
|
124
|
+
this.collectionElement(collectionClass, folderUid, count),
|
|
125
|
+
]);
|
|
126
|
+
}
|
|
127
|
+
collectionElement(collectionClass, folderUid, estimate) {
|
|
128
|
+
return element(WbxmlCodePage.AirSync, "Collection", [
|
|
129
|
+
textElement(WbxmlCodePage.AirSync, "Class", collectionClass),
|
|
130
|
+
textElement(WbxmlCodePage.AirSync, "CollectionId", folderUid),
|
|
131
|
+
...(estimate !== undefined ? [textElement(WbxmlCodePage.ItemEstimate, "Estimate", String(estimate))] : []),
|
|
132
|
+
]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
__decorate([
|
|
136
|
+
Config("mail:eas:item_estimate_max_count", DEFAULT_MAX_COUNT),
|
|
137
|
+
__metadata("design:type", Number)
|
|
138
|
+
], GetItemEstimateCommand.prototype, "maxCount", void 0);
|
|
139
|
+
__decorate([
|
|
140
|
+
Inject(ACLUtils),
|
|
141
|
+
__metadata("design:type", ACLUtils)
|
|
142
|
+
], GetItemEstimateCommand.prototype, "aclUtils", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
Init,
|
|
145
|
+
__metadata("design:type", Function),
|
|
146
|
+
__metadata("design:paramtypes", []),
|
|
147
|
+
__metadata("design:returntype", Promise)
|
|
148
|
+
], GetItemEstimateCommand.prototype, "init", null);
|
|
149
|
+
//# sourceMappingURL=GetItemEstimateCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GetItemEstimateCommand.js","sourceRoot":"","sources":["../../../src/commands/GetItemEstimateCommand.ts"],"names":[],"mappings":"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"}
|