@checkfirst/nestjs-outlook 8.0.2 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/constants.d.ts +2 -0
  2. package/dist/constants.js +3 -1
  3. package/dist/constants.js.map +1 -1
  4. package/dist/controllers/calendar.controller.js +3 -0
  5. package/dist/controllers/calendar.controller.js.map +1 -1
  6. package/dist/controllers/email.controller.js +2 -0
  7. package/dist/controllers/email.controller.js.map +1 -1
  8. package/dist/guards/webhook-client-state.guard.d.ts +8 -0
  9. package/dist/guards/webhook-client-state.guard.js +75 -0
  10. package/dist/guards/webhook-client-state.guard.js.map +1 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.js +3 -0
  13. package/dist/index.js.map +1 -1
  14. package/dist/interfaces/config/outlook-config.interface.d.ts +10 -0
  15. package/dist/interfaces/state/redis-like.interface.d.ts +13 -0
  16. package/dist/interfaces/state/redis-like.interface.js +3 -0
  17. package/dist/interfaces/state/redis-like.interface.js.map +1 -0
  18. package/dist/microsoft-outlook.module.js +66 -0
  19. package/dist/microsoft-outlook.module.js.map +1 -1
  20. package/dist/repositories/outlook-webhook-subscription.repository.d.ts +1 -0
  21. package/dist/repositories/outlook-webhook-subscription.repository.js +5 -0
  22. package/dist/repositories/outlook-webhook-subscription.repository.js.map +1 -1
  23. package/dist/services/auth/microsoft-auth.service.d.ts +5 -1
  24. package/dist/services/auth/microsoft-auth.service.js +13 -4
  25. package/dist/services/auth/microsoft-auth.service.js.map +1 -1
  26. package/dist/services/calendar/calendar.service.d.ts +1 -1
  27. package/dist/services/calendar/calendar.service.js +4 -4
  28. package/dist/services/calendar/calendar.service.js.map +1 -1
  29. package/dist/services/email/email.service.js +2 -1
  30. package/dist/services/email/email.service.js.map +1 -1
  31. package/dist/services/shared/delta-sync.service.d.ts +6 -1
  32. package/dist/services/shared/delta-sync.service.js +121 -110
  33. package/dist/services/shared/delta-sync.service.js.map +1 -1
  34. package/dist/services/shared/graph-rate-limiter.service.d.ts +15 -17
  35. package/dist/services/shared/graph-rate-limiter.service.js +104 -148
  36. package/dist/services/shared/graph-rate-limiter.service.js.map +1 -1
  37. package/dist/services/shared/outlook-lock.store.d.ts +37 -0
  38. package/dist/services/shared/outlook-lock.store.js +134 -0
  39. package/dist/services/shared/outlook-lock.store.js.map +1 -0
  40. package/dist/services/shared/outlook-rate-limit.store.d.ts +59 -0
  41. package/dist/services/shared/outlook-rate-limit.store.js +235 -0
  42. package/dist/services/shared/outlook-rate-limit.store.js.map +1 -0
  43. package/dist/services/subscription/microsoft-subscription.service.d.ts +12 -0
  44. package/dist/services/subscription/microsoft-subscription.service.js +85 -0
  45. package/dist/services/subscription/microsoft-subscription.service.js.map +1 -1
  46. package/dist/tsconfig.tsbuildinfo +1 -1
  47. package/dist/utils/outlook-api-executor.util.js +3 -3
  48. package/dist/utils/outlook-api-executor.util.js.map +1 -1
  49. package/package.json +3 -1
@@ -8,213 +8,167 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
11
14
  var GraphRateLimiterService_1;
12
15
  Object.defineProperty(exports, "__esModule", { value: true });
13
16
  exports.GraphRateLimiterService = void 0;
14
17
  const common_1 = require("@nestjs/common");
15
18
  const schedule_1 = require("@nestjs/schedule");
16
19
  const retry_util_1 = require("../../utils/retry.util");
20
+ const constants_1 = require("../../constants");
17
21
  let GraphRateLimiterService = GraphRateLimiterService_1 = class GraphRateLimiterService {
18
- constructor() {
22
+ constructor(store) {
23
+ this.store = store;
19
24
  this.logger = new common_1.Logger(GraphRateLimiterService_1.name);
20
25
  this.MAX_REQUESTS_PER_SECOND = 4;
21
26
  this.MAX_REQUESTS_PER_10_MINUTES = 10000;
22
27
  this.ONE_SECOND_MS = 1000;
23
28
  this.TEN_MINUTES_MS = 10 * 60 * 1000;
24
29
  this.INACTIVE_USER_THRESHOLD_MS = 30 * 60 * 1000;
25
- this.userLimiters = new Map();
26
30
  this.totalPermitsAcquired = 0;
27
31
  this.totalWaitTime = 0;
28
32
  this.cooldownCount = 0;
29
33
  this.CB_FAILURE_THRESHOLD = 5;
30
34
  this.CB_FAILURE_WINDOW_MS = 60000;
31
35
  this.CB_COOLDOWN_MS = 60000;
32
- this.CB_HALF_OPEN_MAX = 1;
33
- this.cbState = 'closed';
36
+ this.CB_PROBE_TTL_MS = 5000;
34
37
  this.cbFailureTimestamps = [];
35
- this.cbOpenedAt = null;
36
- this.cbHalfOpenInFlight = 0;
37
38
  this.cbTotalTrips = 0;
38
39
  }
39
40
  onModuleInit() {
40
- this.logger.log(`GraphRateLimiterService initialized - Limits: ${this.MAX_REQUESTS_PER_SECOND} req/sec, ` +
41
+ this.logger.log(`GraphRateLimiterService initialized (backend=${this.store.kind}) - Limits: ${this.MAX_REQUESTS_PER_SECOND} req/sec, ` +
41
42
  `${this.MAX_REQUESTS_PER_10_MINUTES} req/10min per user`);
42
43
  }
43
44
  async acquirePermit(userId) {
44
45
  await this.waitForCircuitBreaker();
45
- if (!this.userLimiters.has(userId)) {
46
- this.initializeLimiter(userId);
47
- }
48
- const limiter = this.userLimiters.get(userId);
49
- if (!limiter) {
50
- this.logger.warn(`[acquirePermit] No limiter found for user ${userId}, skipping acquire`);
51
- return;
52
- }
53
46
  const startTime = Date.now();
54
47
  let waitedOnce = false;
55
- while (!this.canMakeRequest(userId)) {
56
- if (!waitedOnce) {
57
- waitedOnce = true;
58
- this.logger.debug(`[acquirePermit] User ${userId} rate limited, entering wait loop`);
48
+ for (;;) {
49
+ const cooldownUntil = await this.store.getCooldown(userId);
50
+ if (cooldownUntil && cooldownUntil > Date.now()) {
51
+ const wait = cooldownUntil - Date.now() + 50;
52
+ if (!waitedOnce) {
53
+ waitedOnce = true;
54
+ this.logger.debug(`[acquirePermit] User ${userId} in cooldown for ${wait}ms`);
55
+ }
56
+ await (0, retry_util_1.delay)(Math.max(wait, 50));
57
+ continue;
59
58
  }
60
- const oldestRequest = limiter.recentRequests[0];
61
- const waitTime = oldestRequest
62
- ? this.ONE_SECOND_MS - (Date.now() - oldestRequest) + 50
63
- : 100;
64
- await (0, retry_util_1.delay)(Math.max(waitTime, 50));
59
+ const secCount = await this.store.getCount(userId, this.ONE_SECOND_MS, 'sec');
60
+ const tenMinCount = await this.store.getCount(userId, this.TEN_MINUTES_MS, 'min10');
61
+ if (secCount >= this.MAX_REQUESTS_PER_SECOND) {
62
+ if (!waitedOnce) {
63
+ waitedOnce = true;
64
+ this.logger.debug(`[acquirePermit] User ${userId} at 1s limit, waiting`);
65
+ }
66
+ await (0, retry_util_1.delay)(100);
67
+ continue;
68
+ }
69
+ if (tenMinCount >= this.MAX_REQUESTS_PER_10_MINUTES) {
70
+ this.logger.warn(`[acquirePermit] User ${userId} hit 10-minute limit (${tenMinCount}/${this.MAX_REQUESTS_PER_10_MINUTES})`);
71
+ await (0, retry_util_1.delay)(1000);
72
+ continue;
73
+ }
74
+ break;
65
75
  }
66
- const now = Date.now();
67
- limiter.recentRequests.push(now);
68
- limiter.tenMinuteWindow.push(now);
69
- limiter.lastActivity = now;
76
+ await this.store.recordRequest(userId, this.ONE_SECOND_MS, 'sec');
77
+ await this.store.recordRequest(userId, this.TEN_MINUTES_MS, 'min10');
70
78
  this.totalPermitsAcquired++;
71
- const totalWait = now - startTime;
79
+ const totalWait = Date.now() - startTime;
72
80
  if (totalWait > 50) {
73
81
  this.totalWaitTime += totalWait;
74
- this.logger.debug(`[acquirePermit] User ${userId} waited ${totalWait}ms for permit ` +
75
- `(recent: ${limiter.recentRequests.length}/${this.MAX_REQUESTS_PER_SECOND}, ` +
76
- `10min: ${limiter.tenMinuteWindow.length}/${this.MAX_REQUESTS_PER_10_MINUTES})`);
82
+ this.logger.debug(`[acquirePermit] User ${userId} waited ${totalWait}ms for permit`);
77
83
  }
78
84
  }
79
- releasePermit(userId) {
80
- if (!this.userLimiters.has(userId)) {
81
- this.logger.warn(`[releasePermit] No limiter found for user ${userId}, skipping release`);
82
- return;
83
- }
85
+ releasePermit(_userId) {
84
86
  }
85
- handleRateLimitResponse(userId, retryAfterSeconds) {
86
- if (!this.userLimiters.has(userId)) {
87
- this.initializeLimiter(userId);
88
- }
89
- const limiter = this.userLimiters.get(userId);
90
- if (!limiter) {
91
- this.logger.warn(`[handleRateLimitResponse] No limiter found for user ${userId}, skipping cooldown`);
92
- return;
93
- }
94
- const cooldownUntil = Date.now() + (retryAfterSeconds * 1000);
95
- limiter.cooldownUntil = cooldownUntil;
87
+ async handleRateLimitResponse(userId, retryAfterSeconds) {
88
+ const cooldownUntil = Date.now() + retryAfterSeconds * 1000;
89
+ await this.store.setCooldown(userId, cooldownUntil);
96
90
  this.cooldownCount++;
97
91
  this.logger.warn(`[handleRateLimitResponse] User ${userId} hit 429 - cooldown for ${retryAfterSeconds}s ` +
98
92
  `until ${new Date(cooldownUntil).toISOString()}`);
99
93
  }
100
- canMakeRequest(userId) {
101
- const limiter = this.userLimiters.get(userId);
102
- if (!limiter)
103
- return true;
104
- const now = Date.now();
105
- limiter.recentRequests = limiter.recentRequests.filter(timestamp => now - timestamp < this.ONE_SECOND_MS);
106
- limiter.tenMinuteWindow = limiter.tenMinuteWindow.filter(timestamp => now - timestamp < this.TEN_MINUTES_MS);
107
- if (limiter.cooldownUntil && now < limiter.cooldownUntil) {
108
- return false;
109
- }
110
- if (limiter.recentRequests.length >= this.MAX_REQUESTS_PER_SECOND) {
111
- return false;
112
- }
113
- if (limiter.tenMinuteWindow.length >= this.MAX_REQUESTS_PER_10_MINUTES) {
114
- this.logger.warn(`[canMakeRequest] User ${userId} hit 10-minute limit ` +
115
- `(${limiter.tenMinuteWindow.length}/${this.MAX_REQUESTS_PER_10_MINUTES})`);
116
- return false;
117
- }
118
- return true;
119
- }
120
- initializeLimiter(userId) {
121
- this.userLimiters.set(userId, {
122
- userId,
123
- recentRequests: [],
124
- tenMinuteWindow: [],
125
- cooldownUntil: null,
126
- lastActivity: Date.now(),
127
- });
128
- this.logger.debug(`[initializeLimiter] Created limiter for user ${userId}`);
129
- }
130
- cleanupInactiveUsers() {
94
+ async cleanupInactiveUsers() {
95
+ if (this.store.kind !== 'memory')
96
+ return;
97
+ const removed = await this.store.cleanupInactive(this.INACTIVE_USER_THRESHOLD_MS);
131
98
  const now = Date.now();
132
- let cleaned = 0;
133
- for (const [userId, limiter] of this.userLimiters.entries()) {
134
- const inactiveDuration = now - limiter.lastActivity;
135
- if (inactiveDuration > this.INACTIVE_USER_THRESHOLD_MS) {
136
- this.userLimiters.delete(userId);
137
- cleaned++;
138
- }
139
- }
140
- this.cbFailureTimestamps = this.cbFailureTimestamps.filter(t => now - t < this.CB_FAILURE_WINDOW_MS);
141
- if (cleaned > 0) {
142
- this.logger.log(`[cleanupInactiveUsers] Cleaned up ${cleaned} inactive users ` +
143
- `(${this.userLimiters.size} active limiters remaining)`);
99
+ this.cbFailureTimestamps = this.cbFailureTimestamps.filter((t) => now - t < this.CB_FAILURE_WINDOW_MS);
100
+ if (removed > 0) {
101
+ this.logger.log(`[cleanupInactiveUsers] Cleaned up ${removed} inactive users`);
144
102
  }
145
103
  }
146
- record503Failure() {
104
+ async record503Failure() {
105
+ var _a;
147
106
  const now = Date.now();
148
107
  this.cbFailureTimestamps.push(now);
149
- this.cbFailureTimestamps = this.cbFailureTimestamps.filter(t => now - t < this.CB_FAILURE_WINDOW_MS);
150
- if (this.cbState === 'half-open') {
151
- this.cbState = 'open';
152
- this.cbOpenedAt = now;
153
- this.cbHalfOpenInFlight = 0;
108
+ this.cbFailureTimestamps = this.cbFailureTimestamps.filter((t) => now - t < this.CB_FAILURE_WINDOW_MS);
109
+ const cb = await this.store.getCbState();
110
+ const state = (_a = cb === null || cb === void 0 ? void 0 : cb.state) !== null && _a !== void 0 ? _a : 'closed';
111
+ if (state === 'half-open') {
112
+ await this.store.setCbState({ state: 'open', openedAt: now });
154
113
  this.logger.warn(`[CircuitBreaker] Half-open probe failed (503), re-opening circuit for ${this.CB_COOLDOWN_MS / 1000}s`);
155
114
  return;
156
115
  }
157
- if (this.cbState === 'closed' &&
116
+ if (state === 'closed' &&
158
117
  this.cbFailureTimestamps.length >= this.CB_FAILURE_THRESHOLD) {
159
- this.cbState = 'open';
160
- this.cbOpenedAt = now;
118
+ await this.store.setCbState({ state: 'open', openedAt: now });
161
119
  this.cbTotalTrips++;
162
120
  this.logger.warn(`[CircuitBreaker] OPEN — ${this.cbFailureTimestamps.length} 503 errors ` +
163
121
  `within ${this.CB_FAILURE_WINDOW_MS / 1000}s window. ` +
164
122
  `Blocking requests for ${this.CB_COOLDOWN_MS / 1000}s`);
165
123
  }
166
124
  }
167
- recordSuccess() {
168
- if (this.cbState === 'half-open') {
169
- this.logger.log('[CircuitBreaker] CLOSED half-open probe succeeded');
170
- this.cbState = 'closed';
125
+ async recordSuccess() {
126
+ const cb = await this.store.getCbState();
127
+ if ((cb === null || cb === void 0 ? void 0 : cb.state) === 'half-open') {
128
+ await this.store.setCbState({ state: 'closed', openedAt: null });
171
129
  this.cbFailureTimestamps = [];
172
- this.cbHalfOpenInFlight = 0;
173
- this.cbOpenedAt = null;
130
+ this.logger.log('[CircuitBreaker] CLOSED — half-open probe succeeded');
174
131
  return;
175
132
  }
176
- if (this.cbState === 'closed') {
133
+ if ((cb === null || cb === void 0 ? void 0 : cb.state) === 'closed') {
177
134
  this.cbFailureTimestamps = [];
178
135
  }
179
136
  }
180
137
  async waitForCircuitBreaker() {
181
138
  var _a;
182
- if (this.cbState === 'closed')
139
+ const cb = await this.store.getCbState();
140
+ if (!cb || cb.state === 'closed')
183
141
  return;
184
142
  const now = Date.now();
185
- if (this.cbState === 'open') {
186
- const elapsed = now - ((_a = this.cbOpenedAt) !== null && _a !== void 0 ? _a : now);
143
+ if (cb.state === 'open') {
144
+ const elapsed = now - ((_a = cb.openedAt) !== null && _a !== void 0 ? _a : now);
187
145
  if (elapsed >= this.CB_COOLDOWN_MS) {
188
- this.cbState = 'half-open';
189
- this.cbHalfOpenInFlight = 0;
190
- this.logger.log('[CircuitBreaker] HALF-OPEN — cooldown expired, allowing probe request');
191
- }
192
- else {
193
- const remaining = this.CB_COOLDOWN_MS - elapsed;
194
- this.logger.warn(`[CircuitBreaker] Circuit OPEN, waiting ${Math.round(remaining / 1000)}s before retry`);
195
- await (0, retry_util_1.delay)(remaining);
196
- this.cbState = 'half-open';
197
- this.cbHalfOpenInFlight = 0;
198
- this.logger.log('[CircuitBreaker] HALF-OPEN — cooldown expired after wait');
199
- }
200
- }
201
- const currentState = this.cbState;
202
- if (currentState === 'half-open') {
203
- while (this.cbHalfOpenInFlight >= this.CB_HALF_OPEN_MAX) {
204
- await (0, retry_util_1.delay)(500);
205
- const stateAfterWait = this.cbState;
206
- if (stateAfterWait === 'closed')
146
+ const wonProbe = await this.store.tryClaimHalfOpenProbe(this.CB_PROBE_TTL_MS);
147
+ if (wonProbe) {
148
+ await this.store.setCbState({ state: 'half-open', openedAt: null });
149
+ this.logger.log('[CircuitBreaker] HALF-OPEN — cooldown expired, this container is probing');
207
150
  return;
208
- if (stateAfterWait === 'open') {
209
- return this.waitForCircuitBreaker();
210
151
  }
152
+ await (0, retry_util_1.delay)(this.CB_PROBE_TTL_MS);
153
+ return this.waitForCircuitBreaker();
211
154
  }
212
- this.cbHalfOpenInFlight++;
155
+ const remaining = this.CB_COOLDOWN_MS - elapsed;
156
+ this.logger.warn(`[CircuitBreaker] Circuit OPEN, waiting ${Math.round(remaining / 1000)}s before retry`);
157
+ await (0, retry_util_1.delay)(remaining);
158
+ return this.waitForCircuitBreaker();
159
+ }
160
+ const wonProbe = await this.store.tryClaimHalfOpenProbe(this.CB_PROBE_TTL_MS);
161
+ if (!wonProbe) {
162
+ await (0, retry_util_1.delay)(this.CB_PROBE_TTL_MS);
163
+ return this.waitForCircuitBreaker();
213
164
  }
214
165
  }
215
- getStats() {
166
+ async getStats() {
167
+ var _a;
168
+ const cb = await this.store.getCbState();
216
169
  return {
217
- activeUsers: this.userLimiters.size,
170
+ backend: this.store.kind,
171
+ activeUsers: await this.store.getActiveUserCount(),
218
172
  totalPermitsAcquired: this.totalPermitsAcquired,
219
173
  totalWaitTimeMs: this.totalWaitTime,
220
174
  averageWaitTimeMs: this.totalPermitsAcquired > 0
@@ -222,25 +176,25 @@ let GraphRateLimiterService = GraphRateLimiterService_1 = class GraphRateLimiter
222
176
  : 0,
223
177
  cooldownCount: this.cooldownCount,
224
178
  circuitBreaker: {
225
- state: this.cbState,
179
+ state: (_a = cb === null || cb === void 0 ? void 0 : cb.state) !== null && _a !== void 0 ? _a : 'closed',
226
180
  recentFailures: this.cbFailureTimestamps.length,
227
181
  totalTrips: this.cbTotalTrips,
228
- openedAt: this.cbOpenedAt ? new Date(this.cbOpenedAt).toISOString() : null,
182
+ openedAt: (cb === null || cb === void 0 ? void 0 : cb.openedAt) ? new Date(cb.openedAt).toISOString() : null,
229
183
  },
230
184
  };
231
185
  }
232
- getUserStats(userId) {
233
- const limiter = this.userLimiters.get(userId);
234
- if (!limiter) {
235
- return null;
236
- }
237
- const now = Date.now();
186
+ async getUserStats(userId) {
187
+ const [secCount, tenMinCount, cooldownUntil] = await Promise.all([
188
+ this.store.getCount(userId, this.ONE_SECOND_MS, 'sec'),
189
+ this.store.getCount(userId, this.TEN_MINUTES_MS, 'min10'),
190
+ this.store.getCooldown(userId),
191
+ ]);
238
192
  return {
239
193
  userId,
240
- recentRequestCount: limiter.recentRequests.filter(t => now - t < this.ONE_SECOND_MS).length,
241
- tenMinuteRequestCount: limiter.tenMinuteWindow.filter(t => now - t < this.TEN_MINUTES_MS).length,
242
- cooldownUntil: limiter.cooldownUntil,
243
- lastActivity: new Date(limiter.lastActivity).toISOString(),
194
+ backend: this.store.kind,
195
+ recentRequestCount: secCount,
196
+ tenMinuteRequestCount: tenMinCount,
197
+ cooldownUntil,
244
198
  };
245
199
  }
246
200
  };
@@ -249,9 +203,11 @@ __decorate([
249
203
  (0, schedule_1.Cron)(schedule_1.CronExpression.EVERY_5_MINUTES),
250
204
  __metadata("design:type", Function),
251
205
  __metadata("design:paramtypes", []),
252
- __metadata("design:returntype", void 0)
206
+ __metadata("design:returntype", Promise)
253
207
  ], GraphRateLimiterService.prototype, "cleanupInactiveUsers", null);
254
208
  exports.GraphRateLimiterService = GraphRateLimiterService = GraphRateLimiterService_1 = __decorate([
255
- (0, common_1.Injectable)()
209
+ (0, common_1.Injectable)(),
210
+ __param(0, (0, common_1.Inject)(constants_1.OUTLOOK_RATE_LIMIT_STORE)),
211
+ __metadata("design:paramtypes", [Object])
256
212
  ], GraphRateLimiterService);
257
213
  //# sourceMappingURL=graph-rate-limiter.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph-rate-limiter.service.js","sourceRoot":"","sources":["../../../src/services/shared/graph-rate-limiter.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph-rate-limiter.service.js","sourceRoot":"","sources":["../../../src/services/shared/graph-rate-limiter.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { RedisLike } from "../../interfaces/state/redis-like.interface";
2
+ export interface WithLockResult<T> {
3
+ acquired: boolean;
4
+ value?: T;
5
+ }
6
+ export interface OutlookLockStore {
7
+ readonly kind: "memory" | "redis";
8
+ acquireLock(key: string, ttlMs?: number): Promise<string | null>;
9
+ renewLock(key: string, token: string, ttlMs: number): Promise<boolean>;
10
+ releaseLock(key: string, token: string): Promise<void>;
11
+ clearLock(key: string): Promise<void>;
12
+ consumeFlag(key: string): Promise<boolean>;
13
+ }
14
+ export declare function generateLockToken(): string;
15
+ export declare class InMemoryOutlookLockStore implements OutlookLockStore {
16
+ readonly kind: "memory";
17
+ private readonly logger;
18
+ private readonly locks;
19
+ acquireLock(key: string, ttlMs?: number): Promise<string | null>;
20
+ renewLock(key: string, token: string, ttlMs: number): Promise<boolean>;
21
+ releaseLock(key: string, token: string): Promise<void>;
22
+ clearLock(key: string): Promise<void>;
23
+ consumeFlag(key: string): Promise<boolean>;
24
+ }
25
+ export declare class RedisOutlookLockStore implements OutlookLockStore {
26
+ private readonly redis;
27
+ private readonly keyPrefix;
28
+ readonly kind: "redis";
29
+ private readonly logger;
30
+ constructor(redis: RedisLike, keyPrefix: string);
31
+ private k;
32
+ acquireLock(key: string, ttlMs?: number): Promise<string | null>;
33
+ renewLock(key: string, token: string, ttlMs: number): Promise<boolean>;
34
+ releaseLock(key: string, token: string): Promise<void>;
35
+ clearLock(key: string): Promise<void>;
36
+ consumeFlag(key: string): Promise<boolean>;
37
+ }
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisOutlookLockStore = exports.InMemoryOutlookLockStore = void 0;
4
+ exports.generateLockToken = generateLockToken;
5
+ const common_1 = require("@nestjs/common");
6
+ const crypto_1 = require("crypto");
7
+ function generateLockToken() {
8
+ return (0, crypto_1.randomBytes)(16).toString("hex");
9
+ }
10
+ class InMemoryOutlookLockStore {
11
+ constructor() {
12
+ this.kind = "memory";
13
+ this.logger = new common_1.Logger(InMemoryOutlookLockStore.name);
14
+ this.locks = new Map();
15
+ }
16
+ acquireLock(key, ttlMs) {
17
+ const now = Date.now();
18
+ const existing = this.locks.get(key);
19
+ if (existing && existing.expiresAt > now) {
20
+ return Promise.resolve(null);
21
+ }
22
+ const token = generateLockToken();
23
+ const expiresAt = ttlMs === undefined ? Infinity : now + ttlMs;
24
+ this.locks.set(key, { token, expiresAt });
25
+ return Promise.resolve(token);
26
+ }
27
+ renewLock(key, token, ttlMs) {
28
+ const now = Date.now();
29
+ const existing = this.locks.get(key);
30
+ if (!existing || existing.token !== token || existing.expiresAt <= now) {
31
+ return Promise.resolve(false);
32
+ }
33
+ existing.expiresAt = now + ttlMs;
34
+ return Promise.resolve(true);
35
+ }
36
+ releaseLock(key, token) {
37
+ const existing = this.locks.get(key);
38
+ if (existing && existing.token === token) {
39
+ this.locks.delete(key);
40
+ }
41
+ return Promise.resolve();
42
+ }
43
+ clearLock(key) {
44
+ this.locks.delete(key);
45
+ return Promise.resolve();
46
+ }
47
+ consumeFlag(key) {
48
+ const now = Date.now();
49
+ const existing = this.locks.get(key);
50
+ const present = !!existing && existing.expiresAt > now;
51
+ this.locks.delete(key);
52
+ return Promise.resolve(present);
53
+ }
54
+ }
55
+ exports.InMemoryOutlookLockStore = InMemoryOutlookLockStore;
56
+ const RELEASE_LUA = `
57
+ if redis.call('GET', KEYS[1]) == ARGV[1] then
58
+ return redis.call('DEL', KEYS[1])
59
+ else
60
+ return 0
61
+ end
62
+ `;
63
+ const RENEW_LUA = `
64
+ if redis.call('GET', KEYS[1]) == ARGV[1] then
65
+ return redis.call('PEXPIRE', KEYS[1], ARGV[2])
66
+ else
67
+ return 0
68
+ end
69
+ `;
70
+ const CONSUME_FLAG_LUA = `
71
+ return redis.call('DEL', KEYS[1])
72
+ `;
73
+ class RedisOutlookLockStore {
74
+ constructor(redis, keyPrefix) {
75
+ this.redis = redis;
76
+ this.keyPrefix = keyPrefix;
77
+ this.kind = "redis";
78
+ this.logger = new common_1.Logger(RedisOutlookLockStore.name);
79
+ }
80
+ k(key) {
81
+ return `${this.keyPrefix}lock:${key}`;
82
+ }
83
+ async acquireLock(key, ttlMs) {
84
+ const token = generateLockToken();
85
+ try {
86
+ const result = ttlMs === undefined
87
+ ? await this.redis.set(this.k(key), token, "NX")
88
+ : await this.redis.set(this.k(key), token, "PX", ttlMs, "NX");
89
+ return result === "OK" ? token : null;
90
+ }
91
+ catch (err) {
92
+ this.logger.error(`[acquireLock] Redis error for ${key}: ${err instanceof Error ? err.message : String(err)}`);
93
+ return null;
94
+ }
95
+ }
96
+ async renewLock(key, token, ttlMs) {
97
+ try {
98
+ const result = await this.redis.eval(RENEW_LUA, 1, this.k(key), token, ttlMs);
99
+ return result === 1;
100
+ }
101
+ catch (err) {
102
+ this.logger.error(`[renewLock] Redis error for ${key}: ${err instanceof Error ? err.message : String(err)}`);
103
+ return false;
104
+ }
105
+ }
106
+ async releaseLock(key, token) {
107
+ try {
108
+ await this.redis.eval(RELEASE_LUA, 1, this.k(key), token);
109
+ }
110
+ catch (err) {
111
+ this.logger.error(`[releaseLock] Redis error for ${key}: ${err instanceof Error ? err.message : String(err)}`);
112
+ }
113
+ }
114
+ async clearLock(key) {
115
+ try {
116
+ await this.redis.del(this.k(key));
117
+ }
118
+ catch (err) {
119
+ this.logger.error(`[clearLock] Redis error for ${key}: ${err instanceof Error ? err.message : String(err)}`);
120
+ }
121
+ }
122
+ async consumeFlag(key) {
123
+ try {
124
+ const removed = await this.redis.eval(CONSUME_FLAG_LUA, 1, this.k(key));
125
+ return removed === 1;
126
+ }
127
+ catch (err) {
128
+ this.logger.error(`[consumeFlag] Redis error for ${key}: ${err instanceof Error ? err.message : String(err)}`);
129
+ return false;
130
+ }
131
+ }
132
+ }
133
+ exports.RedisOutlookLockStore = RedisOutlookLockStore;
134
+ //# sourceMappingURL=outlook-lock.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlook-lock.store.js","sourceRoot":"","sources":["../../../src/services/shared/outlook-lock.store.ts"],"names":[],"mappings":"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"}