@checkfirst/nestjs-outlook 6.1.2 → 6.2.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/dist/entities/microsoft-user.entity.d.ts +1 -0
- package/dist/entities/microsoft-user.entity.js +5 -0
- package/dist/entities/microsoft-user.entity.js.map +1 -1
- package/dist/migrations/1740400000000-AddDefaultCalendarIdColumn.d.ts +5 -0
- package/dist/migrations/1740400000000-AddDefaultCalendarIdColumn.js +19 -0
- package/dist/migrations/1740400000000-AddDefaultCalendarIdColumn.js.map +1 -0
- package/dist/repositories/outlook-webhook-subscription.repository.js +1 -1
- package/dist/repositories/outlook-webhook-subscription.repository.js.map +1 -1
- package/dist/services/calendar/calendar.service.d.ts +0 -1
- package/dist/services/calendar/calendar.service.js +133 -100
- package/dist/services/calendar/calendar.service.js.map +1 -1
- package/dist/services/email/email.service.js +26 -7
- package/dist/services/email/email.service.js.map +1 -1
- package/dist/services/shared/delta-sync.service.d.ts +3 -1
- package/dist/services/shared/delta-sync.service.js +26 -2
- package/dist/services/shared/delta-sync.service.js.map +1 -1
- package/dist/services/subscription/microsoft-subscription.service.js +13 -8
- package/dist/services/subscription/microsoft-subscription.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/outlook-api-executor.util.d.ts +3 -0
- package/dist/utils/outlook-api-executor.util.js +38 -45
- package/dist/utils/outlook-api-executor.util.js.map +1 -1
- package/dist/utils/retry.util.d.ts +0 -1
- package/dist/utils/retry.util.js +34 -37
- package/dist/utils/retry.util.js.map +1 -1
- package/package.json +1 -1
|
@@ -19,6 +19,7 @@ let MicrosoftUser = class MicrosoftUser {
|
|
|
19
19
|
this.tokenExpiry = new Date();
|
|
20
20
|
this.scopes = '';
|
|
21
21
|
this.isActive = true;
|
|
22
|
+
this.defaultCalendarId = null;
|
|
22
23
|
this.createdAt = new Date();
|
|
23
24
|
this.updatedAt = new Date();
|
|
24
25
|
}
|
|
@@ -53,6 +54,10 @@ __decorate([
|
|
|
53
54
|
(0, typeorm_1.Column)({ name: 'is_active', default: true }),
|
|
54
55
|
__metadata("design:type", Boolean)
|
|
55
56
|
], MicrosoftUser.prototype, "isActive", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, typeorm_1.Column)({ name: 'default_calendar_id', type: 'varchar', length: 255, nullable: true }),
|
|
59
|
+
__metadata("design:type", Object)
|
|
60
|
+
], MicrosoftUser.prototype, "defaultCalendarId", void 0);
|
|
56
61
|
__decorate([
|
|
57
62
|
(0, typeorm_1.CreateDateColumn)({ name: 'created_at' }),
|
|
58
63
|
__metadata("design:type", Date)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"microsoft-user.entity.js","sourceRoot":"","sources":["../../src/entities/microsoft-user.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAOiB;AAQV,IAAM,aAAa,GAAnB,MAAM,aAAa;IAAnB;QAML,mBAAc,GAAW,EAAE,CAAC;QAG5B,gBAAW,GAAW,EAAE,CAAC;QAGzB,iBAAY,GAAW,EAAE,CAAC;QAG1B,gBAAW,GAAS,IAAI,IAAI,EAAE,CAAC;QAG/B,WAAM,GAAW,EAAE,CAAC;QAGpB,aAAQ,GAAY,IAAI,CAAC;QAGzB,cAAS,GAAS,IAAI,IAAI,EAAE,CAAC;QAG7B,cAAS,GAAS,IAAI,IAAI,EAAE,CAAC;IAC/B,CAAC;CAAA,CAAA;
|
|
1
|
+
{"version":3,"file":"microsoft-user.entity.js","sourceRoot":"","sources":["../../src/entities/microsoft-user.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAOiB;AAQV,IAAM,aAAa,GAAnB,MAAM,aAAa;IAAnB;QAML,mBAAc,GAAW,EAAE,CAAC;QAG5B,gBAAW,GAAW,EAAE,CAAC;QAGzB,iBAAY,GAAW,EAAE,CAAC;QAG1B,gBAAW,GAAS,IAAI,IAAI,EAAE,CAAC;QAG/B,WAAM,GAAW,EAAE,CAAC;QAGpB,aAAQ,GAAY,IAAI,CAAC;QAGzB,sBAAiB,GAAkB,IAAI,CAAC;QAGxC,cAAS,GAAS,IAAI,IAAI,EAAE,CAAC;QAG7B,cAAS,GAAS,IAAI,IAAI,EAAE,CAAC;IAC/B,CAAC;CAAA,CAAA;AA/BY,sCAAa;AAExB;IADC,IAAA,gCAAsB,EAAC,WAAW,CAAC;;yCACxB;AAIZ;IAFC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;IACpC,IAAA,eAAK,GAAE;;qDACoB;AAG5B;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;kDACtB;AAGzB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;mDACtB;AAG1B;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;8BACtC,IAAI;kDAAc;AAG/B;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;6CACrB;AAGpB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;+CACpB;AAGzB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;wDAC9C;AAGxC;IADC,IAAA,0BAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;8BAC9B,IAAI;gDAAc;AAG7B;IADC,IAAA,0BAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;8BAC9B,IAAI;gDAAc;wBA9BlB,aAAa;IADzB,IAAA,gBAAM,EAAC,iBAAiB,CAAC;GACb,aAAa,CA+BzB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AddDefaultCalendarIdColumn1740400000000 = void 0;
|
|
4
|
+
const typeorm_1 = require("typeorm");
|
|
5
|
+
class AddDefaultCalendarIdColumn1740400000000 {
|
|
6
|
+
async up(queryRunner) {
|
|
7
|
+
await queryRunner.addColumn('microsoft_users', new typeorm_1.TableColumn({
|
|
8
|
+
name: 'default_calendar_id',
|
|
9
|
+
type: 'varchar',
|
|
10
|
+
length: '255',
|
|
11
|
+
isNullable: true,
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
async down(queryRunner) {
|
|
15
|
+
await queryRunner.dropColumn('microsoft_users', 'default_calendar_id');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.AddDefaultCalendarIdColumn1740400000000 = AddDefaultCalendarIdColumn1740400000000;
|
|
19
|
+
//# sourceMappingURL=1740400000000-AddDefaultCalendarIdColumn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1740400000000-AddDefaultCalendarIdColumn.js","sourceRoot":"","sources":["../../src/migrations/1740400000000-AddDefaultCalendarIdColumn.ts"],"names":[],"mappings":";;;AAAA,qCAAuE;AAEvE,MAAa,uCAAuC;IAC3C,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,SAAS,CACzB,iBAAiB,EACjB,IAAI,qBAAW,CAAC;YACd,IAAI,EAAE,qBAAqB;YAC3B,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,IAAI;SACjB,CAAC,CACH,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,UAAU,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;IACzE,CAAC;CACF;AAhBD,0FAgBC"}
|
|
@@ -77,7 +77,7 @@ let OutlookWebhookSubscriptionRepository = class OutlookWebhookSubscriptionRepos
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
async count(options) {
|
|
80
|
-
return this.repository.count(options);
|
|
80
|
+
return await this.repository.count(options);
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
exports.OutlookWebhookSubscriptionRepository = OutlookWebhookSubscriptionRepository;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outlook-webhook-subscription.repository.js","sourceRoot":"","sources":["../../src/repositories/outlook-webhook-subscription.repository.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"outlook-webhook-subscription.repository.js","sourceRoot":"","sources":["../../src/repositories/outlook-webhook-subscription.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -78,7 +78,6 @@ export declare class CalendarService {
|
|
|
78
78
|
getEventDetails(resource: string, externalUserId: string): Promise<Event | null>;
|
|
79
79
|
getEventsBatch(eventIds: string[], externalUserId: string): Promise<Event[]>;
|
|
80
80
|
private getEventsBatchInternal;
|
|
81
|
-
private extractRetryAfterFromResponse;
|
|
82
81
|
importEventsStream(externalUserId: string, options?: {
|
|
83
82
|
startDate?: Date;
|
|
84
83
|
endDate?: Date;
|
|
@@ -53,12 +53,12 @@ const typeorm_1 = require("@nestjs/typeorm");
|
|
|
53
53
|
const microsoft_user_entity_1 = require("../../entities/microsoft-user.entity");
|
|
54
54
|
const typeorm_2 = require("typeorm");
|
|
55
55
|
const delta_sync_service_1 = require("../shared/delta-sync.service");
|
|
56
|
-
const retry_util_1 = require("../../utils/retry.util");
|
|
57
56
|
const user_id_converter_service_1 = require("../shared/user-id-converter.service");
|
|
58
57
|
const resource_type_enum_1 = require("../../enums/resource-type.enum");
|
|
59
58
|
const microsoft_subscription_service_1 = require("../subscription/microsoft-subscription.service");
|
|
60
59
|
const outlook_api_executor_util_1 = require("../../utils/outlook-api-executor.util");
|
|
61
60
|
const graph_rate_limiter_service_1 = require("../shared/graph-rate-limiter.service");
|
|
61
|
+
const retry_util_1 = require("../../utils/retry.util");
|
|
62
62
|
const OUTLOOK_EVENT_CREATED = event_types_enum_1.OutlookEventTypes.EVENT_CREATED;
|
|
63
63
|
const OUTLOOK_EVENT_UPDATED = event_types_enum_1.OutlookEventTypes.EVENT_UPDATED;
|
|
64
64
|
const OUTLOOK_EVENT_DELETED = event_types_enum_1.OutlookEventTypes.EVENT_DELETED;
|
|
@@ -99,25 +99,45 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
99
99
|
}
|
|
100
100
|
async getDefaultCalendarId(externalUserId) {
|
|
101
101
|
try {
|
|
102
|
-
const
|
|
103
|
-
|
|
102
|
+
const user = await this.microsoftUserRepository.findOne({
|
|
103
|
+
where: { externalUserId, isActive: true },
|
|
104
|
+
cache: true,
|
|
105
|
+
});
|
|
106
|
+
if (!user) {
|
|
107
|
+
throw new Error(`No Microsoft user found for external user ID ${externalUserId}`);
|
|
108
|
+
}
|
|
109
|
+
if (user.defaultCalendarId) {
|
|
110
|
+
this.logger.debug(`Using cached calendar ID for user ${externalUserId}`);
|
|
111
|
+
return user.defaultCalendarId;
|
|
112
|
+
}
|
|
113
|
+
this.logger.debug(`Fetching calendar ID from Microsoft for user ${externalUserId}`);
|
|
114
|
+
const accessToken = await this.microsoftAuthService.getUserAccessToken({ externalUserId, cache: true });
|
|
115
|
+
await this.rateLimiter.acquirePermit(externalUserId);
|
|
116
|
+
const response = await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => axios_1.default.get("https://graph.microsoft.com/v1.0/me/calendar", {
|
|
104
117
|
headers: {
|
|
105
118
|
Authorization: `Bearer ${accessToken}`,
|
|
106
119
|
"Content-Type": "application/json",
|
|
107
120
|
},
|
|
121
|
+
}), {
|
|
122
|
+
logger: this.logger,
|
|
123
|
+
resourceName: `me/calendar for user ${externalUserId}`,
|
|
124
|
+
maxRetries: 3,
|
|
108
125
|
});
|
|
109
|
-
if (!response.data.id) {
|
|
126
|
+
if (!(response === null || response === void 0 ? void 0 : response.data.id)) {
|
|
110
127
|
throw new Error("Failed to retrieve calendar ID");
|
|
111
128
|
}
|
|
112
|
-
|
|
129
|
+
const calendarId = response.data.id;
|
|
130
|
+
user.defaultCalendarId = calendarId;
|
|
131
|
+
await this.microsoftUserRepository.save(user);
|
|
132
|
+
this.logger.log(`Cached calendar ID for user ${externalUserId}`);
|
|
133
|
+
return calendarId;
|
|
113
134
|
}
|
|
114
135
|
catch (error) {
|
|
115
|
-
this.logger.error(
|
|
136
|
+
this.logger.error(`Error getting default calendar ID for user ${externalUserId}:`, error);
|
|
116
137
|
throw new Error("Failed to get calendar ID from Microsoft");
|
|
117
138
|
}
|
|
118
139
|
}
|
|
119
140
|
async createEvent(event, externalUserId, calendarId) {
|
|
120
|
-
await this.rateLimiter.acquirePermit(externalUserId);
|
|
121
141
|
try {
|
|
122
142
|
const accessToken = await this.microsoftAuthService.getUserAccessToken({ externalUserId });
|
|
123
143
|
const client = microsoft_graph_client_1.Client.init({
|
|
@@ -125,9 +145,13 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
125
145
|
done(null, accessToken);
|
|
126
146
|
},
|
|
127
147
|
});
|
|
128
|
-
const createdEvent = (await client
|
|
129
|
-
.
|
|
130
|
-
|
|
148
|
+
const createdEvent = (await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => client.api(`/me/calendars/${calendarId}/events`).post(event), {
|
|
149
|
+
logger: this.logger,
|
|
150
|
+
resourceName: `create event in calendar ${calendarId} for user ${externalUserId}`,
|
|
151
|
+
maxRetries: 3,
|
|
152
|
+
rateLimiter: this.rateLimiter,
|
|
153
|
+
userId: externalUserId,
|
|
154
|
+
}));
|
|
131
155
|
return {
|
|
132
156
|
event: createdEvent,
|
|
133
157
|
};
|
|
@@ -137,12 +161,8 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
137
161
|
this.logger.error(`Failed to create Outlook calendar event: ${errorMessage}`);
|
|
138
162
|
throw new Error(`Failed to create Outlook calendar event: ${errorMessage}`);
|
|
139
163
|
}
|
|
140
|
-
finally {
|
|
141
|
-
this.rateLimiter.releasePermit(externalUserId);
|
|
142
|
-
}
|
|
143
164
|
}
|
|
144
165
|
async updateEvent(eventId, updates, externalUserId, calendarId) {
|
|
145
|
-
await this.rateLimiter.acquirePermit(externalUserId);
|
|
146
166
|
try {
|
|
147
167
|
const accessToken = await this.microsoftAuthService.getUserAccessToken({ externalUserId });
|
|
148
168
|
const client = microsoft_graph_client_1.Client.init({
|
|
@@ -151,9 +171,13 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
151
171
|
},
|
|
152
172
|
});
|
|
153
173
|
this.logger.log(`Updating event ${eventId} in calendar ${calendarId} for user ${externalUserId}`);
|
|
154
|
-
const updatedEvent = (await client
|
|
155
|
-
.
|
|
156
|
-
|
|
174
|
+
const updatedEvent = (await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => client.api(`/me/calendars/${calendarId}/events/${eventId}`).patch(updates), {
|
|
175
|
+
logger: this.logger,
|
|
176
|
+
resourceName: `update event ${eventId} in calendar ${calendarId} for user ${externalUserId}`,
|
|
177
|
+
maxRetries: 3,
|
|
178
|
+
rateLimiter: this.rateLimiter,
|
|
179
|
+
userId: externalUserId,
|
|
180
|
+
}));
|
|
157
181
|
return {
|
|
158
182
|
event: updatedEvent,
|
|
159
183
|
};
|
|
@@ -163,12 +187,8 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
163
187
|
this.logger.error(`Failed to update Outlook calendar event: ${errorMessage}`);
|
|
164
188
|
throw new Error(`Failed to update Outlook calendar event: ${errorMessage}`);
|
|
165
189
|
}
|
|
166
|
-
finally {
|
|
167
|
-
this.rateLimiter.releasePermit(externalUserId);
|
|
168
|
-
}
|
|
169
190
|
}
|
|
170
191
|
async deleteEvent(event, externalUserId, calendarId) {
|
|
171
|
-
await this.rateLimiter.acquirePermit(externalUserId);
|
|
172
192
|
try {
|
|
173
193
|
const internalUserId = await this.userIdConverter.toInternalUserId(externalUserId);
|
|
174
194
|
const accessToken = await this.microsoftAuthService.getUserAccessToken({ internalUserId });
|
|
@@ -178,24 +198,20 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
178
198
|
},
|
|
179
199
|
});
|
|
180
200
|
this.logger.log(`Deleting event ${event.id} from calendar ${calendarId} for user ${externalUserId}`);
|
|
181
|
-
await (0,
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
201
|
+
await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => client.api(`/me/calendars/${calendarId}/events/${event.id}`).delete(), {
|
|
202
|
+
logger: this.logger,
|
|
203
|
+
resourceName: `delete event ${event.id} from calendar ${calendarId} for user ${externalUserId}`,
|
|
204
|
+
maxRetries: 3,
|
|
205
|
+
rateLimiter: this.rateLimiter,
|
|
206
|
+
userId: externalUserId,
|
|
207
|
+
return404AsNull: true,
|
|
208
|
+
});
|
|
186
209
|
}
|
|
187
210
|
catch (error) {
|
|
188
|
-
if ((0, retry_util_1.is404Error)(error)) {
|
|
189
|
-
this.logger.warn(`Outlook calendar event ${event.id} not found (already deleted), treating as successful deletion`);
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
211
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
193
212
|
this.logger.error(`Failed to delete Outlook calendar event after retries: ${errorMessage}`);
|
|
194
213
|
throw new Error(`Failed to delete Outlook calendar event: ${errorMessage}`);
|
|
195
214
|
}
|
|
196
|
-
finally {
|
|
197
|
-
this.rateLimiter.releasePermit(externalUserId);
|
|
198
|
-
}
|
|
199
215
|
}
|
|
200
216
|
async createBatchEvents(events, externalUserId, calendarId) {
|
|
201
217
|
if (events.length === 0) {
|
|
@@ -222,15 +238,20 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
222
238
|
})),
|
|
223
239
|
};
|
|
224
240
|
this.logger.log(`Creating batch of ${batchEvents.length} events in calendar ${calendarId} for user ${externalUserId}`);
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
241
|
+
const response = await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => axios_1.default.post('https://graph.microsoft.com/v1.0/$batch', batchPayload, {
|
|
242
|
+
headers: {
|
|
243
|
+
Authorization: `Bearer ${accessToken}`,
|
|
244
|
+
'Content-Type': 'application/json',
|
|
245
|
+
},
|
|
246
|
+
}), {
|
|
247
|
+
logger: this.logger,
|
|
248
|
+
resourceName: `batch create ${batchEvents.length} events for user ${externalUserId}`,
|
|
249
|
+
maxRetries: 3,
|
|
250
|
+
});
|
|
251
|
+
const batchResponse = response === null || response === void 0 ? void 0 : response.data;
|
|
252
|
+
if (!batchResponse) {
|
|
253
|
+
throw new Error('Batch request returned null response');
|
|
254
|
+
}
|
|
234
255
|
batchResponse.responses.forEach((response, batchIndex) => {
|
|
235
256
|
const globalIndex = i + batchIndex;
|
|
236
257
|
if (response.status === 201) {
|
|
@@ -307,15 +328,20 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
307
328
|
};
|
|
308
329
|
this.logger.log(`Updating batch of ${batchUpdates.length} events in calendar ${calendarId} for user ${externalUserId}`);
|
|
309
330
|
try {
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
331
|
+
const response = await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => axios_1.default.post('https://graph.microsoft.com/v1.0/$batch', batchPayload, {
|
|
332
|
+
headers: {
|
|
333
|
+
Authorization: `Bearer ${accessToken}`,
|
|
334
|
+
'Content-Type': 'application/json',
|
|
335
|
+
},
|
|
336
|
+
}), {
|
|
337
|
+
logger: this.logger,
|
|
338
|
+
resourceName: `batch update ${batchUpdates.length} events for user ${externalUserId}`,
|
|
339
|
+
maxRetries: 3,
|
|
340
|
+
});
|
|
341
|
+
const batchResponse = response === null || response === void 0 ? void 0 : response.data;
|
|
342
|
+
if (!batchResponse) {
|
|
343
|
+
throw new Error('Batch request returned null response');
|
|
344
|
+
}
|
|
319
345
|
batchResponse.responses.forEach((response, batchIndex) => {
|
|
320
346
|
const globalIndex = i + batchIndex;
|
|
321
347
|
if (response.status === 200) {
|
|
@@ -385,15 +411,20 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
385
411
|
};
|
|
386
412
|
this.logger.log(`Deleting batch of ${batchEventIds.length} events from calendar ${calendarId} for user ${externalUserId}`);
|
|
387
413
|
try {
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
414
|
+
const response = await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => axios_1.default.post('https://graph.microsoft.com/v1.0/$batch', batchPayload, {
|
|
415
|
+
headers: {
|
|
416
|
+
Authorization: `Bearer ${accessToken}`,
|
|
417
|
+
'Content-Type': 'application/json',
|
|
418
|
+
},
|
|
419
|
+
}), {
|
|
420
|
+
logger: this.logger,
|
|
421
|
+
resourceName: `batch delete ${batchEventIds.length} events for user ${externalUserId}`,
|
|
422
|
+
maxRetries: 3,
|
|
423
|
+
});
|
|
424
|
+
const batchResponse = response === null || response === void 0 ? void 0 : response.data;
|
|
425
|
+
if (!batchResponse) {
|
|
426
|
+
throw new Error('Batch request returned null response');
|
|
427
|
+
}
|
|
397
428
|
batchResponse.responses.forEach((response, index) => {
|
|
398
429
|
const eventId = batchEventIds[index];
|
|
399
430
|
if (response.status === 204 || response.status === 404) {
|
|
@@ -467,12 +498,19 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
467
498
|
this.logger.log(`[${correlationId}] Creating webhook subscription with notificationUrl: ${notificationUrl}`);
|
|
468
499
|
this.logger.debug(`[${correlationId}] Subscription data: ${JSON.stringify(subscriptionData)}`);
|
|
469
500
|
this.logger.log(`[${correlationId}] Sending POST request to Microsoft Graph API`);
|
|
470
|
-
const response = await axios_1.default.post("https://graph.microsoft.com/v1.0/subscriptions", subscriptionData, {
|
|
501
|
+
const response = await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => axios_1.default.post("https://graph.microsoft.com/v1.0/subscriptions", subscriptionData, {
|
|
471
502
|
headers: {
|
|
472
503
|
Authorization: `Bearer ${accessToken}`,
|
|
473
504
|
"Content-Type": "application/json",
|
|
474
505
|
},
|
|
506
|
+
}), {
|
|
507
|
+
logger: this.logger,
|
|
508
|
+
resourceName: `create webhook subscription for user ${internalUserId}`,
|
|
509
|
+
maxRetries: 3,
|
|
475
510
|
});
|
|
511
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
512
|
+
throw new Error('Subscription creation returned null response');
|
|
513
|
+
}
|
|
476
514
|
this.logger.log(`[${correlationId}] Created webhook subscription ${response.data.id || "unknown"} for user ${internalUserId}`);
|
|
477
515
|
this.logger.log(`[${correlationId}] Saving subscription to database (internalUserId: ${internalUserId}, externalUserId: ${externalUserId})`);
|
|
478
516
|
await this.webhookSubscriptionRepository.saveSubscription({
|
|
@@ -528,12 +566,19 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
528
566
|
expirationDateTime: expirationDateTime.toISOString(),
|
|
529
567
|
};
|
|
530
568
|
this.logger.debug(`[${correlationId}] Calling Microsoft Graph API to renew subscription`);
|
|
531
|
-
const response = await axios_1.default.patch(`https://graph.microsoft.com/v1.0/subscriptions/${subscriptionId}`, renewalData, {
|
|
569
|
+
const response = await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => axios_1.default.patch(`https://graph.microsoft.com/v1.0/subscriptions/${subscriptionId}`, renewalData, {
|
|
532
570
|
headers: {
|
|
533
571
|
Authorization: `Bearer ${accessToken}`,
|
|
534
572
|
"Content-Type": "application/json",
|
|
535
573
|
},
|
|
574
|
+
}), {
|
|
575
|
+
logger: this.logger,
|
|
576
|
+
resourceName: `renew webhook subscription ${subscriptionId} for user ${internalUserId}`,
|
|
577
|
+
maxRetries: 3,
|
|
536
578
|
});
|
|
579
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
580
|
+
throw new Error('Subscription renewal returned null response');
|
|
581
|
+
}
|
|
537
582
|
this.logger.debug(`[${correlationId}] Microsoft Graph API returned status: ${response.status}`);
|
|
538
583
|
if (response.data.expirationDateTime) {
|
|
539
584
|
await this.webhookSubscriptionRepository.updateSubscriptionExpiration(subscriptionId, new Date(response.data.expirationDateTime));
|
|
@@ -788,21 +833,21 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
788
833
|
this.logger.log(`[saveDeltaLink] Saved delta link for user ${externalUserId} (internal: ${internalUserId})`);
|
|
789
834
|
}
|
|
790
835
|
async getEventDetails(resource, externalUserId) {
|
|
791
|
-
var _a;
|
|
792
836
|
try {
|
|
793
837
|
const accessToken = await this.microsoftAuthService.getUserAccessToken({ externalUserId });
|
|
794
|
-
const response = await axios_1.default.get(`https://graph.microsoft.com/v1.0/${resource}`, {
|
|
838
|
+
const response = await (0, outlook_api_executor_util_1.executeGraphApiCall)(() => axios_1.default.get(`https://graph.microsoft.com/v1.0/${resource}`, {
|
|
795
839
|
headers: {
|
|
796
840
|
Authorization: `Bearer ${accessToken}`,
|
|
797
841
|
},
|
|
842
|
+
}), {
|
|
843
|
+
logger: this.logger,
|
|
844
|
+
resourceName: `event details for ${resource}`,
|
|
845
|
+
maxRetries: 3,
|
|
846
|
+
return404AsNull: true,
|
|
798
847
|
});
|
|
799
|
-
return response.data;
|
|
848
|
+
return response === null || response === void 0 ? void 0 : response.data;
|
|
800
849
|
}
|
|
801
850
|
catch (error) {
|
|
802
|
-
if (axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
|
|
803
|
-
this.logger.debug(`Event not found (404) for resource ${resource}, likely deleted - returning null`);
|
|
804
|
-
return null;
|
|
805
|
-
}
|
|
806
851
|
this.logger.error("Error fetching event details:", error);
|
|
807
852
|
throw error;
|
|
808
853
|
}
|
|
@@ -877,16 +922,14 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
877
922
|
return count < maxRetries;
|
|
878
923
|
});
|
|
879
924
|
if (retryableEvents.length > 0) {
|
|
880
|
-
const
|
|
881
|
-
if (
|
|
882
|
-
this.rateLimiter.handleRateLimitResponse(externalUserId,
|
|
925
|
+
const retryAfterSeconds = (0, retry_util_1.extractRetryAfterSeconds)(response);
|
|
926
|
+
if (retryAfterSeconds) {
|
|
927
|
+
this.rateLimiter.handleRateLimitResponse(externalUserId, retryAfterSeconds);
|
|
928
|
+
}
|
|
929
|
+
this.logger.log(`[getEventsBatch] Retrying ${retryableEvents.length} rate-limited events after ${retryAfterSeconds}s`);
|
|
930
|
+
if (retryAfterSeconds) {
|
|
931
|
+
await new Promise(resolve => setTimeout(resolve, retryAfterSeconds * 1000));
|
|
883
932
|
}
|
|
884
|
-
retryableEvents.forEach(id => {
|
|
885
|
-
retryCount.set(id, (retryCount.get(id) || 0) + 1);
|
|
886
|
-
});
|
|
887
|
-
const maxAttempt = Math.max(...retryableEvents.map(id => retryCount.get(id) || 0));
|
|
888
|
-
this.logger.log(`[getEventsBatch] Retrying ${retryableEvents.length} rate-limited events ` +
|
|
889
|
-
`(attempt ${maxAttempt}/${maxRetries})`);
|
|
890
933
|
const retriedEvents = await this.getEventsBatchInternal(retryableEvents, externalUserId, retryCount, maxRetries);
|
|
891
934
|
events.push(...retriedEvents);
|
|
892
935
|
}
|
|
@@ -905,20 +948,6 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
905
948
|
this.rateLimiter.releasePermit(externalUserId);
|
|
906
949
|
}
|
|
907
950
|
}
|
|
908
|
-
extractRetryAfterFromResponse(response) {
|
|
909
|
-
var _a;
|
|
910
|
-
try {
|
|
911
|
-
const retryAfter = (_a = response.headers) === null || _a === void 0 ? void 0 : _a['retry-after'];
|
|
912
|
-
if (typeof retryAfter === 'string' || typeof retryAfter === 'number') {
|
|
913
|
-
const parsed = parseInt(String(retryAfter), 10);
|
|
914
|
-
return !isNaN(parsed) ? Math.max(parsed, 5) : null;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
catch (_error) {
|
|
918
|
-
this.logger.debug('[extractRetryAfterFromResponse] Failed to extract Retry-After header');
|
|
919
|
-
}
|
|
920
|
-
return null;
|
|
921
|
-
}
|
|
922
951
|
importEventsStream(externalUserId, options) {
|
|
923
952
|
return __asyncGenerator(this, arguments, function* importEventsStream_1() {
|
|
924
953
|
var _a;
|
|
@@ -932,7 +961,12 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
932
961
|
let totalFetched = 0;
|
|
933
962
|
while (nextLink) {
|
|
934
963
|
this.logger.debug(`Fetching page: ${nextLink}`);
|
|
935
|
-
const response = (yield __await((0,
|
|
964
|
+
const response = (yield __await((0, outlook_api_executor_util_1.executeGraphApiCall)(() => client.api(nextLink).get(), {
|
|
965
|
+
logger: this.logger,
|
|
966
|
+
resourceName: `calendarView for user ${externalUserId}`,
|
|
967
|
+
rateLimiter: this.rateLimiter,
|
|
968
|
+
userId: externalUserId,
|
|
969
|
+
})));
|
|
936
970
|
const items = response.value;
|
|
937
971
|
buffer.push(...items);
|
|
938
972
|
totalFetched += items.length;
|
|
@@ -942,9 +976,6 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
942
976
|
yield yield __await(chunk);
|
|
943
977
|
}
|
|
944
978
|
nextLink = response["@odata.nextLink"];
|
|
945
|
-
if (nextLink) {
|
|
946
|
-
yield __await((0, retry_util_1.delay)(200));
|
|
947
|
-
}
|
|
948
979
|
}
|
|
949
980
|
if (buffer.length > 0) {
|
|
950
981
|
this.logger.debug(`Yielding final chunk of ${buffer.length} items`);
|
|
@@ -1005,7 +1036,12 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
1005
1036
|
const buffer = [];
|
|
1006
1037
|
let totalFetched = 0;
|
|
1007
1038
|
while (nextLink) {
|
|
1008
|
-
const response = (yield __await((0,
|
|
1039
|
+
const response = (yield __await((0, outlook_api_executor_util_1.executeGraphApiCall)(() => client.api(nextLink).get(), {
|
|
1040
|
+
logger: this.logger,
|
|
1041
|
+
resourceName: `recurring event instances for series ${seriesMasterId}`,
|
|
1042
|
+
rateLimiter: this.rateLimiter,
|
|
1043
|
+
userId: externalUserId,
|
|
1044
|
+
})));
|
|
1009
1045
|
const items = response.value;
|
|
1010
1046
|
buffer.push(...items);
|
|
1011
1047
|
totalFetched += items.length;
|
|
@@ -1014,9 +1050,6 @@ let CalendarService = CalendarService_1 = class CalendarService {
|
|
|
1014
1050
|
yield yield __await(chunk);
|
|
1015
1051
|
}
|
|
1016
1052
|
nextLink = response['@odata.nextLink'];
|
|
1017
|
-
if (nextLink) {
|
|
1018
|
-
yield __await((0, retry_util_1.delay)(200));
|
|
1019
|
-
}
|
|
1020
1053
|
}
|
|
1021
1054
|
if (buffer.length > 0) {
|
|
1022
1055
|
yield yield __await(buffer);
|