dt-common-device 7.6.9 → 7.6.11

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/index.d.ts CHANGED
@@ -17,3 +17,4 @@ export * from "./queue";
17
17
  export * from "./entities/pms";
18
18
  export * from "./audit";
19
19
  export { initialize, getConfig, shutdown } from "./config/config";
20
+ export * from "./pms/index";
package/dist/index.js CHANGED
@@ -59,3 +59,5 @@ var config_1 = require("./config/config");
59
59
  Object.defineProperty(exports, "initialize", { enumerable: true, get: function () { return config_1.initialize; } });
60
60
  Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_1.getConfig; } });
61
61
  Object.defineProperty(exports, "shutdown", { enumerable: true, get: function () { return config_1.shutdown; } });
62
+ //Export PMS Webhook Queue
63
+ __exportStar(require("./pms/index"), exports);
@@ -1,55 +1,7 @@
1
- import { IWebhookQueueMetrics, IWebhookQueueOptions, IWebhookQueueStatus } from "../types/webhook.types";
1
+ import { IWebhookQueueOptions } from "../types/webhook.types";
2
2
  export interface IWebhookQueue {
3
3
  /**
4
4
  * Add a webhook to the appropriate queue based on propertyId and pmsType
5
5
  */
6
6
  addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: IWebhookQueueOptions): Promise<string>;
7
- /**
8
- * Get the status of a specific webhook queue
9
- */
10
- getQueueStatus(propertyId: string, pmsType: string): Promise<IWebhookQueueStatus>;
11
- /**
12
- * Get status of all webhook queues for a property
13
- */
14
- getAllPropertyQueueStatuses(propertyId: string): Promise<Record<string, IWebhookQueueStatus>>;
15
- /**
16
- * Get detailed metrics for a specific queue
17
- */
18
- getQueueMetrics(propertyId: string, pmsType: string): Promise<IWebhookQueueMetrics>;
19
- /**
20
- * Clean up completed and failed jobs from a specific queue
21
- */
22
- cleanupQueue(propertyId: string, pmsType: string): Promise<void>;
23
- /**
24
- * Pause a specific queue
25
- */
26
- pauseQueue(propertyId: string, pmsType: string): Promise<void>;
27
- /**
28
- * Resume a paused queue
29
- */
30
- resumeQueue(propertyId: string, pmsType: string): Promise<void>;
31
- /**
32
- * Get all active queues
33
- */
34
- getActiveQueues(): Promise<string[]>;
35
- /**
36
- * Shutdown all queues and workers
37
- */
38
- shutdown(): Promise<void>;
39
- /**
40
- * Check if a queue exists
41
- */
42
- queueExists(propertyId: string, pmsType: string): Promise<boolean>;
43
- /**
44
- * Get queue configuration
45
- */
46
- getQueueConfig(propertyId: string, pmsType: string): Promise<any>;
47
- /**
48
- * Update queue configuration
49
- */
50
- updateQueueConfig(propertyId: string, pmsType: string, config: Partial<any>): Promise<void>;
51
- /**
52
- * Set webhook processor function for a specific queue
53
- */
54
- setWebhookProcessor(propertyId: string, pmsType: string, processor: (webhookData: any, pmsType: string) => Promise<any>): Promise<void>;
55
7
  }
@@ -1,2 +1 @@
1
1
  export * from "./IWebhookQueue";
2
- export * from "./IWebhookWorker";
@@ -15,4 +15,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./IWebhookQueue"), exports);
18
- __exportStar(require("./IWebhookWorker"), exports);
@@ -1,27 +1,16 @@
1
- import { IWebhookQueue } from "../interfaces";
2
- import { IWebhookQueueConfig, IWebhookQueueMetrics, IWebhookQueueOptions, IWebhookQueueStatus } from "../types/webhook.types";
1
+ import { IWebhookQueue } from "../interfaces/IWebhookQueue";
2
+ import { IWebhookQueueOptions } from "../types/webhook.types";
3
3
  export declare class WebhookQueueService implements IWebhookQueue {
4
- private redisConnection;
5
- private webhookQueues;
6
- private workers;
7
- private config;
8
- constructor(config: IWebhookQueueConfig);
9
- addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: IWebhookQueueOptions): Promise<string>;
10
- getQueueStatus(propertyId: string, pmsType: string): Promise<IWebhookQueueStatus>;
11
- getAllPropertyQueueStatuses(propertyId: string): Promise<Record<string, IWebhookQueueStatus>>;
12
- getQueueMetrics(propertyId: string, pmsType: string): Promise<IWebhookQueueMetrics>;
13
- cleanupQueue(propertyId: string, pmsType: string): Promise<void>;
14
- pauseQueue(propertyId: string, pmsType: string): Promise<void>;
15
- resumeQueue(propertyId: string, pmsType: string): Promise<void>;
16
- getActiveQueues(): Promise<string[]>;
17
- shutdown(): Promise<void>;
18
- queueExists(propertyId: string, pmsType: string): Promise<boolean>;
19
- getQueueConfig(propertyId: string, pmsType: string): Promise<any>;
20
- updateQueueConfig(propertyId: string, pmsType: string, config: Partial<any>): Promise<void>;
4
+ private readonly webhookQueues;
5
+ /**
6
+ * Generate queue name based on propertyId and pmsType
7
+ * Format: propertyId_pmsType_webhook
8
+ */
9
+ private generateQueueName;
21
10
  /**
22
- * Set webhook processor function for a specific queue
11
+ * Add a webhook to the appropriate queue based on propertyId and pmsType
12
+ * Creates queue if it doesn't exist
23
13
  */
24
- setWebhookProcessor(propertyId: string, pmsType: string, processor: (webhookData: any, pmsType: string) => Promise<any>): Promise<void>;
25
- private getQueueName;
26
- private getOrCreateQueue;
14
+ addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: IWebhookQueueOptions): Promise<string>;
15
+ static getOrCreateQueue(queueKey: string, queues: Map<string, any>): any;
27
16
  }
@@ -39,226 +39,52 @@ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, p
39
39
  };
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
41
  exports.WebhookQueueService = void 0;
42
- const bullmq_1 = require("bullmq");
43
- const ioredis_1 = require("ioredis");
44
42
  const typedi_1 = require("typedi");
45
- const WebhookWorker_1 = require("./WebhookWorker");
43
+ const redis_1 = require("../../../db/redis");
46
44
  let WebhookQueueService = (() => {
47
45
  let _classDecorators = [(0, typedi_1.Service)()];
48
46
  let _classDescriptor;
49
47
  let _classExtraInitializers = [];
50
48
  let _classThis;
51
49
  var WebhookQueueService = _classThis = class {
52
- constructor(config) {
53
- this.webhookQueues = new Map();
54
- this.workers = new Map();
55
- this.config = {
56
- maxRetries: 3,
57
- backoffDelay: 2000,
58
- jobTimeout: 300000, // 5 minutes
59
- removeOnComplete: { age: 3600000, count: 100 }, // 1 hour, max 100
60
- removeOnFail: { age: 7200000, count: 50 }, // 2 hours, max 50
61
- ...config,
62
- };
63
- this.redisConnection = new ioredis_1.Redis({
64
- host: this.config.redisHost,
65
- port: this.config.redisPort,
66
- maxRetriesPerRequest: null,
67
- enableReadyCheck: false,
68
- });
50
+ constructor() {
51
+ this.webhookQueues = new Map(); // BullMQ Queue instances
52
+ }
53
+ /**
54
+ * Generate queue name based on propertyId and pmsType
55
+ * Format: propertyId_pmsType_webhook
56
+ */
57
+ generateQueueName(propertyId, pmsType) {
58
+ return `${propertyId}_${pmsType}_webhook`;
69
59
  }
70
- async addWebhookToQueue(propertyId, pmsType, webhookData, options = {}) {
71
- const queueName = this.getQueueName(propertyId, pmsType);
72
- const queue = await this.getOrCreateQueue(queueName);
73
- const jobData = {
60
+ /**
61
+ * Add a webhook to the appropriate queue based on propertyId and pmsType
62
+ * Creates queue if it doesn't exist
63
+ */
64
+ async addWebhookToQueue(propertyId, pmsType, webhookData, options) {
65
+ const queueName = this.generateQueueName(propertyId, pmsType);
66
+ // Get or create queue using the static method
67
+ const queue = WebhookQueueService.getOrCreateQueue(queueName, this.webhookQueues);
68
+ // Add job to queue immediately with 5 minute TTL
69
+ const job = await queue.add("webhook-job", {
74
70
  propertyId,
75
71
  pmsType,
76
72
  webhookData,
77
73
  timestamp: new Date().toISOString(),
78
- retryCount: 0,
79
- };
80
- const jobOptions = {
81
- priority: options.priority || 1,
82
- delay: options.delay || 0,
83
- attempts: options.attempts || this.config.maxRetries,
84
- backoff: options.backoff || {
85
- type: "exponential",
86
- delay: this.config.backoffDelay,
87
- },
88
- removeOnComplete: this.config.removeOnComplete,
89
- removeOnFail: this.config.removeOnFail,
90
- timeout: this.config.jobTimeout,
91
- };
92
- const job = await queue.add("process_webhook", jobData, jobOptions);
74
+ }, {
75
+ removeOnComplete: { age: 5 * 60 }, // Remove after 5 minutes
76
+ removeOnFail: { age: 5 * 60 }, // Remove failed jobs after 5 minutes
77
+ attempts: 1, // Only try once
78
+ });
93
79
  return job.id;
94
80
  }
95
- async getQueueStatus(propertyId, pmsType) {
96
- const queueName = this.getQueueName(propertyId, pmsType);
97
- const queue = this.webhookQueues.get(queueName);
98
- if (!queue) {
99
- return {
100
- waiting: 0,
101
- active: 0,
102
- completed: 0,
103
- failed: 0,
104
- delayed: 0,
105
- };
106
- }
107
- const [waiting, active, completed, failed, delayed] = await Promise.all([
108
- queue.getWaiting(),
109
- queue.getActive(),
110
- queue.getCompleted(),
111
- queue.getFailed(),
112
- queue.getDelayed(),
113
- ]);
114
- return {
115
- waiting: waiting.length,
116
- active: active.length,
117
- completed: completed.length,
118
- failed: failed.length,
119
- delayed: delayed.length,
120
- };
121
- }
122
- async getAllPropertyQueueStatuses(propertyId) {
123
- const pmsTypes = ["CLOUDBEDS", "HOTELKEY", "STAYNTOUCH"];
124
- const statuses = {};
125
- for (const pmsType of pmsTypes) {
126
- statuses[pmsType] = await this.getQueueStatus(propertyId, pmsType);
127
- }
128
- return statuses;
129
- }
130
- async getQueueMetrics(propertyId, pmsType) {
131
- const queueName = this.getQueueName(propertyId, pmsType);
132
- const queue = this.webhookQueues.get(queueName);
133
- if (!queue) {
134
- return {
135
- totalProcessed: 0,
136
- totalFailed: 0,
137
- averageProcessingTime: 0,
138
- queueName,
139
- };
140
- }
141
- const [completed, failed] = await Promise.all([
142
- queue.getCompleted(),
143
- queue.getFailed(),
144
- ]);
145
- const totalProcessed = completed.length;
146
- const totalFailed = failed.length;
147
- // Calculate average processing time from completed jobs
148
- let totalProcessingTime = 0;
149
- let processedWithTime = 0;
150
- for (const job of completed) {
151
- if (job.processedOn && job.timestamp) {
152
- totalProcessingTime += job.processedOn - job.timestamp;
153
- processedWithTime++;
154
- }
155
- }
156
- const averageProcessingTime = processedWithTime > 0 ? totalProcessingTime / processedWithTime : 0;
157
- const lastProcessedAt = completed.length > 0
158
- ? new Date(completed[0].processedOn || 0).toISOString()
159
- : undefined;
160
- return {
161
- totalProcessed,
162
- totalFailed,
163
- averageProcessingTime,
164
- lastProcessedAt,
165
- queueName,
166
- };
167
- }
168
- async cleanupQueue(propertyId, pmsType) {
169
- const queueName = this.getQueueName(propertyId, pmsType);
170
- const queue = this.webhookQueues.get(queueName);
171
- if (queue) {
172
- // BullMQ v5: clean(grace, limit, type)
173
- await queue.clean(3600000, 1000, "completed"); // Clean completed jobs older than 1 hour
174
- await queue.clean(7200000, 1000, "failed"); // Clean failed jobs older than 2 hours
175
- }
176
- }
177
- async pauseQueue(propertyId, pmsType) {
178
- const queueName = this.getQueueName(propertyId, pmsType);
179
- const queue = this.webhookQueues.get(queueName);
180
- if (queue) {
181
- await queue.pause();
182
- }
183
- }
184
- async resumeQueue(propertyId, pmsType) {
185
- const queueName = this.getQueueName(propertyId, pmsType);
186
- const queue = this.webhookQueues.get(queueName);
187
- if (queue) {
188
- await queue.resume();
189
- }
190
- }
191
- async getActiveQueues() {
192
- return Array.from(this.webhookQueues.keys());
193
- }
194
- async shutdown() {
195
- // Stop all workers
196
- for (const worker of this.workers.values()) {
197
- await worker.stopProcessing();
198
- }
199
- // Close all queues
200
- for (const queue of this.webhookQueues.values()) {
201
- await queue.close();
202
- }
203
- // Close Redis connection
204
- await this.redisConnection.quit();
205
- this.webhookQueues.clear();
206
- this.workers.clear();
207
- }
208
- async queueExists(propertyId, pmsType) {
209
- const queueName = this.getQueueName(propertyId, pmsType);
210
- return this.webhookQueues.has(queueName);
211
- }
212
- async getQueueConfig(propertyId, pmsType) {
213
- const queueName = this.getQueueName(propertyId, pmsType);
214
- const queue = this.webhookQueues.get(queueName);
215
- if (!queue) {
216
- return null;
217
- }
218
- return {
219
- name: queue.name,
220
- client: queue.client,
221
- opts: queue.opts,
222
- };
223
- }
224
- async updateQueueConfig(propertyId, pmsType, config) {
225
- // Note: BullMQ doesn't support runtime config updates
226
- // This would require recreating the queue
227
- throw new Error("Queue configuration updates not supported at runtime");
228
- }
229
- /**
230
- * Set webhook processor function for a specific queue
231
- */
232
- async setWebhookProcessor(propertyId, pmsType, processor) {
233
- const queueName = this.getQueueName(propertyId, pmsType);
234
- let worker = this.workers.get(queueName);
235
- if (!worker) {
236
- worker = new WebhookWorker_1.WebhookWorker(this.redisConnection);
237
- this.workers.set(queueName, worker);
238
- }
239
- worker.setWebhookProcessor(processor);
240
- await worker.startProcessing(queueName);
241
- }
242
- getQueueName(propertyId, pmsType) {
243
- return `${propertyId}_${pmsType}_webhook`;
244
- }
245
- async getOrCreateQueue(queueName) {
246
- if (!this.webhookQueues.has(queueName)) {
247
- const queue = new bullmq_1.Queue(queueName, {
248
- connection: this.redisConnection,
249
- defaultJobOptions: {
250
- removeOnComplete: this.config.removeOnComplete,
251
- removeOnFail: this.config.removeOnFail,
252
- attempts: this.config.maxRetries,
253
- backoff: {
254
- type: "exponential",
255
- delay: this.config.backoffDelay,
256
- },
257
- },
258
- });
259
- this.webhookQueues.set(queueName, queue);
260
- }
261
- return this.webhookQueues.get(queueName);
81
+ static getOrCreateQueue(queueKey, queues) {
82
+ return (queues.get(queueKey) ??
83
+ queues
84
+ .set(queueKey, new (require("bullmq").Queue)(queueKey, {
85
+ connection: (0, redis_1.getRedisClient)(),
86
+ }))
87
+ .get(queueKey));
262
88
  }
263
89
  };
264
90
  __setFunctionName(_classThis, "WebhookQueueService");
@@ -1,4 +1 @@
1
- export * from "./WebhookQueueFactory";
2
- export * from "./WebhookQueueIntegration";
3
1
  export * from "./WebhookQueueService";
4
- export * from "./WebhookWorker";
@@ -14,7 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./WebhookQueueFactory"), exports);
18
- __exportStar(require("./WebhookQueueIntegration"), exports);
19
17
  __exportStar(require("./WebhookQueueService"), exports);
20
- __exportStar(require("./WebhookWorker"), exports);
@@ -36,25 +36,4 @@ export interface IWebhookQueueOptions {
36
36
  delay: number;
37
37
  };
38
38
  }
39
- export interface IWebhookProcessingResult {
40
- success: boolean;
41
- propertyId: string;
42
- pmsType: string;
43
- timestamp: string;
44
- error?: string;
45
- processingTime?: number;
46
- }
47
- export interface IWebhookQueueMetrics {
48
- totalProcessed: number;
49
- totalFailed: number;
50
- averageProcessingTime: number;
51
- lastProcessedAt?: string;
52
- queueName: string;
53
- }
54
39
  export type PMS_TYPE = "CLOUDBEDS" | "HOTELKEY" | "STAYNTOUCH";
55
- export interface IWebhookPayload {
56
- eventType?: string;
57
- propertyId?: string;
58
- reservationId?: string;
59
- [key: string]: any;
60
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dt-common-device",
3
- "version": "7.6.9",
3
+ "version": "7.6.11",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [