@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,496 @@
1
+ /**
2
+ * Route53 Resolver
3
+ * DNS firewall, resolver rules, and endpoints
4
+ */
5
+
6
+ export interface ResolverEndpoint {
7
+ id: string
8
+ name: string
9
+ direction: 'INBOUND' | 'OUTBOUND'
10
+ ipAddresses: ResolverIP[]
11
+ securityGroupIds: string[]
12
+ status: 'CREATING' | 'OPERATIONAL' | 'UPDATING' | 'DELETING' | 'ACTION_NEEDED'
13
+ }
14
+
15
+ export interface ResolverIP {
16
+ subnetId: string
17
+ ip?: string
18
+ ipv6?: string
19
+ }
20
+
21
+ export interface ResolverRule {
22
+ id: string
23
+ name: string
24
+ ruleType: 'FORWARD' | 'SYSTEM' | 'RECURSIVE'
25
+ domainName: string
26
+ targetIps?: TargetIP[]
27
+ resolverEndpointId?: string
28
+ status: 'COMPLETE' | 'CREATING' | 'UPDATING' | 'DELETING' | 'FAILED'
29
+ }
30
+
31
+ export interface TargetIP {
32
+ ip: string
33
+ port?: number
34
+ }
35
+
36
+ export interface DNSFirewall {
37
+ id: string
38
+ name: string
39
+ firewallRuleGroupAssociations: FirewallRuleGroupAssociation[]
40
+ }
41
+
42
+ export interface FirewallRuleGroupAssociation {
43
+ id: string
44
+ vpcId: string
45
+ firewallRuleGroupId: string
46
+ priority: number
47
+ mutationProtection: 'ENABLED' | 'DISABLED'
48
+ status: 'COMPLETE' | 'CREATING' | 'UPDATING' | 'DELETING'
49
+ }
50
+
51
+ export interface FirewallRuleGroup {
52
+ id: string
53
+ name: string
54
+ rules: FirewallRule[]
55
+ shareStatus: 'NOT_SHARED' | 'SHARED_WITH_ME' | 'SHARED_BY_ME'
56
+ }
57
+
58
+ export interface FirewallRule {
59
+ id: string
60
+ name: string
61
+ priority: number
62
+ action: 'ALLOW' | 'BLOCK' | 'ALERT'
63
+ blockResponse?: 'NODATA' | 'NXDOMAIN' | 'OVERRIDE'
64
+ blockOverrideDomain?: string
65
+ blockOverrideTTL?: number
66
+ firewallDomainListId: string
67
+ }
68
+
69
+ export interface FirewallDomainList {
70
+ id: string
71
+ name: string
72
+ domains: string[]
73
+ status: 'COMPLETE' | 'CREATING' | 'UPDATING' | 'DELETING'
74
+ }
75
+
76
+ /**
77
+ * Route53 Resolver manager
78
+ */
79
+ export class Route53ResolverManager {
80
+ private endpoints: Map<string, ResolverEndpoint> = new Map()
81
+ private rules: Map<string, ResolverRule> = new Map()
82
+ private firewalls: Map<string, DNSFirewall> = new Map()
83
+ private ruleGroups: Map<string, FirewallRuleGroup> = new Map()
84
+ private domainLists: Map<string, FirewallDomainList> = new Map()
85
+ private endpointCounter = 0
86
+ private ruleCounter = 0
87
+ private firewallCounter = 0
88
+ private ruleGroupCounter = 0
89
+ private domainListCounter = 0
90
+
91
+ /**
92
+ * Create resolver endpoint
93
+ */
94
+ createResolverEndpoint(endpoint: Omit<ResolverEndpoint, 'id' | 'status'>): ResolverEndpoint {
95
+ const id = `endpoint-${Date.now()}-${this.endpointCounter++}`
96
+
97
+ const resolverEndpoint: ResolverEndpoint = {
98
+ id,
99
+ status: 'CREATING',
100
+ ...endpoint,
101
+ }
102
+
103
+ this.endpoints.set(id, resolverEndpoint)
104
+
105
+ // Simulate endpoint creation
106
+ setTimeout(() => {
107
+ resolverEndpoint.status = 'OPERATIONAL'
108
+
109
+ // Assign IPs to addresses without explicit IPs
110
+ resolverEndpoint.ipAddresses.forEach(addr => {
111
+ if (!addr.ip) {
112
+ addr.ip = `10.0.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`
113
+ }
114
+ })
115
+ }, 100)
116
+
117
+ return resolverEndpoint
118
+ }
119
+
120
+ /**
121
+ * Create inbound endpoint
122
+ */
123
+ createInboundEndpoint(options: {
124
+ name: string
125
+ subnetIds: string[]
126
+ securityGroupIds: string[]
127
+ }): ResolverEndpoint {
128
+ return this.createResolverEndpoint({
129
+ name: options.name,
130
+ direction: 'INBOUND',
131
+ ipAddresses: options.subnetIds.map(subnetId => ({ subnetId })),
132
+ securityGroupIds: options.securityGroupIds,
133
+ })
134
+ }
135
+
136
+ /**
137
+ * Create outbound endpoint
138
+ */
139
+ createOutboundEndpoint(options: {
140
+ name: string
141
+ subnetIds: string[]
142
+ securityGroupIds: string[]
143
+ }): ResolverEndpoint {
144
+ return this.createResolverEndpoint({
145
+ name: options.name,
146
+ direction: 'OUTBOUND',
147
+ ipAddresses: options.subnetIds.map(subnetId => ({ subnetId })),
148
+ securityGroupIds: options.securityGroupIds,
149
+ })
150
+ }
151
+
152
+ /**
153
+ * Create resolver rule
154
+ */
155
+ createResolverRule(rule: Omit<ResolverRule, 'id' | 'status'>): ResolverRule {
156
+ const id = `rule-${Date.now()}-${this.ruleCounter++}`
157
+
158
+ const resolverRule: ResolverRule = {
159
+ id,
160
+ status: 'CREATING',
161
+ ...rule,
162
+ }
163
+
164
+ this.rules.set(id, resolverRule)
165
+
166
+ setTimeout(() => {
167
+ resolverRule.status = 'COMPLETE'
168
+ }, 100)
169
+
170
+ return resolverRule
171
+ }
172
+
173
+ /**
174
+ * Create forward rule
175
+ */
176
+ createForwardRule(options: {
177
+ name: string
178
+ domainName: string
179
+ targetIps: TargetIP[]
180
+ resolverEndpointId: string
181
+ }): ResolverRule {
182
+ return this.createResolverRule({
183
+ name: options.name,
184
+ ruleType: 'FORWARD',
185
+ domainName: options.domainName,
186
+ targetIps: options.targetIps,
187
+ resolverEndpointId: options.resolverEndpointId,
188
+ })
189
+ }
190
+
191
+ /**
192
+ * Create system rule
193
+ */
194
+ createSystemRule(options: {
195
+ name: string
196
+ domainName: string
197
+ }): ResolverRule {
198
+ return this.createResolverRule({
199
+ name: options.name,
200
+ ruleType: 'SYSTEM',
201
+ domainName: options.domainName,
202
+ })
203
+ }
204
+
205
+ /**
206
+ * Create firewall domain list
207
+ */
208
+ createFirewallDomainList(options: {
209
+ name: string
210
+ domains: string[]
211
+ }): FirewallDomainList {
212
+ const id = `domain-list-${Date.now()}-${this.domainListCounter++}`
213
+
214
+ const domainList: FirewallDomainList = {
215
+ id,
216
+ status: 'CREATING',
217
+ ...options,
218
+ }
219
+
220
+ this.domainLists.set(id, domainList)
221
+
222
+ setTimeout(() => {
223
+ domainList.status = 'COMPLETE'
224
+ }, 100)
225
+
226
+ return domainList
227
+ }
228
+
229
+ /**
230
+ * Create firewall rule group
231
+ */
232
+ createFirewallRuleGroup(options: {
233
+ name: string
234
+ rules: Omit<FirewallRule, 'id'>[]
235
+ }): FirewallRuleGroup {
236
+ const id = `rule-group-${Date.now()}-${this.ruleGroupCounter++}`
237
+
238
+ const ruleGroup: FirewallRuleGroup = {
239
+ id,
240
+ name: options.name,
241
+ rules: options.rules.map((rule, index) => ({
242
+ id: `rule-${id}-${index}`,
243
+ ...rule,
244
+ })),
245
+ shareStatus: 'NOT_SHARED',
246
+ }
247
+
248
+ this.ruleGroups.set(id, ruleGroup)
249
+
250
+ return ruleGroup
251
+ }
252
+
253
+ /**
254
+ * Create block rule
255
+ */
256
+ createBlockRule(options: {
257
+ name: string
258
+ priority: number
259
+ domainListId: string
260
+ blockResponse?: 'NODATA' | 'NXDOMAIN' | 'OVERRIDE'
261
+ blockOverrideDomain?: string
262
+ }): FirewallRuleGroup {
263
+ return this.createFirewallRuleGroup({
264
+ name: options.name,
265
+ rules: [
266
+ {
267
+ name: options.name,
268
+ priority: options.priority,
269
+ action: 'BLOCK',
270
+ blockResponse: options.blockResponse || 'NODATA',
271
+ blockOverrideDomain: options.blockOverrideDomain,
272
+ firewallDomainListId: options.domainListId,
273
+ },
274
+ ],
275
+ })
276
+ }
277
+
278
+ /**
279
+ * Create allow rule
280
+ */
281
+ createAllowRule(options: {
282
+ name: string
283
+ priority: number
284
+ domainListId: string
285
+ }): FirewallRuleGroup {
286
+ return this.createFirewallRuleGroup({
287
+ name: options.name,
288
+ rules: [
289
+ {
290
+ name: options.name,
291
+ priority: options.priority,
292
+ action: 'ALLOW',
293
+ firewallDomainListId: options.domainListId,
294
+ },
295
+ ],
296
+ })
297
+ }
298
+
299
+ /**
300
+ * Create DNS firewall
301
+ */
302
+ createDNSFirewall(options: {
303
+ name: string
304
+ vpcId: string
305
+ ruleGroupAssociations: Array<{
306
+ firewallRuleGroupId: string
307
+ priority: number
308
+ mutationProtection?: 'ENABLED' | 'DISABLED'
309
+ }>
310
+ }): DNSFirewall {
311
+ const id = `firewall-${Date.now()}-${this.firewallCounter++}`
312
+
313
+ const firewall: DNSFirewall = {
314
+ id,
315
+ name: options.name,
316
+ firewallRuleGroupAssociations: options.ruleGroupAssociations.map((assoc, index) => ({
317
+ id: `assoc-${id}-${index}`,
318
+ vpcId: options.vpcId,
319
+ firewallRuleGroupId: assoc.firewallRuleGroupId,
320
+ priority: assoc.priority,
321
+ mutationProtection: assoc.mutationProtection || 'DISABLED',
322
+ status: 'COMPLETE',
323
+ })),
324
+ }
325
+
326
+ this.firewalls.set(id, firewall)
327
+
328
+ return firewall
329
+ }
330
+
331
+ /**
332
+ * Create malware protection firewall
333
+ */
334
+ createMalwareProtectionFirewall(options: {
335
+ name: string
336
+ vpcId: string
337
+ maliciousDomains: string[]
338
+ }): DNSFirewall {
339
+ // Create domain list
340
+ const domainList = this.createFirewallDomainList({
341
+ name: `${options.name}-malware-domains`,
342
+ domains: options.maliciousDomains,
343
+ })
344
+
345
+ // Create rule group
346
+ const ruleGroup = this.createBlockRule({
347
+ name: `${options.name}-block-malware`,
348
+ priority: 100,
349
+ domainListId: domainList.id,
350
+ blockResponse: 'NXDOMAIN',
351
+ })
352
+
353
+ // Create firewall
354
+ return this.createDNSFirewall({
355
+ name: options.name,
356
+ vpcId: options.vpcId,
357
+ ruleGroupAssociations: [
358
+ {
359
+ firewallRuleGroupId: ruleGroup.id,
360
+ priority: 100,
361
+ mutationProtection: 'ENABLED',
362
+ },
363
+ ],
364
+ })
365
+ }
366
+
367
+ /**
368
+ * Get resolver endpoint
369
+ */
370
+ getEndpoint(id: string): ResolverEndpoint | undefined {
371
+ return this.endpoints.get(id)
372
+ }
373
+
374
+ /**
375
+ * List resolver endpoints
376
+ */
377
+ listEndpoints(direction?: 'INBOUND' | 'OUTBOUND'): ResolverEndpoint[] {
378
+ const endpoints = Array.from(this.endpoints.values())
379
+ return direction ? endpoints.filter(e => e.direction === direction) : endpoints
380
+ }
381
+
382
+ /**
383
+ * Get resolver rule
384
+ */
385
+ getRule(id: string): ResolverRule | undefined {
386
+ return this.rules.get(id)
387
+ }
388
+
389
+ /**
390
+ * List resolver rules
391
+ */
392
+ listRules(): ResolverRule[] {
393
+ return Array.from(this.rules.values())
394
+ }
395
+
396
+ /**
397
+ * Get firewall
398
+ */
399
+ getFirewall(id: string): DNSFirewall | undefined {
400
+ return this.firewalls.get(id)
401
+ }
402
+
403
+ /**
404
+ * List firewalls
405
+ */
406
+ listFirewalls(): DNSFirewall[] {
407
+ return Array.from(this.firewalls.values())
408
+ }
409
+
410
+ /**
411
+ * Generate CloudFormation for resolver endpoint
412
+ */
413
+ generateResolverEndpointCF(endpoint: ResolverEndpoint): any {
414
+ return {
415
+ Type: 'AWS::Route53Resolver::ResolverEndpoint',
416
+ Properties: {
417
+ Name: endpoint.name,
418
+ Direction: endpoint.direction,
419
+ IpAddresses: endpoint.ipAddresses.map(addr => ({
420
+ SubnetId: addr.subnetId,
421
+ ...(addr.ip && { Ip: addr.ip }),
422
+ })),
423
+ SecurityGroupIds: endpoint.securityGroupIds,
424
+ },
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Generate CloudFormation for resolver rule
430
+ */
431
+ generateResolverRuleCF(rule: ResolverRule): any {
432
+ return {
433
+ Type: 'AWS::Route53Resolver::ResolverRule',
434
+ Properties: {
435
+ Name: rule.name,
436
+ RuleType: rule.ruleType,
437
+ DomainName: rule.domainName,
438
+ ...(rule.targetIps && {
439
+ TargetIps: rule.targetIps.map(target => ({
440
+ Ip: target.ip,
441
+ Port: target.port || 53,
442
+ })),
443
+ }),
444
+ ...(rule.resolverEndpointId && {
445
+ ResolverEndpointId: rule.resolverEndpointId,
446
+ }),
447
+ },
448
+ }
449
+ }
450
+
451
+ /**
452
+ * Generate CloudFormation for firewall rule group
453
+ */
454
+ generateFirewallRuleGroupCF(ruleGroup: FirewallRuleGroup): any {
455
+ return {
456
+ Type: 'AWS::Route53Resolver::FirewallRuleGroup',
457
+ Properties: {
458
+ Name: ruleGroup.name,
459
+ FirewallRules: ruleGroup.rules.map(rule => ({
460
+ Name: rule.name,
461
+ Priority: rule.priority,
462
+ Action: rule.action,
463
+ FirewallDomainListId: rule.firewallDomainListId,
464
+ ...(rule.blockResponse && { BlockResponse: rule.blockResponse }),
465
+ ...(rule.blockOverrideDomain && {
466
+ BlockOverrideDomain: rule.blockOverrideDomain,
467
+ }),
468
+ ...(rule.blockOverrideTTL && {
469
+ BlockOverrideTtl: rule.blockOverrideTTL,
470
+ }),
471
+ })),
472
+ },
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Clear all data
478
+ */
479
+ clear(): void {
480
+ this.endpoints.clear()
481
+ this.rules.clear()
482
+ this.firewalls.clear()
483
+ this.ruleGroups.clear()
484
+ this.domainLists.clear()
485
+ this.endpointCounter = 0
486
+ this.ruleCounter = 0
487
+ this.firewallCounter = 0
488
+ this.ruleGroupCounter = 0
489
+ this.domainListCounter = 0
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Global Route53 Resolver manager instance
495
+ */
496
+ export const route53ResolverManager: Route53ResolverManager = new Route53ResolverManager()