@stacksjs/ts-cloud-core 0.1.1

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 (251) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +321 -0
  3. package/package.json +31 -0
  4. package/src/advanced-features.test.ts +465 -0
  5. package/src/aws/cloudformation.ts +421 -0
  6. package/src/aws/cloudfront.ts +158 -0
  7. package/src/aws/credentials.test.ts +132 -0
  8. package/src/aws/credentials.ts +545 -0
  9. package/src/aws/index.ts +87 -0
  10. package/src/aws/s3.test.ts +188 -0
  11. package/src/aws/s3.ts +1088 -0
  12. package/src/aws/signature.test.ts +670 -0
  13. package/src/aws/signature.ts +1155 -0
  14. package/src/backup/disaster-recovery.test.ts +726 -0
  15. package/src/backup/disaster-recovery.ts +500 -0
  16. package/src/backup/index.ts +34 -0
  17. package/src/backup/manager.test.ts +498 -0
  18. package/src/backup/manager.ts +432 -0
  19. package/src/cicd/circleci.ts +430 -0
  20. package/src/cicd/github-actions.ts +424 -0
  21. package/src/cicd/gitlab-ci.ts +255 -0
  22. package/src/cicd/index.ts +8 -0
  23. package/src/cli/history.ts +396 -0
  24. package/src/cli/index.ts +10 -0
  25. package/src/cli/progress.ts +458 -0
  26. package/src/cli/repl.ts +454 -0
  27. package/src/cli/suggestions.ts +327 -0
  28. package/src/cli/table.test.ts +319 -0
  29. package/src/cli/table.ts +332 -0
  30. package/src/cloudformation/builder.test.ts +327 -0
  31. package/src/cloudformation/builder.ts +378 -0
  32. package/src/cloudformation/builders/api-gateway.ts +449 -0
  33. package/src/cloudformation/builders/cache.ts +334 -0
  34. package/src/cloudformation/builders/cdn.ts +278 -0
  35. package/src/cloudformation/builders/compute.ts +485 -0
  36. package/src/cloudformation/builders/database.ts +392 -0
  37. package/src/cloudformation/builders/functions.ts +343 -0
  38. package/src/cloudformation/builders/messaging.ts +140 -0
  39. package/src/cloudformation/builders/monitoring.ts +300 -0
  40. package/src/cloudformation/builders/network.ts +264 -0
  41. package/src/cloudformation/builders/queue.ts +147 -0
  42. package/src/cloudformation/builders/security.ts +399 -0
  43. package/src/cloudformation/builders/storage.ts +285 -0
  44. package/src/cloudformation/index.ts +30 -0
  45. package/src/cloudformation/types.ts +173 -0
  46. package/src/compliance/aws-config.ts +543 -0
  47. package/src/compliance/cloudtrail.ts +376 -0
  48. package/src/compliance/compliance.test.ts +423 -0
  49. package/src/compliance/guardduty.ts +446 -0
  50. package/src/compliance/index.ts +66 -0
  51. package/src/compliance/security-hub.ts +456 -0
  52. package/src/containers/build-optimization.ts +416 -0
  53. package/src/containers/containers.test.ts +508 -0
  54. package/src/containers/image-scanning.ts +360 -0
  55. package/src/containers/index.ts +9 -0
  56. package/src/containers/registry.ts +293 -0
  57. package/src/containers/service-mesh.ts +520 -0
  58. package/src/database/database.test.ts +762 -0
  59. package/src/database/index.ts +9 -0
  60. package/src/database/migrations.ts +444 -0
  61. package/src/database/performance.ts +528 -0
  62. package/src/database/replicas.ts +534 -0
  63. package/src/database/users.ts +494 -0
  64. package/src/dependency-graph.ts +143 -0
  65. package/src/deployment/ab-testing.ts +582 -0
  66. package/src/deployment/blue-green.ts +452 -0
  67. package/src/deployment/canary.ts +500 -0
  68. package/src/deployment/deployment.test.ts +526 -0
  69. package/src/deployment/index.ts +61 -0
  70. package/src/deployment/progressive.ts +62 -0
  71. package/src/dns/dns.test.ts +641 -0
  72. package/src/dns/dnssec.ts +315 -0
  73. package/src/dns/index.ts +8 -0
  74. package/src/dns/resolver.ts +496 -0
  75. package/src/dns/routing.ts +593 -0
  76. package/src/email/advanced/analytics.ts +445 -0
  77. package/src/email/advanced/index.ts +11 -0
  78. package/src/email/advanced/rules.ts +465 -0
  79. package/src/email/advanced/scheduling.ts +352 -0
  80. package/src/email/advanced/search.ts +412 -0
  81. package/src/email/advanced/shared-mailboxes.ts +404 -0
  82. package/src/email/advanced/templates.ts +455 -0
  83. package/src/email/advanced/threading.ts +281 -0
  84. package/src/email/analytics.ts +467 -0
  85. package/src/email/bounce-handling.ts +425 -0
  86. package/src/email/email.test.ts +431 -0
  87. package/src/email/handlers/__tests__/inbound.test.ts +38 -0
  88. package/src/email/handlers/__tests__/outbound.test.ts +37 -0
  89. package/src/email/handlers/converter.ts +227 -0
  90. package/src/email/handlers/feedback.ts +228 -0
  91. package/src/email/handlers/inbound.ts +169 -0
  92. package/src/email/handlers/outbound.ts +178 -0
  93. package/src/email/index.ts +15 -0
  94. package/src/email/reputation.ts +303 -0
  95. package/src/email/templates.ts +352 -0
  96. package/src/errors/index.test.ts +434 -0
  97. package/src/errors/index.ts +416 -0
  98. package/src/health-checks/index.ts +40 -0
  99. package/src/index.ts +360 -0
  100. package/src/intrinsic-functions.ts +118 -0
  101. package/src/lambda/concurrency.ts +330 -0
  102. package/src/lambda/destinations.ts +345 -0
  103. package/src/lambda/dlq.ts +425 -0
  104. package/src/lambda/index.ts +11 -0
  105. package/src/lambda/lambda.test.ts +840 -0
  106. package/src/lambda/layers.ts +263 -0
  107. package/src/lambda/versions.ts +376 -0
  108. package/src/lambda/vpc.ts +399 -0
  109. package/src/local/config.ts +114 -0
  110. package/src/local/index.ts +6 -0
  111. package/src/local/mock-aws.ts +351 -0
  112. package/src/modules/ai.ts +340 -0
  113. package/src/modules/api.ts +478 -0
  114. package/src/modules/auth.ts +805 -0
  115. package/src/modules/cache.ts +417 -0
  116. package/src/modules/cdn.ts +1062 -0
  117. package/src/modules/communication.ts +1094 -0
  118. package/src/modules/compute.ts +3348 -0
  119. package/src/modules/database.ts +554 -0
  120. package/src/modules/deployment.ts +1079 -0
  121. package/src/modules/dns.ts +337 -0
  122. package/src/modules/email.ts +1538 -0
  123. package/src/modules/filesystem.ts +515 -0
  124. package/src/modules/index.ts +32 -0
  125. package/src/modules/messaging.ts +486 -0
  126. package/src/modules/monitoring.ts +2086 -0
  127. package/src/modules/network.ts +664 -0
  128. package/src/modules/parameter-store.ts +325 -0
  129. package/src/modules/permissions.ts +1081 -0
  130. package/src/modules/phone.ts +494 -0
  131. package/src/modules/queue.ts +1260 -0
  132. package/src/modules/redirects.ts +464 -0
  133. package/src/modules/registry.ts +699 -0
  134. package/src/modules/search.ts +401 -0
  135. package/src/modules/secrets.ts +416 -0
  136. package/src/modules/security.ts +731 -0
  137. package/src/modules/sms.ts +389 -0
  138. package/src/modules/storage.ts +1120 -0
  139. package/src/modules/workflow.ts +680 -0
  140. package/src/multi-account/config.ts +521 -0
  141. package/src/multi-account/index.ts +7 -0
  142. package/src/multi-account/manager.ts +427 -0
  143. package/src/multi-region/cross-region.ts +410 -0
  144. package/src/multi-region/index.ts +8 -0
  145. package/src/multi-region/manager.ts +483 -0
  146. package/src/multi-region/regions.ts +435 -0
  147. package/src/network-security/index.ts +48 -0
  148. package/src/observability/index.ts +9 -0
  149. package/src/observability/logs.ts +522 -0
  150. package/src/observability/metrics.ts +460 -0
  151. package/src/observability/observability.test.ts +782 -0
  152. package/src/observability/synthetics.ts +568 -0
  153. package/src/observability/xray.ts +358 -0
  154. package/src/phone/advanced/analytics.ts +349 -0
  155. package/src/phone/advanced/callbacks.ts +428 -0
  156. package/src/phone/advanced/index.ts +8 -0
  157. package/src/phone/advanced/ivr-builder.ts +504 -0
  158. package/src/phone/advanced/recording.ts +310 -0
  159. package/src/phone/handlers/__tests__/incoming-call.test.ts +40 -0
  160. package/src/phone/handlers/incoming-call.ts +117 -0
  161. package/src/phone/handlers/missed-call.ts +116 -0
  162. package/src/phone/handlers/voicemail.ts +179 -0
  163. package/src/phone/index.ts +9 -0
  164. package/src/presets/api-backend.ts +134 -0
  165. package/src/presets/data-pipeline.ts +204 -0
  166. package/src/presets/extend.test.ts +295 -0
  167. package/src/presets/extend.ts +297 -0
  168. package/src/presets/fullstack-app.ts +144 -0
  169. package/src/presets/index.ts +27 -0
  170. package/src/presets/jamstack.ts +135 -0
  171. package/src/presets/microservices.ts +167 -0
  172. package/src/presets/ml-api.ts +208 -0
  173. package/src/presets/nodejs-server.ts +104 -0
  174. package/src/presets/nodejs-serverless.ts +114 -0
  175. package/src/presets/realtime-app.ts +184 -0
  176. package/src/presets/static-site.ts +64 -0
  177. package/src/presets/traditional-web-app.ts +339 -0
  178. package/src/presets/wordpress.ts +138 -0
  179. package/src/preview/github.test.ts +249 -0
  180. package/src/preview/github.ts +297 -0
  181. package/src/preview/index.ts +37 -0
  182. package/src/preview/manager.test.ts +440 -0
  183. package/src/preview/manager.ts +326 -0
  184. package/src/preview/notifications.test.ts +582 -0
  185. package/src/preview/notifications.ts +341 -0
  186. package/src/queue/batch-processing.ts +402 -0
  187. package/src/queue/dlq-monitoring.ts +402 -0
  188. package/src/queue/fifo.ts +342 -0
  189. package/src/queue/index.ts +9 -0
  190. package/src/queue/management.ts +428 -0
  191. package/src/queue/queue.test.ts +429 -0
  192. package/src/resource-mgmt/index.ts +39 -0
  193. package/src/resource-naming.ts +62 -0
  194. package/src/s3/index.ts +523 -0
  195. package/src/schema/cloud-config.schema.json +554 -0
  196. package/src/schema/index.ts +68 -0
  197. package/src/security/certificate-manager.ts +492 -0
  198. package/src/security/index.ts +9 -0
  199. package/src/security/scanning.ts +545 -0
  200. package/src/security/secrets-manager.ts +476 -0
  201. package/src/security/secrets-rotation.ts +456 -0
  202. package/src/security/security.test.ts +738 -0
  203. package/src/sms/advanced/ab-testing.ts +389 -0
  204. package/src/sms/advanced/analytics.ts +336 -0
  205. package/src/sms/advanced/campaigns.ts +523 -0
  206. package/src/sms/advanced/chatbot.ts +224 -0
  207. package/src/sms/advanced/index.ts +10 -0
  208. package/src/sms/advanced/link-tracking.ts +248 -0
  209. package/src/sms/advanced/mms.ts +308 -0
  210. package/src/sms/handlers/__tests__/send.test.ts +40 -0
  211. package/src/sms/handlers/delivery-status.ts +133 -0
  212. package/src/sms/handlers/receive.ts +162 -0
  213. package/src/sms/handlers/send.ts +174 -0
  214. package/src/sms/index.ts +9 -0
  215. package/src/stack-diff.ts +389 -0
  216. package/src/static-site/index.ts +85 -0
  217. package/src/template-builder.ts +110 -0
  218. package/src/template-validator.ts +574 -0
  219. package/src/utils/cache.ts +291 -0
  220. package/src/utils/diff.ts +269 -0
  221. package/src/utils/hash.ts +227 -0
  222. package/src/utils/index.ts +8 -0
  223. package/src/utils/parallel.ts +294 -0
  224. package/src/validators/credentials.test.ts +274 -0
  225. package/src/validators/credentials.ts +233 -0
  226. package/src/validators/quotas.test.ts +434 -0
  227. package/src/validators/quotas.ts +217 -0
  228. package/test/ai.test.ts +327 -0
  229. package/test/api.test.ts +511 -0
  230. package/test/auth.test.ts +632 -0
  231. package/test/cache.test.ts +406 -0
  232. package/test/cdn.test.ts +247 -0
  233. package/test/compute.test.ts +861 -0
  234. package/test/database.test.ts +523 -0
  235. package/test/deployment.test.ts +499 -0
  236. package/test/dns.test.ts +270 -0
  237. package/test/email.test.ts +439 -0
  238. package/test/filesystem.test.ts +382 -0
  239. package/test/integration.test.ts +350 -0
  240. package/test/messaging.test.ts +514 -0
  241. package/test/monitoring.test.ts +634 -0
  242. package/test/network.test.ts +425 -0
  243. package/test/permissions.test.ts +488 -0
  244. package/test/queue.test.ts +484 -0
  245. package/test/registry.test.ts +306 -0
  246. package/test/security.test.ts +462 -0
  247. package/test/storage.test.ts +463 -0
  248. package/test/template-validator.test.ts +559 -0
  249. package/test/workflow.test.ts +592 -0
  250. package/tsconfig.json +16 -0
  251. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,402 @@
1
+ /**
2
+ * SQS Dead Letter Queue Monitoring
3
+ * DLQ monitoring, alerts, and automated reprocessing
4
+ */
5
+
6
+ export interface DLQMonitor {
7
+ id: string
8
+ name: string
9
+ queueUrl: string
10
+ sourceQueues: string[]
11
+ maxReceiveCount: number
12
+ alarmThreshold: number
13
+ autoReprocess: boolean
14
+ reprocessStrategy: 'immediate' | 'scheduled' | 'manual'
15
+ notificationTopicArn?: string
16
+ }
17
+
18
+ export interface DLQMetrics {
19
+ id: string
20
+ queueUrl: string
21
+ timestamp: Date
22
+ approximateNumberOfMessages: number
23
+ approximateAgeOfOldestMessage: number // seconds
24
+ messagesReceived: number
25
+ messagesDeleted: number
26
+ messagesReprocessed: number
27
+ }
28
+
29
+ export interface DLQAlert {
30
+ id: string
31
+ monitorId: string
32
+ alertType: 'threshold_exceeded' | 'old_message' | 'high_receive_count'
33
+ severity: 'low' | 'medium' | 'high' | 'critical'
34
+ message: string
35
+ timestamp: Date
36
+ acknowledged: boolean
37
+ }
38
+
39
+ export interface ReprocessJob {
40
+ id: string
41
+ queueUrl: string
42
+ messageId: string
43
+ attempts: number
44
+ status: 'pending' | 'processing' | 'success' | 'failed'
45
+ startedAt?: Date
46
+ completedAt?: Date
47
+ error?: string
48
+ }
49
+
50
+ /**
51
+ * DLQ monitoring manager
52
+ */
53
+ export class DLQMonitoringManager {
54
+ private monitors: Map<string, DLQMonitor> = new Map()
55
+ private metrics: Map<string, DLQMetrics[]> = new Map()
56
+ private alerts: Map<string, DLQAlert> = new Map()
57
+ private reprocessJobs: Map<string, ReprocessJob> = new Map()
58
+ private monitorCounter = 0
59
+ private metricsCounter = 0
60
+ private alertCounter = 0
61
+ private jobCounter = 0
62
+
63
+ /**
64
+ * Create DLQ monitor
65
+ */
66
+ createDLQMonitor(monitor: Omit<DLQMonitor, 'id'>): DLQMonitor {
67
+ const id = `dlq-monitor-${Date.now()}-${this.monitorCounter++}`
68
+
69
+ const dlqMonitor: DLQMonitor = {
70
+ id,
71
+ ...monitor,
72
+ }
73
+
74
+ this.monitors.set(id, dlqMonitor)
75
+
76
+ return dlqMonitor
77
+ }
78
+
79
+ /**
80
+ * Create automated DLQ monitor
81
+ */
82
+ createAutomatedMonitor(options: {
83
+ name: string
84
+ queueUrl: string
85
+ sourceQueues: string[]
86
+ notificationTopicArn: string
87
+ }): DLQMonitor {
88
+ return this.createDLQMonitor({
89
+ name: options.name,
90
+ queueUrl: options.queueUrl,
91
+ sourceQueues: options.sourceQueues,
92
+ maxReceiveCount: 3,
93
+ alarmThreshold: 10,
94
+ autoReprocess: true,
95
+ reprocessStrategy: 'scheduled',
96
+ notificationTopicArn: options.notificationTopicArn,
97
+ })
98
+ }
99
+
100
+ /**
101
+ * Collect DLQ metrics
102
+ */
103
+ collectMetrics(queueUrl: string): DLQMetrics {
104
+ const id = `metrics-${Date.now()}-${this.metricsCounter++}`
105
+
106
+ // Simulate metrics collection
107
+ const metrics: DLQMetrics = {
108
+ id,
109
+ queueUrl,
110
+ timestamp: new Date(),
111
+ approximateNumberOfMessages: Math.floor(Math.random() * 100),
112
+ approximateAgeOfOldestMessage: Math.floor(Math.random() * 86400), // 0-24 hours
113
+ messagesReceived: Math.floor(Math.random() * 50),
114
+ messagesDeleted: Math.floor(Math.random() * 30),
115
+ messagesReprocessed: Math.floor(Math.random() * 20),
116
+ }
117
+
118
+ const queueMetrics = this.metrics.get(queueUrl) || []
119
+ queueMetrics.push(metrics)
120
+ this.metrics.set(queueUrl, queueMetrics)
121
+
122
+ // Check for alerts
123
+ this.checkForAlerts(queueUrl, metrics)
124
+
125
+ return metrics
126
+ }
127
+
128
+ /**
129
+ * Check for alerts
130
+ */
131
+ private checkForAlerts(queueUrl: string, metrics: DLQMetrics): void {
132
+ const monitor = Array.from(this.monitors.values()).find(m => m.queueUrl === queueUrl)
133
+
134
+ if (!monitor) {
135
+ return
136
+ }
137
+
138
+ // Check message threshold
139
+ if (metrics.approximateNumberOfMessages >= monitor.alarmThreshold) {
140
+ this.createAlert({
141
+ monitorId: monitor.id,
142
+ alertType: 'threshold_exceeded',
143
+ severity: 'high',
144
+ message: `DLQ ${monitor.name} has ${metrics.approximateNumberOfMessages} messages (threshold: ${monitor.alarmThreshold})`,
145
+ })
146
+ }
147
+
148
+ // Check message age
149
+ const maxAge = 3600 // 1 hour
150
+ if (metrics.approximateAgeOfOldestMessage > maxAge) {
151
+ this.createAlert({
152
+ monitorId: monitor.id,
153
+ alertType: 'old_message',
154
+ severity: 'medium',
155
+ message: `DLQ ${monitor.name} has messages older than ${maxAge} seconds`,
156
+ })
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Create alert
162
+ */
163
+ private createAlert(alert: Omit<DLQAlert, 'id' | 'timestamp' | 'acknowledged'>): DLQAlert {
164
+ const id = `alert-${Date.now()}-${this.alertCounter++}`
165
+
166
+ const dlqAlert: DLQAlert = {
167
+ id,
168
+ timestamp: new Date(),
169
+ acknowledged: false,
170
+ ...alert,
171
+ }
172
+
173
+ this.alerts.set(id, dlqAlert)
174
+
175
+ return dlqAlert
176
+ }
177
+
178
+ /**
179
+ * Acknowledge alert
180
+ */
181
+ acknowledgeAlert(alertId: string): DLQAlert {
182
+ const alert = this.alerts.get(alertId)
183
+
184
+ if (!alert) {
185
+ throw new Error(`Alert not found: ${alertId}`)
186
+ }
187
+
188
+ alert.acknowledged = true
189
+
190
+ return alert
191
+ }
192
+
193
+ /**
194
+ * Create reprocess job
195
+ */
196
+ createReprocessJob(options: {
197
+ queueUrl: string
198
+ messageId: string
199
+ }): ReprocessJob {
200
+ const id = `reprocess-${Date.now()}-${this.jobCounter++}`
201
+
202
+ const job: ReprocessJob = {
203
+ id,
204
+ queueUrl: options.queueUrl,
205
+ messageId: options.messageId,
206
+ attempts: 0,
207
+ status: 'pending',
208
+ }
209
+
210
+ this.reprocessJobs.set(id, job)
211
+
212
+ return job
213
+ }
214
+
215
+ /**
216
+ * Execute reprocess job
217
+ */
218
+ async executeReprocessJob(jobId: string): Promise<ReprocessJob> {
219
+ const job = this.reprocessJobs.get(jobId)
220
+
221
+ if (!job) {
222
+ throw new Error(`Reprocess job not found: ${jobId}`)
223
+ }
224
+
225
+ job.status = 'processing'
226
+ job.startedAt = new Date()
227
+ job.attempts++
228
+
229
+ // Simulate reprocessing
230
+ await new Promise(resolve => setTimeout(resolve, 100))
231
+
232
+ // Random success/failure
233
+ const success = Math.random() > 0.3
234
+
235
+ job.status = success ? 'success' : 'failed'
236
+ job.completedAt = new Date()
237
+
238
+ if (!success) {
239
+ job.error = 'Reprocessing failed - original error still present'
240
+ }
241
+
242
+ return job
243
+ }
244
+
245
+ /**
246
+ * Batch reprocess DLQ messages
247
+ */
248
+ async batchReprocess(options: {
249
+ queueUrl: string
250
+ maxMessages: number
251
+ }): Promise<ReprocessJob[]> {
252
+ const jobs: ReprocessJob[] = []
253
+
254
+ for (let i = 0; i < options.maxMessages; i++) {
255
+ const job = this.createReprocessJob({
256
+ queueUrl: options.queueUrl,
257
+ messageId: `msg-${i}`,
258
+ })
259
+
260
+ await this.executeReprocessJob(job.id)
261
+ jobs.push(job)
262
+ }
263
+
264
+ return jobs
265
+ }
266
+
267
+ /**
268
+ * Get DLQ statistics
269
+ */
270
+ getDLQStatistics(queueUrl: string, hours: number = 24): {
271
+ totalMessages: number
272
+ avgAge: number
273
+ messagesReceived: number
274
+ messagesDeleted: number
275
+ messagesReprocessed: number
276
+ successRate: number
277
+ } {
278
+ const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000)
279
+ const metricsHistory = (this.metrics.get(queueUrl) || [])
280
+ .filter(m => m.timestamp >= cutoff)
281
+
282
+ if (metricsHistory.length === 0) {
283
+ return {
284
+ totalMessages: 0,
285
+ avgAge: 0,
286
+ messagesReceived: 0,
287
+ messagesDeleted: 0,
288
+ messagesReprocessed: 0,
289
+ successRate: 0,
290
+ }
291
+ }
292
+
293
+ const latest = metricsHistory[metricsHistory.length - 1]
294
+ const totalReceived = metricsHistory.reduce((sum, m) => sum + m.messagesReceived, 0)
295
+ const totalDeleted = metricsHistory.reduce((sum, m) => sum + m.messagesDeleted, 0)
296
+ const totalReprocessed = metricsHistory.reduce((sum, m) => sum + m.messagesReprocessed, 0)
297
+ const avgAge = metricsHistory.reduce((sum, m) => sum + m.approximateAgeOfOldestMessage, 0) / metricsHistory.length
298
+
299
+ const successRate = totalReprocessed > 0 ? (totalDeleted / totalReprocessed) * 100 : 0
300
+
301
+ return {
302
+ totalMessages: latest.approximateNumberOfMessages,
303
+ avgAge,
304
+ messagesReceived: totalReceived,
305
+ messagesDeleted: totalDeleted,
306
+ messagesReprocessed: totalReprocessed,
307
+ successRate,
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Get monitor
313
+ */
314
+ getMonitor(id: string): DLQMonitor | undefined {
315
+ return this.monitors.get(id)
316
+ }
317
+
318
+ /**
319
+ * List monitors
320
+ */
321
+ listMonitors(): DLQMonitor[] {
322
+ return Array.from(this.monitors.values())
323
+ }
324
+
325
+ /**
326
+ * Get alerts
327
+ */
328
+ getAlerts(monitorId?: string, acknowledged?: boolean): DLQAlert[] {
329
+ let alerts = Array.from(this.alerts.values())
330
+
331
+ if (monitorId) {
332
+ alerts = alerts.filter(a => a.monitorId === monitorId)
333
+ }
334
+
335
+ if (acknowledged !== undefined) {
336
+ alerts = alerts.filter(a => a.acknowledged === acknowledged)
337
+ }
338
+
339
+ return alerts.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
340
+ }
341
+
342
+ /**
343
+ * Get reprocess jobs
344
+ */
345
+ getReprocessJobs(queueUrl?: string): ReprocessJob[] {
346
+ let jobs = Array.from(this.reprocessJobs.values())
347
+
348
+ if (queueUrl) {
349
+ jobs = jobs.filter(j => j.queueUrl === queueUrl)
350
+ }
351
+
352
+ return jobs
353
+ }
354
+
355
+ /**
356
+ * Generate CloudFormation for DLQ alarm
357
+ */
358
+ generateDLQAlarmCF(monitor: DLQMonitor): any {
359
+ return {
360
+ Type: 'AWS::CloudWatch::Alarm',
361
+ Properties: {
362
+ AlarmName: `${monitor.name}-messages-alarm`,
363
+ AlarmDescription: `Alert when DLQ ${monitor.name} exceeds threshold`,
364
+ MetricName: 'ApproximateNumberOfMessagesVisible',
365
+ Namespace: 'AWS/SQS',
366
+ Statistic: 'Average',
367
+ Period: 300,
368
+ EvaluationPeriods: 1,
369
+ Threshold: monitor.alarmThreshold,
370
+ ComparisonOperator: 'GreaterThanThreshold',
371
+ Dimensions: [
372
+ {
373
+ Name: 'QueueName',
374
+ Value: monitor.queueUrl.split('/').pop(),
375
+ },
376
+ ],
377
+ ...(monitor.notificationTopicArn && {
378
+ AlarmActions: [monitor.notificationTopicArn],
379
+ }),
380
+ },
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Clear all data
386
+ */
387
+ clear(): void {
388
+ this.monitors.clear()
389
+ this.metrics.clear()
390
+ this.alerts.clear()
391
+ this.reprocessJobs.clear()
392
+ this.monitorCounter = 0
393
+ this.metricsCounter = 0
394
+ this.alertCounter = 0
395
+ this.jobCounter = 0
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Global DLQ monitoring manager instance
401
+ */
402
+ export const dlqMonitoringManager: DLQMonitoringManager = new DLQMonitoringManager()