@rapidmx/mapi-plugin 1.0.0-beta.3 → 1.0.0-beta.5

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 (154) hide show
  1. package/README.md +4 -4
  2. package/dist/lib/BaseMapiEmsmdbRoute.js +229 -37
  3. package/dist/lib/BaseMapiEmsmdbRoute.js.map +1 -1
  4. package/dist/lib/MapiSessionManager.js +404 -48
  5. package/dist/lib/MapiSessionManager.js.map +1 -1
  6. package/dist/lib/RegexPatternUtils.js +30 -0
  7. package/dist/lib/RegexPatternUtils.js.map +1 -0
  8. package/dist/lib/RopDispatcher.js +130 -19
  9. package/dist/lib/RopDispatcher.js.map +1 -1
  10. package/dist/lib/codec/AppointmentRecurrence.js +22 -21
  11. package/dist/lib/codec/AppointmentRecurrence.js.map +1 -1
  12. package/dist/lib/codec/BufferCursor.js +41 -12
  13. package/dist/lib/codec/BufferCursor.js.map +1 -1
  14. package/dist/lib/codec/GlobalObjectId.js +26 -20
  15. package/dist/lib/codec/GlobalObjectId.js.map +1 -1
  16. package/dist/lib/codec/MapiTimeZone.js +43 -10
  17. package/dist/lib/codec/MapiTimeZone.js.map +1 -1
  18. package/dist/lib/codec/PropertyValue.js +28 -2
  19. package/dist/lib/codec/PropertyValue.js.map +1 -1
  20. package/dist/lib/codec/RopBuffer.js +15 -3
  21. package/dist/lib/codec/RopBuffer.js.map +1 -1
  22. package/dist/lib/mongo/MapiEmsmdbRouteMongo.js +2 -1
  23. package/dist/lib/mongo/MapiEmsmdbRouteMongo.js.map +1 -1
  24. package/dist/lib/nspi/NspiCodec.js +5 -5
  25. package/dist/lib/nspi/NspiCodec.js.map +1 -1
  26. package/dist/lib/nspi/NspiGetMatchesHandler.js +14 -14
  27. package/dist/lib/nspi/NspiGetMatchesHandler.js.map +1 -1
  28. package/dist/lib/rop/AddressList.js +109 -0
  29. package/dist/lib/rop/AddressList.js.map +1 -0
  30. package/dist/lib/rop/CalendarEventTarget.js +7 -4
  31. package/dist/lib/rop/CalendarEventTarget.js.map +1 -1
  32. package/dist/lib/rop/ContactTarget.js +2 -6
  33. package/dist/lib/rop/ContactTarget.js.map +1 -1
  34. package/dist/lib/rop/ContentsTable.js +60 -0
  35. package/dist/lib/rop/ContentsTable.js.map +1 -0
  36. package/dist/lib/rop/ExecuteBudget.js +82 -0
  37. package/dist/lib/rop/ExecuteBudget.js.map +1 -0
  38. package/dist/lib/rop/FastTransferStream.js +99 -2
  39. package/dist/lib/rop/FastTransferStream.js.map +1 -1
  40. package/dist/lib/rop/FolderTarget.js +13 -6
  41. package/dist/lib/rop/FolderTarget.js.map +1 -1
  42. package/dist/lib/rop/HandleDataCache.js +412 -0
  43. package/dist/lib/rop/HandleDataCache.js.map +1 -0
  44. package/dist/lib/rop/MeetingMessageClassHandler.js +194 -48
  45. package/dist/lib/rop/MeetingMessageClassHandler.js.map +1 -1
  46. package/dist/lib/rop/MessageBodyStream.js +33 -7
  47. package/dist/lib/rop/MessageBodyStream.js.map +1 -1
  48. package/dist/lib/rop/MessageTarget.js +17 -4
  49. package/dist/lib/rop/MessageTarget.js.map +1 -1
  50. package/dist/lib/rop/NamedPropertyRegistry.js +8 -5
  51. package/dist/lib/rop/NamedPropertyRegistry.js.map +1 -1
  52. package/dist/lib/rop/PropertyResolvers.js +3 -1
  53. package/dist/lib/rop/PropertyResolvers.js.map +1 -1
  54. package/dist/lib/rop/RepoPaging.js +54 -0
  55. package/dist/lib/rop/RepoPaging.js.map +1 -0
  56. package/dist/lib/rop/RestapiRules.js +52 -0
  57. package/dist/lib/rop/RestapiRules.js.map +1 -0
  58. package/dist/lib/rop/RopCreateMessageHandler.js +4 -2
  59. package/dist/lib/rop/RopCreateMessageHandler.js.map +1 -1
  60. package/dist/lib/rop/RopDeleteFolderHandler.js +118 -77
  61. package/dist/lib/rop/RopDeleteFolderHandler.js.map +1 -1
  62. package/dist/lib/rop/RopDeleteMessagesHandler.js +26 -1
  63. package/dist/lib/rop/RopDeleteMessagesHandler.js.map +1 -1
  64. package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js +14 -14
  65. package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js.map +1 -1
  66. package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js +13 -14
  67. package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js.map +1 -1
  68. package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js +33 -32
  69. package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js.map +1 -1
  70. package/dist/lib/rop/RopGetContentsTableHandler.js +17 -38
  71. package/dist/lib/rop/RopGetContentsTableHandler.js.map +1 -1
  72. package/dist/lib/rop/RopGetHierarchyTableHandler.js +4 -2
  73. package/dist/lib/rop/RopGetHierarchyTableHandler.js.map +1 -1
  74. package/dist/lib/rop/RopGetPropertiesSpecificHandler.js +6 -8
  75. package/dist/lib/rop/RopGetPropertiesSpecificHandler.js.map +1 -1
  76. package/dist/lib/rop/RopHandler.js +5 -1
  77. package/dist/lib/rop/RopHandler.js.map +1 -1
  78. package/dist/lib/rop/RopLogonHandler.js +5 -2
  79. package/dist/lib/rop/RopLogonHandler.js.map +1 -1
  80. package/dist/lib/rop/RopOpenFolderHandler.js +3 -1
  81. package/dist/lib/rop/RopOpenFolderHandler.js.map +1 -1
  82. package/dist/lib/rop/RopOpenMessageHandler.js +3 -1
  83. package/dist/lib/rop/RopOpenMessageHandler.js.map +1 -1
  84. package/dist/lib/rop/RopOpenStreamHandler.js +11 -8
  85. package/dist/lib/rop/RopOpenStreamHandler.js.map +1 -1
  86. package/dist/lib/rop/RopQueryRowsHandler.js +31 -5
  87. package/dist/lib/rop/RopQueryRowsHandler.js.map +1 -1
  88. package/dist/lib/rop/RopReadStreamHandler.js +22 -4
  89. package/dist/lib/rop/RopReadStreamHandler.js.map +1 -1
  90. package/dist/lib/rop/RopReleaseHandler.js +4 -1
  91. package/dist/lib/rop/RopReleaseHandler.js.map +1 -1
  92. package/dist/lib/rop/RopSaveChangesMessageHandler.js +66 -7
  93. package/dist/lib/rop/RopSaveChangesMessageHandler.js.map +1 -1
  94. package/dist/lib/rop/RopSetColumnsHandler.js +6 -8
  95. package/dist/lib/rop/RopSetColumnsHandler.js.map +1 -1
  96. package/dist/lib/rop/RopSetPropertiesHandler.js +23 -12
  97. package/dist/lib/rop/RopSetPropertiesHandler.js.map +1 -1
  98. package/dist/lib/rop/RopSubmitMessageHandler.js +148 -120
  99. package/dist/lib/rop/RopSubmitMessageHandler.js.map +1 -1
  100. package/dist/lib/rop/RopWriteStreamHandler.js +37 -10
  101. package/dist/lib/rop/RopWriteStreamHandler.js.map +1 -1
  102. package/dist/lib/rop/TaskTarget.js +2 -6
  103. package/dist/lib/rop/TaskTarget.js.map +1 -1
  104. package/dist/lib/rop/TransportSend.js +16 -0
  105. package/dist/lib/rop/TransportSend.js.map +1 -0
  106. package/dist/lib/sql/MapiEmsmdbRouteSQL.js +2 -1
  107. package/dist/lib/sql/MapiEmsmdbRouteSQL.js.map +1 -1
  108. package/dist/types/BaseMapiEmsmdbRoute.d.ts +59 -2
  109. package/dist/types/MapiSessionManager.d.ts +218 -63
  110. package/dist/types/RegexPatternUtils.d.ts +14 -0
  111. package/dist/types/RopDispatcher.d.ts +47 -11
  112. package/dist/types/codec/BufferCursor.d.ts +14 -0
  113. package/dist/types/codec/GlobalObjectId.d.ts +9 -5
  114. package/dist/types/codec/PropertyValue.d.ts +10 -0
  115. package/dist/types/codec/RopBuffer.d.ts +7 -0
  116. package/dist/types/mongo/MapiEmsmdbRouteMongo.d.ts +1 -0
  117. package/dist/types/nspi/NspiGetMatchesHandler.d.ts +2 -0
  118. package/dist/types/rop/AddressList.d.ts +48 -0
  119. package/dist/types/rop/CalendarEventTarget.d.ts +7 -3
  120. package/dist/types/rop/ContactTarget.d.ts +3 -3
  121. package/dist/types/rop/ContentsTable.d.ts +16 -0
  122. package/dist/types/rop/ExecuteBudget.d.ts +48 -0
  123. package/dist/types/rop/FastTransferStream.d.ts +41 -2
  124. package/dist/types/rop/FolderTarget.d.ts +3 -2
  125. package/dist/types/rop/HandleDataCache.d.ts +145 -0
  126. package/dist/types/rop/MeetingMessageClassHandler.d.ts +23 -29
  127. package/dist/types/rop/MessageBodyStream.d.ts +16 -7
  128. package/dist/types/rop/MessageTarget.d.ts +10 -3
  129. package/dist/types/rop/NamedPropertyRegistry.d.ts +6 -2
  130. package/dist/types/rop/PropertyResolvers.d.ts +1 -1
  131. package/dist/types/rop/RepoPaging.d.ts +30 -0
  132. package/dist/types/rop/RestapiRules.d.ts +32 -0
  133. package/dist/types/rop/RopCreateMessageHandler.d.ts +1 -0
  134. package/dist/types/rop/RopDeleteFolderHandler.d.ts +36 -21
  135. package/dist/types/rop/RopDeleteMessagesHandler.d.ts +7 -0
  136. package/dist/types/rop/RopFastTransferSourceCopyPropertiesHandler.d.ts +1 -0
  137. package/dist/types/rop/RopFastTransferSourceCopyToHandler.d.ts +1 -0
  138. package/dist/types/rop/RopFastTransferSourceGetBufferHandler.d.ts +10 -11
  139. package/dist/types/rop/RopGetContentsTableHandler.d.ts +7 -13
  140. package/dist/types/rop/RopGetHierarchyTableHandler.d.ts +1 -0
  141. package/dist/types/rop/RopHandler.d.ts +40 -1
  142. package/dist/types/rop/RopOpenFolderHandler.d.ts +1 -0
  143. package/dist/types/rop/RopOpenMessageHandler.d.ts +1 -0
  144. package/dist/types/rop/RopOpenStreamHandler.d.ts +1 -0
  145. package/dist/types/rop/RopQueryRowsHandler.d.ts +3 -0
  146. package/dist/types/rop/RopReadStreamHandler.d.ts +3 -1
  147. package/dist/types/rop/RopReleaseHandler.d.ts +1 -0
  148. package/dist/types/rop/RopSaveChangesMessageHandler.d.ts +16 -1
  149. package/dist/types/rop/RopSubmitMessageHandler.d.ts +33 -23
  150. package/dist/types/rop/RopWriteStreamHandler.d.ts +18 -8
  151. package/dist/types/rop/TaskTarget.d.ts +3 -3
  152. package/dist/types/rop/TransportSend.d.ts +10 -0
  153. package/dist/types/sql/MapiEmsmdbRouteSQL.d.ts +1 -0
  154. package/package.json +3 -3
@@ -2,14 +2,18 @@
2
2
  // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
3
  // SPDX-License-Identifier: MPL-2.0
4
4
  ///////////////////////////////////////////////////////////////////////////////
5
- import { AttendeeResponseStatus } from "@rapidmx/restapi";
5
+ import MailComposer from "nodemailer/lib/mail-composer/index.js";
6
+ import { AttendeeResponseStatus, buildEventIcs } from "@rapidmx/restapi";
6
7
  import { BufferReader } from "../codec/BufferCursor.js";
7
- import { decodeGlobalObjectId } from "../codec/GlobalObjectId.js";
8
+ import { isPlainEmailAddress } from "./AddressList.js";
9
+ import { decodeGlobalObjectId, globalObjectIdInstanceDate } from "../codec/GlobalObjectId.js";
8
10
  import { LID_GLOBAL_OBJECT_ID, PSETID_MEETING } from "./CalendarNamedProperties.js";
9
11
  import { resolveNamedProperty } from "./NamedPropertyRegistry.js";
12
+ import { asEntity, boundIndexedValue, literalQueryValue } from "./RestapiRules.js";
13
+ import { sendOrThrow } from "./TransportSend.js";
10
14
  /** `PidTagMessageClass` suffix -> the caller's own new `AttendeeResponseStatus`, per `[MS-OXOCAL]`'s meeting
11
15
  * response object naming convention. An unrecognized suffix (a message class this pragmatic subset doesn't
12
- * know how to interpret as a response) is simply not handled - see `submitMeetingResponse`'s own doc comment. */
16
+ * know how to interpret as a response) is answered with `MAPI_E_INVALID_PARAMETER`. */
13
17
  const RESPONSE_STATUS_BY_MESSAGE_CLASS = {
14
18
  "IPM.Schedule.Meeting.Resp.Pos": AttendeeResponseStatus.ACCEPTED,
15
19
  "IPM.Schedule.Meeting.Resp.Tent": AttendeeResponseStatus.TENTATIVE,
@@ -31,65 +35,207 @@ function findNamedPropertyValue(session, properties, guid, lid) {
31
35
  }
32
36
  return undefined;
33
37
  }
38
+ /** `MAPI_E_INVALID_PARAMETER`: not a response this server understands (unknown message class, no or malformed
39
+ * `PidLidGlobalObjectId`). */
40
+ const ERROR_INVALID_PARAMETER = 0x80070057;
41
+ /** `MAPI_E_NOT_FOUND`: no meeting in the caller's mailbox matches, or the caller isn't one of its attendees. */
42
+ const ERROR_NOT_FOUND = 0x8004010f;
43
+ /** `MAPI_E_CALL_FAILED`: the response was recorded but the iTIP `REPLY` couldn't be sent to the organizer. */
44
+ const ERROR_CALL_FAILED = 0x80004005;
34
45
  /**
35
46
  * Handles a submitted `"IPM.Schedule.Meeting.Resp.{Pos,Neg,Tent}"` message - an attendee's own response to a
36
- * meeting invite this server previously sent (`RopSubmitMessageHandler.submitAppointment`). Delegated to from
37
- * `RopSubmitMessageHandler` for that message-class prefix, instead of the ordinary mail or Appointment paths.
47
+ * meeting invite. Delegated to from `RopSubmitMessageHandler` for that message-class prefix, instead of the ordinary
48
+ * mail or Appointment paths. Returns the ROP's `ReturnValue`.
38
49
  *
39
- * Correlates the response back to the original `CalendarEvent` via `PidLidGlobalObjectId` (echoed by a real
40
- * client from the invite it's responding to - see `GlobalObjectId.ts`'s own doc comment for why this requires
41
- * no separate correlation table) and updates the caller's own `Attendee.responseStatus` in place, reusing the
42
- * exact same matching-by-mailbox-address logic `MeetingResponseCommand` (EAS's own `MeetingResponse` handler)
43
- * already implements - this is a from-scratch reimplementation of that small algorithm rather than a
44
- * cross-import, since EAS and MAPI are independent protocol verticals in this codebase with no dependency
45
- * between them.
50
+ * Mirrors restapi's `BaseCalendarEventRoute.respond()`. It correlates the response via `PidLidGlobalObjectId`
51
+ * (echoed by a real client from the invite it's responding to - see `GlobalObjectId.ts`) to **the caller's own
52
+ * copy** of the meeting: the query is scoped to the caller's `mailboxUid`, which is the access check. The
53
+ * organizer's copy (in another mailbox) is never touched here; the organizer's server applies the iTIP `REPLY` sent
54
+ * below, exactly as for a REST response. A native Outlook `GlobalObjectId` decodes to the uppercase hex form of its
55
+ * iCalendar UID, which is matched in either case.
46
56
  *
47
- * Every failure mode here (no `PidLidGlobalObjectId` set, no matching `CalendarEvent`, no resolvable mailbox,
48
- * caller isn't actually an attendee, unrecognized message-class suffix) is a silent no-op rather than an error
49
- * response - the same "don't fail the whole ROP over a stale/unresolvable reference" principle this pragmatic
50
- * subset applies throughout (e.g. `MessageTarget.resolveMessageInfo`'s own doc comment). A response that can't
51
- * be correlated or applied is simply dropped, not a reason to reject the client's `RopSubmitMessage` call.
57
+ * **One occurrence of a recurring meeting** (the `GlobalObjectId`'s instance date is set): the caller's exception
58
+ * copy for that date is used when there is one, comparing dates in the event's own time zone. Without one, the
59
+ * series is left alone - responding to one occurrence must not change or delete every other occurrence. Declining
60
+ * adds the occurrence to the caller's series `recurrenceRule.exceptions` (so it leaves their calendar); accepting or
61
+ * tentatively accepting changes nothing locally. Either way the `REPLY` names just that occurrence (`RECURRENCE-ID`).
52
62
  *
53
- * **The one query in this package that isn't `mailboxUid`-scoped, and why that's unavoidable here**: unlike
54
- * every other `ignoreACL: true` repo call in this codebase (all transitively scoped to the caller's own
55
- * mailbox via a session FID/MID registry that itself only ever gets populated from mailbox-scoped queries),
56
- * `calendarEventRepo.find({ icalUid })` below deliberately searches *every* mailbox on this server - the
57
- * `CalendarEvent` being responded to belongs to the meeting's *organizer*, who is very often a different
58
- * mailbox than the attendee submitting this response, and the caller's own session has no way to know which
59
- * mailbox that is. Safety instead comes from two independent properties: `icalUid` is a server-generated
60
- * `crypto.randomUUID()` (see `RopSaveChangesMessageHandler.saveAppointment`), for all practical purposes
61
- * globally unique, so this can't be used to enumerate or collide with another organizer's events; and the
62
- * actual authorization gate is the attendee-membership check a few lines down (`callerAddresses.has(...)`),
63
- * derived entirely from *this* caller's own resolved mailbox record, not from anything the client supplied -
64
- * a crafted `PidLidGlobalObjectId` can at best name a real `icalUid` it doesn't already know the value of
65
- * (astronomically unlikely against a random UUID) and still can't mutate an event unless the caller's own
66
- * mailbox is genuinely a listed attendee on it.
63
+ * **The whole meeting** (no instance date, or a copy that doesn't recur): the caller's `Attendee.responseStatus` is
64
+ * recorded; declining soft-deletes the caller's copy instead. Declining an occurrence through its exception copy also
65
+ * adds that occurrence to the series' exceptions, so the series doesn't show it again. Every update is versioned
66
+ * (`asEntity`), so a concurrent change fails the response instead of being overwritten.
67
+ *
68
+ * The `REPLY` (restapi's own `buildEventIcs`) goes out through `sendOrThrow`, so a transport that rejects it is
69
+ * reported as `MAPI_E_CALL_FAILED` instead of success; the response itself stays recorded. An organizer or attendee
70
+ * address that isn't a plain SMTP address is not mailed at all. A response that can't be matched to a meeting the
71
+ * caller attends is an error (`MAPI_E_NOT_FOUND`/`MAPI_E_INVALID_PARAMETER`), not a silent success.
67
72
  */
68
73
  export async function submitMeetingResponse(messageClass, draftProperties, context) {
69
74
  const responseStatus = RESPONSE_STATUS_BY_MESSAGE_CLASS[messageClass];
70
- if (!responseStatus) {
71
- return;
72
- }
73
- const globalObjectIdBase64 = findNamedPropertyValue(context.session, draftProperties, PSETID_MEETING, LID_GLOBAL_OBJECT_ID);
75
+ const globalObjectIdBase64 = responseStatus
76
+ ? findNamedPropertyValue(context.session, draftProperties, PSETID_MEETING, LID_GLOBAL_OBJECT_ID)
77
+ : undefined;
74
78
  if (!globalObjectIdBase64) {
75
- return;
79
+ return ERROR_INVALID_PARAMETER;
76
80
  }
77
- const icalUid = decodeGlobalObjectId(new BufferReader(Buffer.from(globalObjectIdBase64, "base64")));
78
- const events = await context.calendarEventRepo.find({ icalUid }, { ignoreACL: true, limit: 1 });
79
- const event = events[0];
80
- if (!event) {
81
- return;
81
+ const globalObjectId = Buffer.from(globalObjectIdBase64, "base64");
82
+ let icalUid;
83
+ try {
84
+ icalUid = decodeGlobalObjectId(new BufferReader(globalObjectId));
82
85
  }
83
- const mailbox = await context.mailboxRepo.findOne(context.mailboxUid, { ignoreACL: true });
84
- if (!mailbox) {
85
- return;
86
+ catch {
87
+ return ERROR_INVALID_PARAMETER;
88
+ }
89
+ const copies = await findCallerCopies(context, icalUid);
90
+ const picked = pickOccurrence(copies, globalObjectIdInstanceDate(globalObjectId));
91
+ const mailbox = picked ? await context.mailboxRepo.findOne(context.mailboxUid, { ignoreACL: true }) : undefined;
92
+ if (!picked || !mailbox) {
93
+ return ERROR_NOT_FOUND;
86
94
  }
95
+ const { event, occurrence } = picked;
87
96
  const callerAddresses = new Set([mailbox.primarySmtpAddress.toLowerCase(), ...mailbox.aliasAddresses.map((a) => a.toLowerCase())]);
88
- const attendeeIndex = event.attendees.findIndex((attendee) => callerAddresses.has(attendee.address.toLowerCase()));
89
- if (attendeeIndex === -1) {
97
+ const respondingAttendee = event.attendees.find((attendee) => callerAddresses.has(attendee.address.toLowerCase()));
98
+ if (!respondingAttendee) {
99
+ return ERROR_NOT_FOUND;
100
+ }
101
+ const updatedAttendee = { ...respondingAttendee, responseStatus };
102
+ let replyEvent = event;
103
+ if (occurrence) {
104
+ if (responseStatus === AttendeeResponseStatus.DECLINED) {
105
+ await addSeriesException(context, event, occurrence);
106
+ }
107
+ const duration = new Date(event.endDate).getTime() - new Date(event.startDate).getTime();
108
+ replyEvent = { ...event, recurrenceRule: undefined, recurrenceId: occurrence, startDate: occurrence, endDate: new Date(occurrence.getTime() + duration) };
109
+ }
110
+ else if (responseStatus === AttendeeResponseStatus.DECLINED) {
111
+ await context.calendarEventRepo.delete(event.uid, { ignoreACL: true });
112
+ // Declining an occurrence that has its own exception copy: deleting the copy alone would bring the series'
113
+ // original occurrence back, so it is excluded from the series too (as restapi's ScanQueueJob does for an
114
+ // occurrence CANCEL).
115
+ const series = copies.find((copy) => copy.recurrenceId == null);
116
+ if (event.recurrenceId != null && series?.recurrenceRule) {
117
+ await addSeriesException(context, series, new Date(event.recurrenceId));
118
+ }
119
+ }
120
+ else {
121
+ const attendees = event.attendees.map((attendee) => (attendee === respondingAttendee ? updatedAttendee : attendee));
122
+ await context.calendarEventRepo.update({ uid: event.uid, version: event.version, attendees }, asEntity(context.calendarEventRepo, event), {
123
+ ignoreACL: true,
124
+ });
125
+ }
126
+ try {
127
+ await sendReply(context, replyEvent, updatedAttendee, mailbox.displayName);
128
+ }
129
+ catch {
130
+ return ERROR_CALL_FAILED;
131
+ }
132
+ return 0;
133
+ }
134
+ /** The most copies of one meeting (series plus exceptions) considered in the caller's mailbox. */
135
+ const MAX_EVENT_COPIES = 100;
136
+ const REPLY_SUBJECT_PREFIX = {
137
+ [AttendeeResponseStatus.ACCEPTED]: "Accepted",
138
+ [AttendeeResponseStatus.TENTATIVE]: "Tentative",
139
+ [AttendeeResponseStatus.DECLINED]: "Declined",
140
+ };
141
+ /** Adds `occurrence` to `series`' recurrence exceptions (a versioned update), unless it is already there. */
142
+ async function addSeriesException(context, series, occurrence) {
143
+ const rule = series.recurrenceRule;
144
+ const exceptions = (rule.exceptions ?? []).map((date) => new Date(date));
145
+ if (exceptions.some((date) => date.getTime() === occurrence.getTime())) {
146
+ return;
147
+ }
148
+ const recurrenceRule = { ...rule, exceptions: [...exceptions, occurrence] };
149
+ await context.calendarEventRepo.update({ uid: series.uid, version: series.version, recurrenceRule }, asEntity(context.calendarEventRepo, series), {
150
+ ignoreACL: true,
151
+ });
152
+ }
153
+ /**
154
+ * The caller's copies of the meeting `icalUid` names. An `OutlookID`'s hex UID may have been stored in either case, so a
155
+ * miss is retried in lower case.
156
+ *
157
+ * The UID comes from the client (and originally from whoever sent the invite), so it is looked up the way restapi
158
+ * stores it (`boundIndexedValue`, hashed past 255 characters), matched literally (a UID like `ne(x)` is not an
159
+ * operator), and every returned row's `icalUid` is compared again.
160
+ */
161
+ async function findCallerCopies(context, icalUid) {
162
+ const find = async (uid) => {
163
+ const key = boundIndexedValue(uid);
164
+ try {
165
+ const rows = await context.calendarEventRepo.find({ icalUid: literalQueryValue(key), mailboxUid: context.mailboxUid, limit: MAX_EVENT_COPIES }, { ignoreACL: true, limit: MAX_EVENT_COPIES });
166
+ return rows.filter((row) => row.icalUid === key);
167
+ }
168
+ catch {
169
+ return []; // a UID the query layer can't take as a value matches nothing
170
+ }
171
+ };
172
+ const events = await find(icalUid);
173
+ return events.length > 0 || icalUid.toLowerCase() === icalUid ? events : find(icalUid.toLowerCase());
174
+ }
175
+ /** `timeZone` when `Intl` accepts it, otherwise `"UTC"`. */
176
+ function usableTimeZone(timeZone) {
177
+ try {
178
+ return new Intl.DateTimeFormat("en-US", { timeZone: timeZone || "UTC" }).resolvedOptions().timeZone;
179
+ }
180
+ catch {
181
+ return "UTC";
182
+ }
183
+ }
184
+ /** `date`'s calendar date (`YYYY-MM-DD`) in `timeZone`. */
185
+ function dateInZone(date, timeZone) {
186
+ return new Intl.DateTimeFormat("en-CA", { timeZone, year: "numeric", month: "2-digit", day: "2-digit" }).format(date);
187
+ }
188
+ /** How far `timeZone`'s wall clock is ahead of UTC at `date`, in milliseconds (minute precision). */
189
+ function zoneOffsetMs(date, timeZone) {
190
+ const parts = {};
191
+ const format = new Intl.DateTimeFormat("en-US", { timeZone, hourCycle: "h23", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric" });
192
+ for (const part of format.formatToParts(date)) {
193
+ parts[part.type] = part.value;
194
+ }
195
+ const wallClock = Date.UTC(Number(parts.year), Number(parts.month) - 1, Number(parts.day), Number(parts.hour), Number(parts.minute));
196
+ return wallClock - Math.floor(date.getTime() / 60000) * 60000;
197
+ }
198
+ /** The start of `series`' occurrence on `instanceDate`: the series' local start time on that date in the series'
199
+ * own time zone, so a daylight-saving change in between keeps the same wall-clock time. */
200
+ function occurrenceStart(series, instanceDate) {
201
+ const timeZone = usableTimeZone(series.timezone);
202
+ const start = new Date(series.startDate);
203
+ const days = Math.round((Date.parse(instanceDate) - Date.parse(dateInZone(start, timeZone))) / 86400000);
204
+ const shifted = new Date(start.getTime() + days * 86400000);
205
+ return new Date(shifted.getTime() - (zoneOffsetMs(shifted, timeZone) - zoneOffsetMs(start, timeZone)));
206
+ }
207
+ /**
208
+ * The copy a response applies to. For an `instanceDate`, the caller's exception copy for that date (its
209
+ * `recurrenceId`'s date in the event's time zone) when one exists; otherwise the series (no `recurrenceId`), with
210
+ * `occurrence` set to the named occurrence's start when the series recurs.
211
+ */
212
+ function pickOccurrence(events, instanceDate) {
213
+ const exception = instanceDate
214
+ ? events.find((event) => event.recurrenceId != null && dateInZone(new Date(event.recurrenceId), usableTimeZone(event.timezone)) === instanceDate)
215
+ : undefined;
216
+ const series = events.find((event) => event.recurrenceId == null);
217
+ if (exception || !series) {
218
+ return exception ? { event: exception } : undefined;
219
+ }
220
+ return { event: series, occurrence: instanceDate && series.recurrenceRule ? occurrenceStart(series, instanceDate) : undefined };
221
+ }
222
+ /** Sends the iTIP `REPLY` for `attendee`'s response to the organizer, the same message `BaseCalendarEventRoute.respond()`
223
+ * sends. Throws when the transport doesn't accept it. */
224
+ async function sendReply(context, event, attendee, displayName) {
225
+ const organizerAddress = event.organizer?.address ?? "";
226
+ if (!isPlainEmailAddress(organizerAddress) || !isPlainEmailAddress(attendee.address)) {
90
227
  return;
91
228
  }
92
- const attendees = event.attendees.map((attendee, i) => (i === attendeeIndex ? { ...attendee, responseStatus } : attendee));
93
- await context.calendarEventRepo.update({ uid: event.uid, version: event.version, attendees }, event, { ignoreACL: true });
229
+ const ics = buildEventIcs({ ...event, attendees: [attendee] }, "REPLY", { onlyAttendee: attendee });
230
+ const raw = await new MailComposer({
231
+ from: { name: displayName ?? "", address: attendee.address },
232
+ to: organizerAddress,
233
+ subject: `${REPLY_SUBJECT_PREFIX[attendee.responseStatus]}: ${event.title}`,
234
+ text: `${attendee.displayName ?? attendee.address} has responded ${attendee.responseStatus} to: ${event.title}`,
235
+ icalEvent: { method: "reply", content: ics },
236
+ })
237
+ .compile()
238
+ .build();
239
+ await sendOrThrow(context.mailTransport, { raw, envelopeFrom: attendee.address, envelopeTo: [organizerAddress] });
94
240
  }
95
241
  //# sourceMappingURL=MeetingMessageClassHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MeetingMessageClassHandler.js","sourceRoot":"","sources":["../../../src/rop/MeetingMessageClassHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MeetingMessageClassHandler.js","sourceRoot":"","sources":["../../../src/rop/MeetingMessageClassHandler.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@
4
4
  ///////////////////////////////////////////////////////////////////////////////
5
5
  import { simpleParser } from "mailparser";
6
6
  import { BufferWriter } from "../codec/BufferCursor.js";
7
+ import { handleDataCache, handleDataKey } from "./HandleDataCache.js";
7
8
  /** `PidTagBody` (`[MS-OXPROPS]`): property ID `0x1000`, `PtypString`. The only streamable property this
8
9
  * pragmatic subset supports via `RopOpenStream`/`RopReadStream` - `PidTagHtml`/`PidTagRtfCompressed` are a
9
10
  * documented gap (see `RopOpenStreamHandler`'s own doc comment). */
@@ -20,23 +21,48 @@ export const PID_TAG_BODY = 0x1000;
20
21
  * `sanitizedHtmlBlobKey` - `PidTagBody` is specifically the plain-text body per `[MS-OXPROPS]`, unlike EAS's
21
22
  * `Body` element, which can carry either format tagged by its own `Type` field.
22
23
  *
23
- * Recomputed on every call rather than cached anywhere (including on the `"stream"` handle itself) -
24
- * `MapiSessionContext` is serialized through `RedisCache`'s JSON round trip for multi-instance deployments, so
25
- * a raw `Buffer` stored there wouldn't survive it (the same class of gap this codebase already documented for
26
- * `Date` fields, see `MapiSessionContext`'s own doc comment). A documented, pragmatic trade-off: a large body
27
- * read across several `RopReadStream` calls re-parses the MIME source each time rather than once - correct,
28
- * not byte-perfect-efficient.
24
+ * Does no caching itself - `loadStreamBody` below is what the stream ROPs call. With a `budget`, nothing is fetched
25
+ * once its bytes are used up, and the raw message's size is charged before it is parsed.
29
26
  */
30
- export async function resolveMessageBodyBytes(target, messageRepo, blobStore) {
27
+ export async function resolveMessageBodyBytes(target, messageRepo, blobStore, budget) {
28
+ budget?.assertBytesLeft();
31
29
  const uid = target.slice("message:".length);
32
30
  const message = await messageRepo.findOne(uid, { ignoreACL: true });
33
31
  if (!message) {
34
32
  return Buffer.alloc(0);
35
33
  }
36
34
  const raw = await blobStore.get(message.bodyBlobKey);
35
+ budget?.chargeBytes(raw.length);
37
36
  const parsed = await simpleParser(raw);
38
37
  const writer = new BufferWriter();
39
38
  writer.writeNullTerminatedUtf16LE(parsed.text ?? "");
40
39
  return writer.toBuffer();
41
40
  }
41
+ /**
42
+ * The body bytes for the read stream at `handleIndex`. Parsed once and kept in `HandleDataCache` (outside the
43
+ * session JSON) for the life of the handle, so reading a large body in many `RopReadStream` chunks costs one
44
+ * fetch and one MIME parse instead of one per chunk. A cache miss (eviction, or a request served by another
45
+ * replica) just resolves the body again: a stored message's body never changes, so the bytes are the same.
46
+ *
47
+ * Within one `Execute`, streams opened on the same message share a single parse (`ExecuteBudget.bodies`), and each
48
+ * parse's bytes count against the request's byte budget.
49
+ */
50
+ export async function loadStreamBody(context, handleIndex, stream) {
51
+ const key = handleDataKey(context.session.uid, handleIndex, stream.generation);
52
+ const cached = handleDataCache.get(key);
53
+ if (cached) {
54
+ return cached;
55
+ }
56
+ const budget = context.budget;
57
+ let pending = budget?.bodies.get(stream.entityUid);
58
+ if (!pending) {
59
+ budget?.assertBytesLeft();
60
+ pending = resolveMessageBodyBytes(stream.entityUid, context.messageRepo, context.blobStore, budget);
61
+ budget?.bodies.set(stream.entityUid, pending);
62
+ budget?.chargeBytes((await pending).length);
63
+ }
64
+ const bytes = await pending;
65
+ handleDataCache.set(key, bytes);
66
+ return bytes;
67
+ }
42
68
  //# sourceMappingURL=MessageBodyStream.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageBodyStream.js","sourceRoot":"","sources":["../../../src/rop/MessageBodyStream.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD;;oEAEoE;AACpE,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAEnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAAc,EAAE,WAA2B,EAAE,SAAoB;IAC3G,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAwB,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"MessageBodyStream.js","sourceRoot":"","sources":["../../../src/rop/MessageBodyStream.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGtE;;oEAEoE;AACpE,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAEnC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAAc,EAAE,WAA2B,EAAE,SAAoB,EAAE,MAAsB;IACnI,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAwB,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAmB,EAAE,WAAmB,EAAE,MAAwB;IACnG,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,MAAM,EAAE,CAAC;QACT,OAAO,MAAM,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,OAAO,GAAG,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,EAAE,eAAe,EAAE,CAAC;QAC1B,OAAO,GAAG,uBAAuB,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACpG,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,EAAE,WAAW,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC;IAC5B,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,OAAO,KAAK,CAAC;AACjB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { findAllCapped, MAX_COLLECTION_ROWS } from "./RepoPaging.js";
1
2
  /** Degrades to empty-looking values for a `"message:<uid>"` target whose real `Message` has since vanished
2
3
  * (soft-deleted or otherwise), the same "don't fail the whole ROP over one stale row" principle
3
4
  * `FolderTarget.resolveFolderInfo` already applies. */
@@ -12,10 +13,12 @@ export async function resolveMessageInfo(target, messageRepo) {
12
13
  labelUids: message?.labelUids ?? [],
13
14
  };
14
15
  }
15
- /** Resolves the messages directly in `folderUid`, as `"message:<uid>"` target strings, for
16
- * `RopGetContentsTable`. */
17
- export async function resolveFolderMessages(folderUid, messageRepo) {
18
- const messages = await messageRepo.find({ folderUid }, { ignoreACL: true });
16
+ /** The order a folder's messages are listed in: newest first, ties broken by `uid` so paging is stable. */
17
+ export const MESSAGE_SORT = { receivedDate: "DESC", uid: "ASC" };
18
+ /** Resolves the messages directly in `folderUid`, newest first and capped at `MAX_COLLECTION_ROWS`, as
19
+ * `"message:<uid>"` target strings. */
20
+ export async function resolveFolderMessages(folderUid, messageRepo, budget) {
21
+ const { items: messages } = await findAllCapped(messageRepo, { folderUid }, MESSAGE_SORT, MAX_COLLECTION_ROWS, budget);
19
22
  return messages.map((m) => `message:${m.uid}`);
20
23
  }
21
24
  /**
@@ -39,6 +42,16 @@ export function assignOrGetMid(session, target) {
39
42
  const mid = session.nextMessageId++;
40
43
  session.messageIds[String(mid)] = target;
41
44
  session.messageTargetIds[target] = mid;
45
+ // MIDs are handed out consecutively, so the mapped ones are exactly [firstMessageId, nextMessageId). Past the cap
46
+ // the oldest is forgotten: opening it by that MID fails until a table row assigns the item a new one.
47
+ while (session.nextMessageId - session.firstMessageId > MAX_MESSAGE_IDS) {
48
+ const oldest = String(session.firstMessageId++);
49
+ delete session.messageTargetIds[session.messageIds[oldest]];
50
+ delete session.messageIds[oldest];
51
+ }
42
52
  return mid;
43
53
  }
54
+ /** The most MIDs one session keeps mapped. A session paging through a very large mailbox would otherwise grow its
55
+ * MID maps - saved with the session on every `Execute` - without bound. */
56
+ export const MAX_MESSAGE_IDS = 20000;
44
57
  //# sourceMappingURL=MessageTarget.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageTarget.js","sourceRoot":"","sources":["../../../src/rop/MessageTarget.ts"],"names":[],"mappings":"AAwBA;;uDAEuD;AACvD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,WAA2B;IAChF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAwB,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,OAAO;QACH,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE;QAC/B,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,IAAI,KAAK;QACnC,cAAc,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK;QAChD,YAAY,EAAE,OAAO,EAAE,YAAY,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;QAClD,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE;KACtC,CAAC;AACN,CAAC;AAED;4BAC4B;AAC5B,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,SAAiB,EAAE,WAA2B;IACtF,MAAM,QAAQ,GAAc,MAAM,WAAW,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,OAA2B,EAAE,MAAc;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC;IACpB,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IACpC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IACzC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;IACvC,OAAO,GAAG,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"MessageTarget.js","sourceRoot":"","sources":["../../../src/rop/MessageTarget.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAiB,MAAM,iBAAiB,CAAC;AAkBpF;;uDAEuD;AACvD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,WAA2B;IAChF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAwB,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,OAAO;QACH,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE;QAC/B,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,IAAI,KAAK;QACnC,cAAc,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK;QAChD,YAAY,EAAE,OAAO,EAAE,YAAY,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;QAClD,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE;KACtC,CAAC;AACN,CAAC;AAED,2GAA2G;AAC3G,MAAM,CAAC,MAAM,YAAY,GAAa,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAE3E;uCACuC;AACvC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,SAAiB,EAAE,WAA2B,EAAE,MAAsB;IAC9G,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,aAAa,CAAU,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAChI,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,OAA2B,EAAE,MAAc;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC;IACpB,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IACpC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IACzC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;IACvC,kHAAkH;IAClH,sGAAsG;IACtG,OAAO,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,cAAc,GAAG,eAAe,EAAE,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QAChD,OAAO,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5D,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED;2EAC2E;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC"}
@@ -11,9 +11,12 @@ function keyFor(propertyName) {
11
11
  ? JSON.stringify({ guid: propertyName.guid.toLowerCase(), kind: "lid", lid: propertyName.lid })
12
12
  : JSON.stringify({ guid: propertyName.guid.toLowerCase(), kind: "name", name: propertyName.name });
13
13
  }
14
- /** The highest numeric property ID a `PropertyTag`'s 16-bit `PropertyId` field can carry at all - not a
15
- * pragmatic-subset choice, an absolute wire-format ceiling (`writeUInt16LE` cannot encode anything past this). */
16
- const LAST_NAMED_PROPERTY_ID = 0xffff;
14
+ /** The most distinct named properties one session registers. The registry is saved with the session on every
15
+ * `Execute`, and a name can be up to 255 bytes, so letting a client fill the whole `0x8000`-`0xFFFF` ID space
16
+ * would make every request carry megabytes of session state. Real clients register a few hundred at most. */
17
+ export const MAX_NAMED_PROPERTIES_PER_SESSION = 4096;
18
+ /** The highest numeric property ID handed out - see `MAX_NAMED_PROPERTIES_PER_SESSION`. */
19
+ const LAST_NAMED_PROPERTY_ID = FIRST_NAMED_PROPERTY_ID + MAX_NAMED_PROPERTIES_PER_SESSION - 1;
17
20
  /**
18
21
  * Returns `propertyName`'s existing numeric property ID if an earlier `RopGetPropertyIdsFromNames` call in
19
22
  * this session already assigned one, otherwise assigns and remembers the next free ID starting at
@@ -31,8 +34,8 @@ const LAST_NAMED_PROPERTY_ID = 0xffff;
31
34
  * lifetime, so a linear scan repeated once per property per row is quadratic over a session that resolves many
32
35
  * named properties.
33
36
  *
34
- * Once `nextNamedPropertyId` would exceed `LAST_NAMED_PROPERTY_ID` (32,768 distinct names already registered
35
- * this session - the entire `0x8000`-`0xFFFF` numeric ID space this pragmatic subset has to hand out), a *new*
37
+ * Once `nextNamedPropertyId` would exceed `LAST_NAMED_PROPERTY_ID` (`MAX_NAMED_PROPERTIES_PER_SESSION` distinct
38
+ * names already registered this session), a *new*
36
39
  * name can no longer be assigned a real ID; this returns `0x0000` for it instead of throwing, the exact value
37
40
  * `[MS-OXCPRPT]`'s own `RopGetPropertyIdsFromNames` processing rules already use for "this `PropertyName`
38
41
  * could not be resolved" (the same value this pragmatic subset already produces for a `Kind = 0xFF` entry) -
@@ -1 +1 @@
1
- {"version":3,"file":"NamedPropertyRegistry.js","sourceRoot":"","sources":["../../../src/rop/NamedPropertyRegistry.ts"],"names":[],"mappings":"AAmBA;;gHAEgH;AAChH,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAEvC;;;+FAG+F;AAC/F,SAAS,MAAM,CAAC,YAA0B;IACtC,OAAO,YAAY,CAAC,IAAI,KAAK,KAAK;QAC9B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,EAAE,CAAC;QAC/F,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3G,CAAC;AAED;kHACkH;AAClH,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAA2B,EAAE,YAA0B;IAC9F,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC;IACpB,CAAC;IACD,IAAI,OAAO,CAAC,mBAAmB,GAAG,sBAAsB,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IACzC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAClC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IACnC,OAAO,EAAE,CAAC;AACd,CAAC;AAED;;;;;qBAKqB;AACrB,MAAM,UAAU,oBAAoB,CAAC,OAA2B,EAAE,UAAkB;IAChF,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACjD,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"NamedPropertyRegistry.js","sourceRoot":"","sources":["../../../src/rop/NamedPropertyRegistry.ts"],"names":[],"mappings":"AAmBA;;gHAEgH;AAChH,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAEvC;;;+FAG+F;AAC/F,SAAS,MAAM,CAAC,YAA0B;IACtC,OAAO,YAAY,CAAC,IAAI,KAAK,KAAK;QAC9B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,EAAE,CAAC;QAC/F,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3G,CAAC;AAED;;6GAE6G;AAC7G,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAC;AAErD,2FAA2F;AAC3F,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,gCAAgC,GAAG,CAAC,CAAC;AAE9F;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAA2B,EAAE,YAA0B;IAC9F,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC;IACpB,CAAC;IACD,IAAI,OAAO,CAAC,mBAAmB,GAAG,sBAAsB,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IACzC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAClC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IACnC,OAAO,EAAE,CAAC;AACd,CAAC;AAED;;;;;qBAKqB;AACrB,MAAM,UAAU,oBAAoB,CAAC,OAA2B,EAAE,UAAkB;IAChF,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACjD,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC"}
@@ -246,13 +246,15 @@ export function taskValueFor(session, propertyId, propertyType, target, info) {
246
246
  * `RopQueryRowsHandler` (one call per table row) and `RopGetPropertiesSpecificHandler` (one call for the single
247
247
  * object a handle refers to). */
248
248
  export async function resolvePropertyValues(target, columns, context, cache) {
249
+ // Every row resolved counts against the request's work budget - see ExecuteBudget.
250
+ context.budget?.chargeRows();
249
251
  const isMessage = target.startsWith("message:");
250
252
  const isCalendarEvent = target.startsWith("calendarEvent:");
251
253
  const isContact = target.startsWith("contact:");
252
254
  const isTask = target.startsWith("task:");
253
255
  const folderInfo = isMessage || isCalendarEvent || isContact || isTask
254
256
  ? undefined
255
- : await resolveFolderInfo(context.mailboxUid, target, context.folderRepo, cache);
257
+ : await resolveFolderInfo(context.mailboxUid, target, context.folderRepo, cache, context.budget);
256
258
  const messageInfo = isMessage ? await resolveMessageInfo(target, context.messageRepo) : undefined;
257
259
  const calendarEventInfo = isCalendarEvent ? await resolveCalendarEventInfo(target, context.calendarEventRepo) : undefined;
258
260
  const contactInfo = isContact && context.contactRepo ? await resolveContactInfo(target, context.contactRepo) : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyResolvers.js","sourceRoot":"","sources":["../../../src/rop/PropertyResolvers.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAqB,MAAM,2BAA2B,CAAC;AAE5E,OAAO,EACH,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,eAAe,EACf,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,GAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAA2B,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,EAAqB,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAA2C,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAqB,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,OAAO,EACH,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAkB,MAAM,iBAAiB,CAAC;AAElE,8GAA8G;AAC9G,8EAA8E;AAC9E,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AACrC,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAC5C,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,+GAA+G;AAC/G,iDAAiD;AACjD,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,qBAAqB,GAAG,MAAM,CAAC;AACrC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AACvC,MAAM,6BAA6B,GAAG,MAAM,CAAC;AAC7C,MAAM,WAAW,GAAG,MAAM,CAAC;AAC3B,wFAAwF;AACxF,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B;;;;;8FAK8F;AAC9F,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AACrE,MAAM,aAAa,GAAG,UAAU,CAAC;AAEjC,sGAAsG;AACtG,gGAAgG;AAChG,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,qBAAqB,GAAG,MAAM,CAAC;AACrC,MAAM,iCAAiC,GAAG,MAAM,CAAC;AACjD,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B,0GAA0G;AAC1G,6GAA6G;AAC7G,8GAA8G;AAC9G,uEAAuE;AAEvE;;;8GAG8G;AAC9G,MAAM,UAAU,mBAAmB,CAAC,YAA0B;IAC1D,QAAQ,YAAY,EAAE,CAAC;QACnB,KAAK,YAAY,CAAC,WAAW;YACzB,OAAO,KAAK,CAAC;QACjB,KAAK,YAAY,CAAC,aAAa,CAAC;QAChC,KAAK,YAAY,CAAC,aAAa,CAAC;QAChC,KAAK,YAAY,CAAC,cAAc,CAAC;QACjC,KAAK,YAAY,CAAC,cAAc;YAC5B,OAAO,CAAC,CAAC;QACb,KAAK,YAAY,CAAC,aAAa;YAC3B,OAAO,EAAE,CAAC;QACd,KAAK,YAAY,CAAC,QAAQ;YACtB,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,KAAK,YAAY,CAAC,QAAQ;YACtB,OAAO,sCAAsC,CAAC;QAClD,KAAK,YAAY,CAAC,UAAU;YACxB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,KAAK,YAAY,CAAC,qBAAqB,CAAC;QACxC,KAAK,YAAY,CAAC,kBAAkB,CAAC;QACrC,KAAK,YAAY,CAAC,mBAAmB,CAAC;QACtC,KAAK,YAAY,CAAC,kBAAkB;YAChC,OAAO,EAAE,CAAC;QACd,KAAK,YAAY,CAAC,UAAU,CAAC;QAC7B,KAAK,YAAY,CAAC,WAAW,CAAC;QAC9B;YACI,OAAO,EAAE,CAAC;IAClB,CAAC;AACL,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,cAAc,CAC1B,OAA2B,EAC3B,UAAkB,EAClB,YAA0B,EAC1B,MAAc,EACd,IAAsB;IAEtB,QAAQ,UAAU,EAAE,CAAC;QACjB,KAAK,oBAAoB;YACrB,OAAO,IAAI,CAAC,WAAW,CAAC;QAC5B,KAAK,iBAAiB;YAClB,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QACnD,KAAK,qBAAqB;YACtB,OAAO,IAAI,CAAC,UAAU,CAAC;QAC3B,KAAK,4BAA4B;YAC7B,OAAO,IAAI,CAAC,WAAW,CAAC;QAC5B,KAAK,kBAAkB;YACnB,OAAO,IAAI,CAAC,WAAW,CAAC;QAC5B;YACI,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC;AACL,CAAC;AAED;;;uDAGuD;AACvD,MAAM,UAAU,eAAe,CAC3B,OAA2B,EAC3B,UAAkB,EAClB,YAA0B,EAC1B,MAAc,EACd,IAAuB,EACvB,aAAuB,EAAE;IAEzB,QAAQ,UAAU,EAAE,CAAC;QACjB,KAAK,eAAe;YAChB,OAAO,IAAI,CAAC,OAAO,CAAC;QACxB,KAAK,qBAAqB;YACtB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,KAAK,uBAAuB;YACxB,OAAO,IAAI,CAAC,cAAc,CAAC;QAC/B,KAAK,6BAA6B;YAC9B,OAAO,IAAI,CAAC,YAAY,CAAC;QAC7B,KAAK,WAAW;YACZ,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC,CAAC;YACN,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;gBACxD,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,qBAAqB,EAAE,CAAC;oBACvH,OAAO,UAAU,CAAC;gBACtB,CAAC;YACL,CAAC;YACD,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC7C,CAAC;IACL,CAAC;AACL,CAAC;AAED;;;;iFAIiF;AACjF,MAAM,UAAU,qBAAqB,CACjC,OAA2B,EAC3B,UAAkB,EAClB,YAA0B,EAC1B,MAAc,EACd,IAA6B,EAC7B,aAAqB;IAErB,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IACD,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,UAAU,GAAG,MAAM,EAAE,CAAC;QACtB,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACjD,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC9C,MAAM,qBAAqB,GAAG,IAAI,KAAK,kBAAkB,CAAC;IAC1D,MAAM,gBAAgB,GAAG,IAAI,KAAK,aAAa,CAAC;IAEhD,QAAQ,aAAa,CAAC,GAAG,EAAE,CAAC;QACxB,KAAK,YAAY;YACb,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC7F,KAAK,2BAA2B;YAC5B,OAAO,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACtF,KAAK,yBAAyB;YAC1B,OAAO,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACpF,KAAK,eAAe;YAChB,OAAO,qBAAqB,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC1G,KAAK,aAAa;YACd,OAAO,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACzG,KAAK,qBAAqB;YACtB,OAAO,qBAAqB,IAAI,IAAI,CAAC,cAAc;gBAC/C,CAAC,CAAC,2BAA2B,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;gBAChF,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC5C,KAAK,oBAAoB;YACrB,OAAO,qBAAqB,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC3H,KAAK,mBAAmB;YACpB,OAAO,qBAAqB,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC9G,KAAK,gBAAgB;YACjB,OAAO,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,IAAI,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC1G,KAAK,kBAAkB;YACnB,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACzG;YACI,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC;AACL,CAAC;AAED;;qFAEqF;AACrF,SAAS,iBAAiB,CAAC,IAA6B,EAAE,aAAqB;IAC3E,IAAI,aAAa,IAAI,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,KAAK,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC;QACvF,OAAO,yBAAyB,CAAC;IACrC,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC;IACrG,OAAO,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC;AAC5F,CAAC;AAED;;oGAEoG;AACpG,MAAM,UAAU,eAAe,CAC3B,OAA2B,EAC3B,UAAkB,EAClB,YAA0B,EAC1B,MAAc,EACd,IAAuB;IAEvB,QAAQ,UAAU,EAAE,CAAC;QACjB,KAAK,eAAe;YAChB,OAAO,IAAI,CAAC,WAAW,CAAC;QAC5B,KAAK,WAAW;YACZ,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QACnD,KAAK,kBAAkB;YACnB,OAAO,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QAChC,KAAK,eAAe;YAChB,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAC9B,KAAK,qBAAqB;YACtB,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5B,KAAK,iCAAiC;YAClC,OAAO,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;QACpC,KAAK,oBAAoB;YACrB,OAAO,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QAClC,KAAK,aAAa;YACd,OAAO,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC/B;YACI,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC;AACL,CAAC;AAED;;;;+DAI+D;AAC/D,MAAM,UAAU,YAAY,CACxB,OAA2B,EAC3B,UAAkB,EAClB,YAA0B,EAC1B,MAAc,EACd,IAAoB;IAEpB,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IACD,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,UAAU,GAAG,MAAM,EAAE,CAAC;QACtB,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,KAAK,KAAK,IAAI,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,WAAW,EAAE,CAAC;QACrG,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;IAED,QAAQ,aAAa,CAAC,GAAG,EAAE,CAAC;QACxB,KAAK,eAAe;YAChB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAC3E,KAAK,oBAAoB;YACrB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACtC,KAAK,iBAAiB;YAClB,OAAO,IAAI,CAAC,OAAO,IAAI,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC7D,KAAK,iBAAiB;YAClB,OAAO,IAAI,CAAC,SAAS,CAAC;QAC1B;YACI,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC;AACL,CAAC;AAmBD;;;iCAGiC;AACjC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACvC,MAAc,EACd,OAA6D,EAC7D,OAWC,EACD,KAAuB;IAEvB,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,UAAU,GACZ,SAAS,IAAI,eAAe,IAAI,SAAS,IAAI,MAAM;QAC/C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACzF,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClG,MAAM,iBAAiB,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1H,MAAM,WAAW,GAAG,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzH,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1G,IAAI,UAAU,GAAa,EAAE,CAAC;IAC9B,IAAI,WAAW,IAAI,WAAW,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACvE,IAAI,eAAoC,CAAC;QACzC,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;gBACzB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrG,KAAK,CAAC,eAAe,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAgC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvG,CAAC;YACD,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;QAC5C,CAAC;aAAM,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACrG,eAAe,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAgC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjG,CAAC;QACD,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IACnI,CAAC;IAED,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,eAAe,EAAE,CAAC;QAClB,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;gBACpC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3F,KAAK,CAAC,aAAa,GAAG,OAAO,EAAE,kBAAkB,IAAI,EAAE,CAAC;YAC5D,CAAC;YACD,aAAa,GAAG,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;QAC9C,CAAC;aAAM,CAAC;YACJ,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3F,aAAa,GAAG,OAAO,EAAE,kBAAkB,IAAI,EAAE,CAAC;QACtD,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC1B,IAAI,iBAAiB,EAAE,CAAC;YACpB,OAAO,qBAAqB,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;QACpI,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YACd,OAAO,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACzG,CAAC;QACD,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YACd,OAAO,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QACrH,CAAC;QACD,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;YACtB,iGAAiG;YACjG,gGAAgG;YAChG,gGAAgG;YAChG,sFAAsF;YACtF,OAAO,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,UAAW,CAAC,CAAC;IACxG,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"PropertyResolvers.js","sourceRoot":"","sources":["../../../src/rop/PropertyResolvers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /** `RepoUtils.find()`'s own largest page. */
2
+ export const REPO_PAGE_SIZE = 1000;
3
+ /** The most rows gathered by `findAllCapped`. */
4
+ export const MAX_COLLECTION_ROWS = 10000;
5
+ /**
6
+ * Fetches one page. `limit`/`page`/`sort` go in both the query (what the SQL query builder reads) and the options
7
+ * (what Mongo reads); without them each backend silently returns its own 100-row default in an unspecified order.
8
+ *
9
+ * With a `budget`, the query is charged before it runs and the rows it returned right after, so a request past its
10
+ * `ExecuteBudget` stops before the next query.
11
+ */
12
+ export async function findPage(repo, query, sort, page, pageSize = REPO_PAGE_SIZE, budget) {
13
+ budget?.chargeQueries();
14
+ const rows = await repo.find({ ...query, sort, limit: pageSize, page }, { ignoreACL: true, limit: pageSize, page });
15
+ budget?.chargeFetchedRows(rows.length);
16
+ return rows;
17
+ }
18
+ /**
19
+ * Fetches every row matching `query`, in `sort` order, up to `cap` rows. `truncated` is `true` when more rows may
20
+ * exist past the cap.
21
+ */
22
+ export async function findAllCapped(repo, query, sort, cap = MAX_COLLECTION_ROWS, budget) {
23
+ const items = [];
24
+ for (let page = 0;; page++) {
25
+ const rows = await findPage(repo, query, sort, page, REPO_PAGE_SIZE, budget);
26
+ items.push(...rows);
27
+ if (rows.length < REPO_PAGE_SIZE) {
28
+ return { items: items.slice(0, cap), truncated: items.length > cap };
29
+ }
30
+ if (items.length >= cap) {
31
+ return { items: items.slice(0, cap), truncated: true };
32
+ }
33
+ }
34
+ }
35
+ /**
36
+ * Fetches the rows at positions `[start, start + count)` of `query` in `sort` order, reading only the pages that
37
+ * window touches.
38
+ */
39
+ export async function findWindow(repo, query, sort, start, count, budget) {
40
+ const result = [];
41
+ let position = start;
42
+ while (result.length < count) {
43
+ const page = Math.floor(position / REPO_PAGE_SIZE);
44
+ const rows = await findPage(repo, query, sort, page, REPO_PAGE_SIZE, budget);
45
+ const taken = rows.slice(position - page * REPO_PAGE_SIZE, position - page * REPO_PAGE_SIZE + (count - result.length));
46
+ result.push(...taken);
47
+ position += taken.length;
48
+ if (rows.length < REPO_PAGE_SIZE) {
49
+ break;
50
+ }
51
+ }
52
+ return result;
53
+ }
54
+ //# sourceMappingURL=RepoPaging.js.map