dt-common-device 7.6.6 → 7.6.9

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 (221) hide show
  1. package/dist/admin/Admin.repository.d.ts +7 -0
  2. package/dist/admin/Admin.repository.js +182 -0
  3. package/dist/admin/Admin.service.d.ts +5 -0
  4. package/dist/admin/Admin.service.js +17 -0
  5. package/dist/admin/index.d.ts +1 -0
  6. package/dist/admin/index.js +17 -0
  7. package/dist/audit/AuditProperties.d.ts +16 -0
  8. package/dist/audit/AuditProperties.js +2 -0
  9. package/dist/chronicle/IChronicle.interface.d.ts +14 -0
  10. package/dist/chronicle/IChronicle.interface.js +2 -0
  11. package/dist/chronicle/chronicle.service.d.ts +4 -0
  12. package/dist/chronicle/chronicle.service.js +44 -0
  13. package/dist/connection/Connection.repository.d.ts +8 -0
  14. package/dist/connection/Connection.repository.js +92 -0
  15. package/dist/connection/Connection.service.d.ts +8 -0
  16. package/dist/connection/Connection.service.js +32 -0
  17. package/dist/connection/IConnection.d.ts +28 -0
  18. package/dist/connection/IConnection.js +16 -0
  19. package/dist/connection/index.d.ts +2 -0
  20. package/dist/connection/index.js +18 -0
  21. package/dist/device/cloud/entities/CloudConnection.d.ts +6 -0
  22. package/dist/device/cloud/entities/CloudConnection.js +6 -0
  23. package/dist/device/cloud/entities/CloudDevice.d.ts +16 -0
  24. package/dist/device/cloud/entities/CloudDevice.js +26 -0
  25. package/dist/device/cloud/entities/CloudDeviceService.d.ts +5 -0
  26. package/dist/device/cloud/entities/CloudDeviceService.js +9 -0
  27. package/dist/device/cloud/entities/DeviceFactory.d.ts +7 -0
  28. package/dist/device/cloud/entities/DeviceFactory.js +80 -0
  29. package/dist/device/cloud/entities/index.d.ts +3 -0
  30. package/dist/device/cloud/entities/index.js +19 -0
  31. package/dist/device/cloud/interface.d.ts +101 -0
  32. package/dist/device/cloud/interface.js +3 -0
  33. package/dist/device/cloud/interfaces/ICloudConnection.d.ts +5 -0
  34. package/dist/device/cloud/interfaces/ICloudConnection.js +2 -0
  35. package/dist/device/cloud/interfaces/ICloudDevice.d.ts +9 -0
  36. package/dist/device/cloud/interfaces/ICloudDevice.js +2 -0
  37. package/dist/device/cloud/interfaces/ICloudDeviceService.d.ts +4 -0
  38. package/dist/device/cloud/interfaces/ICloudDeviceService.js +2 -0
  39. package/dist/device/cloud/interfaces/IConnectionService.d.ts +7 -0
  40. package/dist/device/cloud/interfaces/IConnectionService.js +2 -0
  41. package/dist/device/cloud/interfaces/IDeviceConnectionService.d.ts +7 -0
  42. package/dist/device/cloud/interfaces/IDeviceConnectionService.js +3 -0
  43. package/dist/device/cloud/interfaces/IDeviceFactory.d.ts +4 -0
  44. package/dist/device/cloud/interfaces/IDeviceFactory.js +2 -0
  45. package/dist/device/cloud/interfaces/IDeviceService.d.ts +8 -0
  46. package/dist/device/cloud/interfaces/IDeviceService.js +2 -0
  47. package/dist/device/cloud/interfaces/IDevicesService.d.ts +9 -0
  48. package/dist/device/cloud/interfaces/IDevicesService.js +2 -0
  49. package/dist/device/cloud/interfaces/IHubService.d.ts +5 -0
  50. package/dist/device/cloud/interfaces/IHubService.js +2 -0
  51. package/dist/device/cloud/interfaces/IRawDataTransformer.d.ts +4 -0
  52. package/dist/device/cloud/interfaces/IRawDataTransformer.js +2 -0
  53. package/dist/device/cloud/interfaces/IRawDevice.d.ts +17 -0
  54. package/dist/device/cloud/interfaces/IRawDevice.js +11 -0
  55. package/dist/device/cloud/interfaces/index.d.ts +5 -0
  56. package/dist/device/cloud/interfaces/index.js +21 -0
  57. package/dist/device/cloud/services/CloudDevice.service.d.ts +5 -0
  58. package/dist/device/cloud/services/CloudDevice.service.js +9 -0
  59. package/dist/device/cloud/services/Connection.service.d.ts +8 -0
  60. package/dist/device/cloud/services/Connection.service.js +6 -0
  61. package/dist/device/cloud/services/Device.service.d.ts +39 -0
  62. package/dist/device/cloud/services/Device.service.js +9 -0
  63. package/dist/device/cloud/services/DeviceCloudService.d.ts +42 -0
  64. package/dist/device/cloud/services/DeviceCloudService.js +59 -0
  65. package/dist/device/cloud/services/DeviceHub.service.d.ts +3 -0
  66. package/dist/device/cloud/services/DeviceHub.service.js +6 -0
  67. package/dist/device/cloud/services/Hub.service.d.ts +25 -0
  68. package/dist/device/cloud/services/Hub.service.js +9 -0
  69. package/dist/device/cloud/services/SmartThingsDeviceService.d.ts +38 -0
  70. package/dist/device/cloud/services/SmartThingsDeviceService.js +52 -0
  71. package/dist/device/cloud/services/index.d.ts +2 -0
  72. package/dist/device/cloud/services/index.js +18 -0
  73. package/dist/device/cloud/types.d.ts +52 -0
  74. package/dist/device/cloud/types.js +15 -0
  75. package/dist/device/index.d.ts +4 -0
  76. package/dist/device/index.js +20 -0
  77. package/dist/device/local/entities/AlertBuilder.d.ts +87 -0
  78. package/dist/device/local/entities/AlertBuilder.example.d.ts +11 -0
  79. package/dist/device/local/entities/AlertBuilder.example.js +117 -0
  80. package/dist/device/local/entities/AlertBuilder.js +179 -0
  81. package/dist/device/local/entities/IssueBuilder.d.ts +109 -0
  82. package/dist/device/local/entities/IssueBuilder.example.d.ts +16 -0
  83. package/dist/device/local/entities/IssueBuilder.example.js +196 -0
  84. package/dist/device/local/entities/IssueBuilder.js +237 -0
  85. package/dist/device/local/entities/index.d.ts +2 -0
  86. package/dist/device/local/entities/index.js +7 -0
  87. package/dist/device/local/events/EventHandler.d.ts +11 -0
  88. package/dist/device/local/events/EventHandler.js +86 -0
  89. package/dist/device/local/events/Events.d.ts +54 -0
  90. package/dist/device/local/events/Events.js +57 -0
  91. package/dist/device/local/events/index.d.ts +2 -0
  92. package/dist/device/local/events/index.js +7 -0
  93. package/dist/device/local/handler/EventHandler.d.ts +7 -0
  94. package/dist/device/local/handler/EventHandler.js +44 -0
  95. package/dist/device/local/interface.d.ts +0 -0
  96. package/dist/device/local/interface.js +1 -0
  97. package/dist/device/local/interfaces/IConnection.d.ts +26 -0
  98. package/dist/device/local/interfaces/IConnection.js +14 -0
  99. package/dist/device/local/interfaces/IDevice.d.ts +68 -0
  100. package/dist/device/local/interfaces/IDevice.js +10 -0
  101. package/dist/device/local/interfaces/IDtDevice.d.ts +16 -0
  102. package/dist/device/local/interfaces/IDtDevice.js +2 -0
  103. package/dist/device/local/interfaces/IHub.d.ts +46 -0
  104. package/dist/device/local/interfaces/IHub.js +2 -0
  105. package/dist/device/local/interfaces/IProperty.d.ts +29 -0
  106. package/dist/device/local/interfaces/IProperty.js +2 -0
  107. package/dist/device/local/interfaces/ISchedule.d.ts +25 -0
  108. package/dist/device/local/interfaces/ISchedule.js +2 -0
  109. package/dist/device/local/interfaces/index.d.ts +3 -0
  110. package/dist/device/local/interfaces/index.js +19 -0
  111. package/dist/device/local/models/Alert.model.d.ts +28 -0
  112. package/dist/device/local/models/Alert.model.js +222 -0
  113. package/dist/device/local/models/Issue.model.d.ts +28 -0
  114. package/dist/device/local/models/Issue.model.js +260 -0
  115. package/dist/device/local/repository/Alert.repository.d.ts +106 -0
  116. package/dist/device/local/repository/Alert.repository.js +374 -0
  117. package/dist/device/local/repository/Connection.repository.d.ts +8 -0
  118. package/dist/device/local/repository/Connection.repository.js +92 -0
  119. package/dist/device/local/repository/Device.repository.d.ts +30 -0
  120. package/dist/device/local/repository/Device.repository.js +325 -0
  121. package/dist/device/local/repository/Hub.repository.d.ts +13 -0
  122. package/dist/device/local/repository/Hub.repository.js +139 -0
  123. package/dist/device/local/repository/Issue.repository.d.ts +113 -0
  124. package/dist/device/local/repository/Issue.repository.js +401 -0
  125. package/dist/device/local/repository/Property.repository.d.ts +8 -0
  126. package/dist/device/local/repository/Property.repository.js +95 -0
  127. package/dist/device/local/repository/Schedule.repository.d.ts +9 -0
  128. package/dist/device/local/repository/Schedule.repository.js +109 -0
  129. package/dist/device/local/services/Alert.service.d.ts +137 -0
  130. package/dist/device/local/services/Alert.service.js +475 -0
  131. package/dist/device/local/services/AlertService.example.d.ts +55 -0
  132. package/dist/device/local/services/AlertService.example.js +148 -0
  133. package/dist/device/local/services/Connection.service.d.ts +8 -0
  134. package/dist/device/local/services/Connection.service.js +32 -0
  135. package/dist/device/local/services/Device.service.d.ts +40 -0
  136. package/dist/device/local/services/Device.service.js +391 -0
  137. package/dist/device/local/services/DeviceHub.service.d.ts +11 -0
  138. package/dist/device/local/services/DeviceHub.service.js +40 -0
  139. package/dist/device/local/services/Hub.service.d.ts +12 -0
  140. package/dist/device/local/services/Hub.service.js +107 -0
  141. package/dist/device/local/services/Issue.service.d.ts +168 -0
  142. package/dist/device/local/services/Issue.service.js +642 -0
  143. package/dist/device/local/services/IssueService.example.d.ts +68 -0
  144. package/dist/device/local/services/IssueService.example.js +177 -0
  145. package/dist/device/local/services/Property.service.d.ts +8 -0
  146. package/dist/device/local/services/Property.service.js +36 -0
  147. package/dist/device/local/services/Schedule.service.d.ts +9 -0
  148. package/dist/device/local/services/Schedule.service.js +26 -0
  149. package/dist/device/local/services/index.d.ts +3 -0
  150. package/dist/device/local/services/index.js +19 -0
  151. package/dist/entities/accessGroup/AccessGroup.repository.d.ts +1 -2
  152. package/dist/entities/accessGroup/AccessGroup.repository.js +1 -4
  153. package/dist/entities/accessGroup/AccessGroup.service.d.ts +1 -2
  154. package/dist/entities/accessGroup/AccessGroup.service.js +3 -4
  155. package/dist/entities/guest/Guest.repository.d.ts +1 -1
  156. package/dist/entities/guest/Guest.repository.js +2 -5
  157. package/dist/entities/guest/Guest.service.d.ts +1 -1
  158. package/dist/entities/guest/Guest.service.js +1 -4
  159. package/dist/entities/schedules/Schedule.repository.d.ts +1 -1
  160. package/dist/entities/schedules/Schedule.repository.js +2 -5
  161. package/dist/entities/schedules/Schedule.service.d.ts +1 -1
  162. package/dist/entities/schedules/Schedule.service.js +1 -4
  163. package/dist/entities/user/User.repository.js +1 -4
  164. package/dist/entities/user/User.service.d.ts +1 -1
  165. package/dist/entities/user/User.service.js +1 -4
  166. package/dist/entities/zone/Zone.service.js +1 -4
  167. package/dist/pms/IPms.d.ts +6 -0
  168. package/dist/pms/IPms.js +10 -0
  169. package/dist/pms/index.d.ts +1 -0
  170. package/dist/pms/index.js +18 -0
  171. package/dist/pms/webhookQueue/examples/index.d.ts +2 -0
  172. package/dist/pms/webhookQueue/examples/index.js +18 -0
  173. package/dist/pms/webhookQueue/examples/pms-integration.d.ts +65 -0
  174. package/dist/pms/webhookQueue/examples/pms-integration.js +254 -0
  175. package/dist/pms/webhookQueue/examples/usage.d.ts +7 -0
  176. package/dist/pms/webhookQueue/examples/usage.js +175 -0
  177. package/dist/pms/webhookQueue/index.d.ts +3 -0
  178. package/dist/pms/webhookQueue/index.js +20 -0
  179. package/dist/pms/webhookQueue/interfaces/IWebhookQueue.d.ts +55 -0
  180. package/dist/pms/webhookQueue/interfaces/IWebhookQueue.js +2 -0
  181. package/dist/pms/webhookQueue/interfaces/IWebhookWorker.d.ts +38 -0
  182. package/dist/pms/webhookQueue/interfaces/IWebhookWorker.js +2 -0
  183. package/dist/pms/webhookQueue/interfaces/index.d.ts +2 -0
  184. package/dist/pms/webhookQueue/interfaces/index.js +18 -0
  185. package/dist/pms/webhookQueue/services/WebhookQueueFactory.d.ts +38 -0
  186. package/dist/pms/webhookQueue/services/WebhookQueueFactory.js +131 -0
  187. package/dist/pms/webhookQueue/services/WebhookQueueIntegration.d.ts +70 -0
  188. package/dist/pms/webhookQueue/services/WebhookQueueIntegration.js +207 -0
  189. package/dist/pms/webhookQueue/services/WebhookQueueService.d.ts +27 -0
  190. package/dist/pms/webhookQueue/services/WebhookQueueService.js +274 -0
  191. package/dist/pms/webhookQueue/services/WebhookWorker.d.ts +37 -0
  192. package/dist/pms/webhookQueue/services/WebhookWorker.js +201 -0
  193. package/dist/pms/webhookQueue/services/index.d.ts +4 -0
  194. package/dist/pms/webhookQueue/services/index.js +20 -0
  195. package/dist/pms/webhookQueue/types/index.d.ts +1 -0
  196. package/dist/pms/webhookQueue/types/index.js +17 -0
  197. package/dist/pms/webhookQueue/types/webhook.types.d.ts +60 -0
  198. package/dist/pms/webhookQueue/types/webhook.types.js +2 -0
  199. package/dist/property/IProperty.d.ts +29 -0
  200. package/dist/property/IProperty.js +2 -0
  201. package/dist/property/Property.repository.d.ts +8 -0
  202. package/dist/property/Property.repository.js +109 -0
  203. package/dist/property/Property.service.d.ts +8 -0
  204. package/dist/property/Property.service.js +124 -0
  205. package/dist/property/index.d.ts +2 -0
  206. package/dist/property/index.js +18 -0
  207. package/dist/queue/interfaces/IHttpRequestJob.d.ts +9 -0
  208. package/dist/queue/interfaces/IHttpRequestJob.js +2 -0
  209. package/dist/types/alert.types.d.ts +57 -0
  210. package/dist/types/alert.types.js +22 -0
  211. package/dist/types/config.types.d.ts +19 -0
  212. package/dist/types/config.types.js +2 -0
  213. package/dist/types/index.d.ts +3 -0
  214. package/dist/types/index.js +19 -0
  215. package/dist/types/issue.types.d.ts +90 -0
  216. package/dist/types/issue.types.js +40 -0
  217. package/dist/utils/http-utils.d.ts +13 -0
  218. package/dist/utils/http-utils.js +117 -0
  219. package/dist/utils/redis.utils.d.ts +1 -0
  220. package/dist/utils/redis.utils.js +3 -0
  221. package/package.json +1 -1
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
37
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
38
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.WebhookQueueService = void 0;
42
+ const bullmq_1 = require("bullmq");
43
+ const ioredis_1 = require("ioredis");
44
+ const typedi_1 = require("typedi");
45
+ const WebhookWorker_1 = require("./WebhookWorker");
46
+ let WebhookQueueService = (() => {
47
+ let _classDecorators = [(0, typedi_1.Service)()];
48
+ let _classDescriptor;
49
+ let _classExtraInitializers = [];
50
+ let _classThis;
51
+ 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
+ });
69
+ }
70
+ async addWebhookToQueue(propertyId, pmsType, webhookData, options = {}) {
71
+ const queueName = this.getQueueName(propertyId, pmsType);
72
+ const queue = await this.getOrCreateQueue(queueName);
73
+ const jobData = {
74
+ propertyId,
75
+ pmsType,
76
+ webhookData,
77
+ 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);
93
+ return job.id;
94
+ }
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);
262
+ }
263
+ };
264
+ __setFunctionName(_classThis, "WebhookQueueService");
265
+ (() => {
266
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
267
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
268
+ WebhookQueueService = _classThis = _classDescriptor.value;
269
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
270
+ __runInitializers(_classThis, _classExtraInitializers);
271
+ })();
272
+ return WebhookQueueService = _classThis;
273
+ })();
274
+ exports.WebhookQueueService = WebhookQueueService;
@@ -0,0 +1,37 @@
1
+ import { Worker } from "bullmq";
2
+ import { Redis } from "ioredis";
3
+ import { IWebhookWorker } from "../interfaces";
4
+ import { IWebhookJobData, IWebhookProcessingResult } from "../types/webhook.types";
5
+ export declare class WebhookWorker implements IWebhookWorker {
6
+ private worker;
7
+ private webhookProcessor;
8
+ private redisConnection;
9
+ private isRunning;
10
+ private processedJobs;
11
+ private failedJobs;
12
+ private lastProcessedAt?;
13
+ constructor(redisConnection: Redis);
14
+ startProcessing(queueName: string): Promise<void>;
15
+ stopProcessing(): Promise<void>;
16
+ processWebhookJob(jobData: IWebhookJobData): Promise<IWebhookProcessingResult>;
17
+ handleError(error: Error, jobData: IWebhookJobData): Promise<void>;
18
+ getWorkerStatus(): Promise<{
19
+ isRunning: boolean;
20
+ processedJobs: number;
21
+ failedJobs: number;
22
+ lastProcessedAt?: string;
23
+ }>;
24
+ setWebhookProcessor(processor: (webhookData: any, pmsType: string) => Promise<any>): void;
25
+ /**
26
+ * Get the underlying BullMQ worker instance
27
+ */
28
+ getWorker(): Worker | null;
29
+ /**
30
+ * Check if the worker is currently processing
31
+ */
32
+ isWorkerRunning(): boolean;
33
+ /**
34
+ * Reset worker statistics
35
+ */
36
+ resetStats(): void;
37
+ }
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
37
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
38
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.WebhookWorker = void 0;
42
+ const bullmq_1 = require("bullmq");
43
+ const typedi_1 = require("typedi");
44
+ let WebhookWorker = (() => {
45
+ let _classDecorators = [(0, typedi_1.Service)()];
46
+ let _classDescriptor;
47
+ let _classExtraInitializers = [];
48
+ let _classThis;
49
+ var WebhookWorker = _classThis = class {
50
+ constructor(redisConnection) {
51
+ this.worker = null;
52
+ this.webhookProcessor = null;
53
+ this.isRunning = false;
54
+ this.processedJobs = 0;
55
+ this.failedJobs = 0;
56
+ this.redisConnection = redisConnection;
57
+ }
58
+ async startProcessing(queueName) {
59
+ if (this.isRunning) {
60
+ return;
61
+ }
62
+ this.worker = new bullmq_1.Worker(queueName, async (job) => {
63
+ try {
64
+ const startTime = Date.now();
65
+ const result = await this.processWebhookJob(job.data);
66
+ const processingTime = Date.now() - startTime;
67
+ this.processedJobs++;
68
+ this.lastProcessedAt = new Date().toISOString();
69
+ return {
70
+ ...result,
71
+ processingTime,
72
+ };
73
+ }
74
+ catch (error) {
75
+ this.failedJobs++;
76
+ await this.handleError(error, job.data);
77
+ throw error;
78
+ }
79
+ }, {
80
+ connection: this.redisConnection,
81
+ lockDuration: 300000, // 5 minutes lock duration
82
+ stalledInterval: 60000, // 1 minute stall check interval
83
+ concurrency: 1, // Process one webhook at a time per queue
84
+ });
85
+ // Set up event handlers
86
+ this.worker.on("completed", (job) => {
87
+ console.log(`[Webhook Worker] Job ${job.id} completed successfully for queue ${queueName}`);
88
+ });
89
+ this.worker.on("failed", (job, err) => {
90
+ if (job) {
91
+ console.error(`[Webhook Worker] Job ${job.id} failed for queue ${queueName} with error: ${err.message}`);
92
+ }
93
+ else {
94
+ console.error(`[Webhook Worker] Unknown job failed for queue ${queueName} with error: ${err.message}`);
95
+ }
96
+ });
97
+ this.worker.on("error", (err) => {
98
+ console.error(`[Webhook Worker] Worker error for queue ${queueName}:`, err);
99
+ });
100
+ this.worker.on("stalled", (jobId) => {
101
+ console.warn(`[Webhook Worker] Job ${jobId} stalled in queue ${queueName}`);
102
+ });
103
+ this.isRunning = true;
104
+ console.log(`[Webhook Worker] Started processing queue: ${queueName}`);
105
+ }
106
+ async stopProcessing() {
107
+ if (!this.isRunning || !this.worker) {
108
+ return;
109
+ }
110
+ await this.worker.close();
111
+ this.worker = null;
112
+ this.isRunning = false;
113
+ console.log("[Webhook Worker] Stopped processing");
114
+ }
115
+ async processWebhookJob(jobData) {
116
+ if (!this.webhookProcessor) {
117
+ throw new Error("Webhook processor not set");
118
+ }
119
+ try {
120
+ const startTime = Date.now();
121
+ // Process the webhook using the provided processor function
122
+ await this.webhookProcessor(jobData.webhookData, jobData.pmsType);
123
+ const processingTime = Date.now() - startTime;
124
+ return {
125
+ success: true,
126
+ propertyId: jobData.propertyId,
127
+ pmsType: jobData.pmsType,
128
+ timestamp: jobData.timestamp,
129
+ processingTime,
130
+ };
131
+ }
132
+ catch (error) {
133
+ const processingTime = Date.now() - Date.parse(jobData.timestamp);
134
+ return {
135
+ success: false,
136
+ propertyId: jobData.propertyId,
137
+ pmsType: jobData.pmsType,
138
+ timestamp: jobData.timestamp,
139
+ error: error.message,
140
+ processingTime,
141
+ };
142
+ }
143
+ }
144
+ async handleError(error, jobData) {
145
+ console.error(`[Webhook Worker] Error processing webhook for property: ${jobData.propertyId}, PMS: ${jobData.pmsType}:`, error);
146
+ // Log additional context
147
+ console.error(`[Webhook Worker] Job data:`, {
148
+ propertyId: jobData.propertyId,
149
+ pmsType: jobData.pmsType,
150
+ timestamp: jobData.timestamp,
151
+ retryCount: jobData.retryCount,
152
+ });
153
+ // You can add additional error handling here:
154
+ // - Send to error monitoring service
155
+ // - Create error tickets
156
+ // - Notify administrators
157
+ // - Log to external logging service
158
+ }
159
+ async getWorkerStatus() {
160
+ return {
161
+ isRunning: this.isRunning,
162
+ processedJobs: this.processedJobs,
163
+ failedJobs: this.failedJobs,
164
+ lastProcessedAt: this.lastProcessedAt,
165
+ };
166
+ }
167
+ setWebhookProcessor(processor) {
168
+ this.webhookProcessor = processor;
169
+ }
170
+ /**
171
+ * Get the underlying BullMQ worker instance
172
+ */
173
+ getWorker() {
174
+ return this.worker;
175
+ }
176
+ /**
177
+ * Check if the worker is currently processing
178
+ */
179
+ isWorkerRunning() {
180
+ return this.isRunning && this.worker !== null;
181
+ }
182
+ /**
183
+ * Reset worker statistics
184
+ */
185
+ resetStats() {
186
+ this.processedJobs = 0;
187
+ this.failedJobs = 0;
188
+ this.lastProcessedAt = undefined;
189
+ }
190
+ };
191
+ __setFunctionName(_classThis, "WebhookWorker");
192
+ (() => {
193
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
194
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
195
+ WebhookWorker = _classThis = _classDescriptor.value;
196
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
197
+ __runInitializers(_classThis, _classExtraInitializers);
198
+ })();
199
+ return WebhookWorker = _classThis;
200
+ })();
201
+ exports.WebhookWorker = WebhookWorker;
@@ -0,0 +1,4 @@
1
+ export * from "./WebhookQueueFactory";
2
+ export * from "./WebhookQueueIntegration";
3
+ export * from "./WebhookQueueService";
4
+ export * from "./WebhookWorker";
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./WebhookQueueFactory"), exports);
18
+ __exportStar(require("./WebhookQueueIntegration"), exports);
19
+ __exportStar(require("./WebhookQueueService"), exports);
20
+ __exportStar(require("./WebhookWorker"), exports);
@@ -0,0 +1 @@
1
+ export * from "./webhook.types";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./webhook.types"), exports);
@@ -0,0 +1,60 @@
1
+ export interface IWebhookJobData {
2
+ propertyId: string;
3
+ pmsType: string;
4
+ webhookData: any;
5
+ timestamp: string;
6
+ retryCount?: number;
7
+ }
8
+ export interface IWebhookQueueConfig {
9
+ redisHost: string;
10
+ redisPort: number;
11
+ maxRetries?: number;
12
+ backoffDelay?: number;
13
+ jobTimeout?: number;
14
+ removeOnComplete?: {
15
+ age: number;
16
+ count: number;
17
+ };
18
+ removeOnFail?: {
19
+ age: number;
20
+ count: number;
21
+ };
22
+ }
23
+ export interface IWebhookQueueStatus {
24
+ waiting: number;
25
+ active: number;
26
+ completed: number;
27
+ failed: number;
28
+ delayed?: number;
29
+ }
30
+ export interface IWebhookQueueOptions {
31
+ priority?: number;
32
+ delay?: number;
33
+ attempts?: number;
34
+ backoff?: {
35
+ type: "exponential" | "fixed";
36
+ delay: number;
37
+ };
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
+ 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
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,29 @@
1
+ export interface IProperty {
2
+ id: string;
3
+ name: string;
4
+ apartment: string;
5
+ city: string;
6
+ country: string;
7
+ state: string;
8
+ street: string;
9
+ zipCode: string;
10
+ createdBy?: string;
11
+ isDeleted: boolean;
12
+ imageURL: string;
13
+ timezone: string;
14
+ officialName?: string;
15
+ sameAsOfficialName?: boolean;
16
+ phoneNumber?: string;
17
+ phoneNumberCountryCode?: string;
18
+ propertyKey?: string;
19
+ hubNetworkId?: string;
20
+ isTimeZoneOverridden: boolean;
21
+ createdAt: string;
22
+ updatedAt: string;
23
+ propertyBillingId?: string;
24
+ }
25
+ export interface IPropertySettings {
26
+ id: string;
27
+ propertyId: string;
28
+ settings: Record<string, any>;
29
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ import { IProperty, IPropertySettings } from "./IProperty";
2
+ export declare class PropertyRepository {
3
+ private readonly postgres;
4
+ constructor();
5
+ getPropertyPreferences(propertyId: string, keys?: string[]): Promise<IPropertySettings | null>;
6
+ getProperty(propertyId: string): Promise<IProperty | null>;
7
+ getAllProperties(): Promise<any[]>;
8
+ }