@stacksjs/ts-cloud 0.16.65 → 0.16.67

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 (195) hide show
  1. package/dist/aws/index.js +1 -1
  2. package/dist/bin/{chunk-v6jm8dsa.js → chunk-0h1ae217.js} +1 -1
  3. package/dist/bin/chunk-19dhvnjh.js +1 -0
  4. package/dist/bin/{chunk-0ejp168p.js → chunk-245rppy4.js} +1 -1
  5. package/dist/bin/{chunk-71b4t3d8.js → chunk-2mdh3syn.js} +2 -2
  6. package/dist/bin/chunk-2r9748kw.js +1 -0
  7. package/dist/bin/{chunk-90ds3vw7.js → chunk-34r2fwwn.js} +1 -1
  8. package/dist/bin/chunk-483ppsv0.js +1 -0
  9. package/dist/bin/{chunk-tpttr74v.js → chunk-5zp3s61y.js} +4 -4
  10. package/dist/bin/{chunk-ya1413jw.js → chunk-6rvejkny.js} +2 -2
  11. package/dist/bin/chunk-6stcmq7g.js +1 -0
  12. package/dist/bin/{chunk-zs0q8sh5.js → chunk-7pxqdq44.js} +1 -1
  13. package/dist/bin/chunk-9fn41ztz.js +1 -0
  14. package/dist/bin/{chunk-aekwpste.js → chunk-9vjg754g.js} +1 -1
  15. package/dist/bin/{chunk-5ad4b744.js → chunk-a68bhc0s.js} +2 -2
  16. package/dist/bin/{chunk-6r04kx46.js → chunk-abk97qeq.js} +2 -2
  17. package/dist/bin/chunk-af8511dv.js +1 -0
  18. package/dist/bin/chunk-asvxjh7p.js +1 -0
  19. package/dist/bin/chunk-bphzq12c.js +1 -0
  20. package/dist/bin/{chunk-zesb85ra.js → chunk-bzjr9jwn.js} +1 -1
  21. package/dist/bin/chunk-c6tt4fj9.js +1 -0
  22. package/dist/bin/chunk-c6yrhzw5.js +1 -0
  23. package/dist/bin/chunk-cf2teb1b.js +1 -0
  24. package/dist/bin/{chunk-v3j9wgmn.js → chunk-dbtm1j98.js} +74 -74
  25. package/dist/bin/chunk-dhb1xs5a.js +1 -0
  26. package/dist/bin/{chunk-nn8k84cd.js → chunk-djqrnrpx.js} +1 -1
  27. package/dist/bin/chunk-dwahpsj4.js +1 -0
  28. package/dist/bin/chunk-er5zfr54.js +1 -0
  29. package/dist/bin/chunk-evbh466n.js +1 -0
  30. package/dist/bin/{chunk-2avtspqd.js → chunk-f4v7nm9a.js} +2 -2
  31. package/dist/bin/{chunk-cf2eyje1.js → chunk-g47h6fg3.js} +6 -6
  32. package/dist/bin/{chunk-38qy0dj2.js → chunk-gvk2af4h.js} +3 -3
  33. package/dist/bin/{chunk-6da5c33e.js → chunk-h2f4f194.js} +2 -2
  34. package/dist/bin/{chunk-tcn6qcc4.js → chunk-jq4xyf7y.js} +1 -1
  35. package/dist/bin/{chunk-kmxkwznm.js → chunk-jwby10he.js} +5 -5
  36. package/dist/bin/{chunk-e51cd46z.js → chunk-jyfm20f3.js} +1 -1
  37. package/dist/bin/{chunk-n667tnf3.js → chunk-k20dxfrh.js} +3 -3
  38. package/dist/bin/{chunk-qpvydcfm.js → chunk-kwfbth5c.js} +5 -5
  39. package/dist/bin/{chunk-75x772gr.js → chunk-mn0rzykt.js} +91 -87
  40. package/dist/bin/chunk-n54ssj0h.js +1 -0
  41. package/dist/bin/{chunk-pe18g092.js → chunk-n80ewf4z.js} +3 -3
  42. package/dist/bin/chunk-nj4eg5vt.js +1 -0
  43. package/dist/bin/{chunk-mver6psb.js → chunk-nxsa7efz.js} +2 -2
  44. package/dist/bin/chunk-p6c2d6em.js +1 -0
  45. package/dist/bin/{chunk-9pj5r0x0.js → chunk-p801tzxz.js} +1 -1
  46. package/dist/bin/{chunk-favx96qj.js → chunk-pxm3w8a3.js} +4 -4
  47. package/dist/bin/chunk-pyxmdv8d.js +1 -0
  48. package/dist/bin/{chunk-v5x06h8w.js → chunk-qascek4k.js} +5 -5
  49. package/dist/bin/{chunk-tw6z2mvh.js → chunk-qjh516ah.js} +13 -13
  50. package/dist/bin/{chunk-eap6bmrq.js → chunk-sb29jzvd.js} +35 -35
  51. package/dist/bin/chunk-shxqbkrz.js +1 -0
  52. package/dist/bin/chunk-sz45s7mw.js +1 -0
  53. package/dist/bin/chunk-va3yvvs0.js +1 -0
  54. package/dist/bin/{chunk-8bgfn8ek.js → chunk-vcs8wtay.js} +2 -2
  55. package/dist/bin/{chunk-sbjzewvk.js → chunk-vf5w5aed.js} +4 -4
  56. package/dist/bin/{chunk-vbq4ten8.js → chunk-vwgpwjwh.js} +3 -3
  57. package/dist/bin/chunk-vy27rc50.js +1 -0
  58. package/dist/bin/{chunk-d38cyam8.js → chunk-xkcvfpd0.js} +4 -4
  59. package/dist/bin/chunk-y815amx5.js +1 -0
  60. package/dist/bin/{chunk-d0q93ecd.js → chunk-yc1n2h5w.js} +5 -5
  61. package/dist/bin/chunk-yec39wzh.js +1 -0
  62. package/dist/bin/{chunk-tg3vzzc4.js → chunk-zs1cpqhv.js} +2 -2
  63. package/dist/bin/cli.js +80 -80
  64. package/dist/bin/dashboard-server.js +1 -1
  65. package/dist/{chunk-rs8v7c67.js → chunk-03eny26f.js} +3 -3
  66. package/dist/{chunk-8jqv6wh7.js → chunk-0860mm00.js} +2 -2
  67. package/dist/chunk-0c48hvb8.js +1 -0
  68. package/dist/{chunk-jt044dg9.js → chunk-0dfyn0bv.js} +103 -99
  69. package/dist/{chunk-tt3pn05f.js → chunk-0kemzwpg.js} +1 -1
  70. package/dist/{chunk-betvtvy7.js → chunk-1t3rjvf9.js} +1 -1
  71. package/dist/{chunk-n0xw26th.js → chunk-3ca6cb1s.js} +1 -1
  72. package/dist/{chunk-r41cawtf.js → chunk-7mpbjr6c.js} +2 -2
  73. package/dist/{chunk-t3ssg8p0.js → chunk-83fy36fn.js} +2 -2
  74. package/dist/chunk-8crqfe8x.js +1 -0
  75. package/dist/chunk-949tycxj.js +1 -0
  76. package/dist/{chunk-et77ydjb.js → chunk-9w5ncn9s.js} +5 -5
  77. package/dist/{chunk-f512g4fq.js → chunk-a92gvctb.js} +5 -5
  78. package/dist/{chunk-bydj8p3h.js → chunk-axcxfz8p.js} +1 -1
  79. package/dist/{chunk-4rxsqf12.js → chunk-bkkwtcnf.js} +29 -29
  80. package/dist/chunk-ecnzvq90.js +1 -0
  81. package/dist/{chunk-mqbsnpsv.js → chunk-eva9hz6q.js} +1 -1
  82. package/dist/{chunk-sqtzajrx.js → chunk-hk1frmnn.js} +1 -1
  83. package/dist/{chunk-7s7w8kzc.js → chunk-m2a60evh.js} +3 -3
  84. package/dist/{chunk-k2bb62em.js → chunk-nkx9pn64.js} +2 -2
  85. package/dist/{chunk-b0s2605f.js → chunk-pah2r8a0.js} +4 -4
  86. package/dist/{chunk-v90w8kbz.js → chunk-pymc2aad.js} +3 -3
  87. package/dist/{chunk-bn3jfrg5.js → chunk-q4408fwg.js} +1 -1
  88. package/dist/{chunk-n3sydv3m.js → chunk-q8vvwmka.js} +1 -1
  89. package/dist/{chunk-2phe49y7.js → chunk-qgtydqpj.js} +12 -12
  90. package/dist/{chunk-8z3jfyk8.js → chunk-qqn369pf.js} +2 -2
  91. package/dist/{chunk-pjdp30dn.js → chunk-r49ynkag.js} +1 -1
  92. package/dist/chunk-s3pe89wj.js +1 -0
  93. package/dist/{chunk-7mw4x3ay.js → chunk-tngsyawj.js} +1 -1
  94. package/dist/chunk-wxjd9gyb.js +1 -0
  95. package/dist/{chunk-gj4hj95p.js → chunk-xd67tr7p.js} +1 -1
  96. package/dist/{chunk-r9ydamw0.js → chunk-y9589qef.js} +70 -70
  97. package/dist/{chunk-e97qhzfe.js → chunk-zgfzc46r.js} +19 -19
  98. package/dist/deploy/index.js +1 -1
  99. package/dist/dns/index.js +1 -1
  100. package/dist/drivers/index.d.ts +1 -1
  101. package/dist/drivers/index.js +1 -1
  102. package/dist/drivers/shared/box-converge.d.ts +10 -2
  103. package/dist/drivers/shared/box-sandbox-converge.test.d.ts +1 -0
  104. package/dist/drivers/shared/releases.d.ts +12 -0
  105. package/dist/index.js +14 -14
  106. package/dist/mail/index.js +1 -1
  107. package/dist/operations/index.js +1 -1
  108. package/dist/protection/index.js +1 -1
  109. package/dist/spend/index.js +1 -1
  110. package/dist/ui/404.html +1 -1
  111. package/dist/ui/accept-invitation.html +1 -1
  112. package/dist/ui/access-denied.html +1 -1
  113. package/dist/ui/account/automation.html +5 -5
  114. package/dist/ui/account/security.html +1 -1
  115. package/dist/ui/applications/compose.html +5 -5
  116. package/dist/ui/applications/new.html +1 -1
  117. package/dist/ui/data/backups.html +5 -5
  118. package/dist/ui/data/services.html +6 -6
  119. package/dist/ui/data/volumes.html +6 -6
  120. package/dist/ui/index.html +6 -6
  121. package/dist/ui/infrastructure/topology.html +5 -5
  122. package/dist/ui/integrations.html +2 -2
  123. package/dist/ui/operations/alerts.html +6 -6
  124. package/dist/ui/operations/configuration.html +5 -5
  125. package/dist/ui/operations/jobs.html +6 -6
  126. package/dist/ui/operations/maintenance.html +5 -5
  127. package/dist/ui/operations/observability.html +6 -6
  128. package/dist/ui/operations/previews.html +6 -6
  129. package/dist/ui/operations/queue.html +5 -5
  130. package/dist/ui/operations/regions.html +5 -5
  131. package/dist/ui/operations/releases.html +6 -6
  132. package/dist/ui/operations/spend.html +6 -6
  133. package/dist/ui/operations/workloads.html +5 -5
  134. package/dist/ui/security.html +2 -2
  135. package/dist/ui/server/actions.html +6 -6
  136. package/dist/ui/server/activity.html +1 -1
  137. package/dist/ui/server/capacity.html +5 -5
  138. package/dist/ui/server/database.html +6 -6
  139. package/dist/ui/server/deployments.html +6 -6
  140. package/dist/ui/server/diagnostics.html +2 -2
  141. package/dist/ui/server/firewall.html +6 -6
  142. package/dist/ui/server/fleet.html +6 -6
  143. package/dist/ui/server/logs.html +6 -6
  144. package/dist/ui/server/metrics.html +6 -6
  145. package/dist/ui/server/security.html +2 -2
  146. package/dist/ui/server/services.html +2 -2
  147. package/dist/ui/server/sites.html +5 -5
  148. package/dist/ui/server/ssh-keys.html +6 -6
  149. package/dist/ui/server/team.html +6 -6
  150. package/dist/ui/server/terminal.html +2 -2
  151. package/dist/ui/serverless/alarms.html +6 -6
  152. package/dist/ui/serverless/assets.html +2 -2
  153. package/dist/ui/serverless/cost.html +2 -2
  154. package/dist/ui/serverless/data.html +6 -6
  155. package/dist/ui/serverless/deployments.html +2 -2
  156. package/dist/ui/serverless/firewall.html +1 -1
  157. package/dist/ui/serverless/functions.html +6 -6
  158. package/dist/ui/serverless/logs.html +6 -6
  159. package/dist/ui/serverless/metrics.html +2 -2
  160. package/dist/ui/serverless/queues.html +5 -5
  161. package/dist/ui/serverless/secrets.html +5 -5
  162. package/dist/ui/serverless/traces.html +6 -6
  163. package/dist/ui/serverless.html +6 -6
  164. package/package.json +3 -3
  165. package/dist/bin/chunk-0v5tsfx5.js +0 -1
  166. package/dist/bin/chunk-3x52axr2.js +0 -1
  167. package/dist/bin/chunk-67mww6gq.js +0 -1
  168. package/dist/bin/chunk-7khzyn7k.js +0 -1
  169. package/dist/bin/chunk-97494wnx.js +0 -1
  170. package/dist/bin/chunk-agmznzms.js +0 -1
  171. package/dist/bin/chunk-ambf5hpg.js +0 -1
  172. package/dist/bin/chunk-b39h9as6.js +0 -1
  173. package/dist/bin/chunk-dfgzav9j.js +0 -1
  174. package/dist/bin/chunk-g0w0jec3.js +0 -1
  175. package/dist/bin/chunk-g514nb80.js +0 -1
  176. package/dist/bin/chunk-hknz7fsr.js +0 -1
  177. package/dist/bin/chunk-k8qrjnyg.js +0 -1
  178. package/dist/bin/chunk-kqstefmv.js +0 -1
  179. package/dist/bin/chunk-mk2h37pm.js +0 -1
  180. package/dist/bin/chunk-mxa9rrw0.js +0 -1
  181. package/dist/bin/chunk-nrtjmzzn.js +0 -1
  182. package/dist/bin/chunk-q3rch5hc.js +0 -1
  183. package/dist/bin/chunk-qqb6h33k.js +0 -1
  184. package/dist/bin/chunk-r1p3k2tn.js +0 -1
  185. package/dist/bin/chunk-t8xq3v3j.js +0 -1
  186. package/dist/bin/chunk-xb48vxmk.js +0 -1
  187. package/dist/bin/chunk-yehb738r.js +0 -1
  188. package/dist/bin/chunk-ythfx8pv.js +0 -1
  189. package/dist/bin/chunk-zynfzzjk.js +0 -1
  190. package/dist/chunk-3b08b1zx.js +0 -1
  191. package/dist/chunk-9sdkhmav.js +0 -1
  192. package/dist/chunk-fc9n4dpq.js +0 -1
  193. package/dist/chunk-kfcct0jz.js +0 -1
  194. package/dist/chunk-v34tdcwv.js +0 -1
  195. package/dist/chunk-xq7xs8bh.js +0 -1
@@ -1,9 +1,9 @@
1
- import{k,ra}from"./chunk-7s7w8kzc.js";import{hn,nt}from"./chunk-t3ssg8p0.js";var Pm={};hn(Pm,{default:()=>Rr,handler:()=>At});var km={};hn(km,{default:()=>Pr,handler:()=>Ct});var bf={};hn(bf,{EmailAnalyticsModule:()=>it,EmailRules:()=>Ut,EmailScheduling:()=>Wt,EmailSearch:()=>Gt,EmailTemplates:()=>ke,EmailThreading:()=>_t,SharedMailboxes:()=>Vt});var Cf={};hn(Cf,{default:()=>ki,handler:()=>xi});var Ef={};hn(Ef,{CallAnalytics:()=>jt,CallRecording:()=>Ht,Callbacks:()=>mt,IVRBuilder:()=>Be});var vf={};hn(vf,{AbTesting:()=>Ee,LinkTracking:()=>Jt,MmsSupport:()=>zt,SmsAnalytics:()=>qt,SmsCampaigns:()=>Kt,SmsChatbot:()=>Qt});var _I={backgroundJobs:{visibilityTimeout:120,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fifo:{fifo:!0,contentBasedDeduplication:!0,visibilityTimeout:30,encrypted:!0},highThroughput:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0},delayed:{delaySeconds:60,visibilityTimeout:60,encrypted:!0},longRunning:{visibilityTimeout:900,messageRetentionPeriod:1209600,deadLetterQueue:!0,maxReceiveCount:2,encrypted:!0},monitored:{visibilityTimeout:60,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0,alarms:{enabled:!0,queueDepthThreshold:1000,messageAgeThreshold:3600,dlqAlarm:!0}},lambdaOptimized:{visibilityTimeout:360,receiveMessageWaitTime:20,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fanOut:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0}},LI={serverless:{development:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:!0},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:1000,handlerMemory:128}},production:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:30,inactivityTimeout:60}},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST",pointInTimeRecovery:!0,connectionTTL:86400}},scaling:{maxConnections:50000,messagesPerSecond:5000,handlerMemory:256,handlerTimeout:30},monitoring:{enabled:!0,connectionThreshold:40000,errorThreshold:100,latencyThreshold:500},keepAlive:!0,keepAliveInterval:30,idleTimeout:600},notifications:{enabled:!0,mode:"serverless",channels:{public:!1,private:!0,presence:!1},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:50000,messagesPerSecond:2000,handlerMemory:128},keepAlive:!0,keepAliveInterval:60,idleTimeout:1800}},server:{development:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"ws",driver:"bun",idleTimeout:120,perMessageDeflate:!1,metrics:!1}},production:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,maxPayloadLength:16777216,backpressureLimit:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"broadcasting:"},rateLimit:{enabled:!0,max:100,window:60000,perChannel:!0,perUser:!0},loadManagement:{enabled:!0,maxConnections:1e4,maxSubscriptionsPerConnection:100,shedLoadThreshold:0.8},metrics:!0,autoScaling:{min:2,max:10,targetCPU:70}},monitoring:{enabled:!0,connectionThreshold:8000,errorThreshold:100}},highPerformance:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:60,maxPayloadLength:8388608,backpressureLimit:2097152,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!0,instances:4,redis:{enabled:!0,useElastiCache:!0,keyPrefix:"rt:"},rateLimit:{enabled:!0,max:200,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:25000,maxSubscriptionsPerConnection:50,shedLoadThreshold:0.7},metrics:{enabled:!0,path:"/metrics"},autoScaling:{min:4,max:20,targetCPU:60,targetConnections:20000}},monitoring:{enabled:!0,connectionThreshold:80000,errorThreshold:50,latencyThreshold:50}},chat:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:200,heartbeatInterval:20,inactivityTimeout:60}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:300,maxPayloadLength:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"chat:"},rateLimit:{enabled:!0,max:60,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:15000,maxSubscriptionsPerConnection:20},metrics:!0},keepAlive:!0,keepAliveInterval:25,idleTimeout:900},gaming:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:10,inactivityTimeout:30}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:30,maxPayloadLength:65536,backpressureLimit:524288,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!1,instances:4,redis:{enabled:!0,useElastiCache:!0},rateLimit:{enabled:!0,max:120,window:60000},loadManagement:{enabled:!0,maxConnections:5000,maxSubscriptionsPerConnection:10,shedLoadThreshold:0.6},metrics:!0,autoScaling:{min:4,max:16,targetCPU:50}},keepAlive:!0,keepAliveInterval:10,idleTimeout:60},single:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,sendPings:!0,perMessageDeflate:!0,instances:1,rateLimit:{enabled:!0,max:100,window:60000},loadManagement:{enabled:!0,maxConnections:1e4},metrics:!0}}}};import{isAbsolute as bt,join as at,relative as sr}from"node:path";var rl=".ts-cloud",Am="TS_CLOUD_STATE_DIR",St=null;function nl(n){St=n?.trim()||null}function il(){return Boolean(process.env[Am]?.trim()||St)}function cn(){return process.env[Am]?.trim()||St||rl}function Q(...n){return at(cn(),...n)}function l(n,...i){let s=cn();return bt(s)?at(s,...i):at(n,s,...i)}function sl(n,i=process.cwd()){let s=(c,u)=>{let d=sr(c,u);return d===""||!d.startsWith("..")&&!bt(d)},o=bt(n)?n:at(i,n);return s(l(i),o)}function ym(n){let i=n.infrastructure?.compute!=null,s=Object.values(n.environments??{}).some((o)=>o?.app!=null);return{server:i,serverless:s}}function K(n){if(n.mode==="server"||n.mode==="serverless")return n.mode;let{serverless:i}=ym(n);return i?"serverless":"server"}function ol(n){let{server:i,serverless:s}=ym(n);if(i&&s)return"A project cannot be both a server and a serverless deployment. Found `infrastructure.compute` (server) AND `environments.<env>.app` (serverless Lambda). Keep one: remove `infrastructure.compute` for a serverless app, or remove `environments.<env>.app` for a server.";if(n.mode==="server"&&s&&!i)return"Config sets `mode: 'server'` but declares a serverless app (`environments.<env>.app`). Remove the app or change the mode.";if(n.mode==="serverless"&&i&&!s)return"Config sets `mode: 'serverless'` but declares a server (`infrastructure.compute`). Remove the compute block or change the mode.";return null}function g(n){return n.infrastructure?.appDatabase??n.infrastructure?.compute?.database}function or(n){return typeof n==="object"&&n!==null?n:{}}function ey(n){return n===!0||typeof n==="object"&&n!==null}function cr(n,i){let s=i?n.environments?.[i]:void 0;if(s?.domain)return s.domain;let o=Object.values(n.sites??{}),c=n.sites?.main?.domain??o.find((u)=>u.domain)?.domain;if(c)return c;return`${n.project?.slug??"app"}.local`}function yr(n){let i=n.indexOf(".");return i>0?n.slice(i+1):void 0}function C(n,i={}){let s=n.infrastructure?.compute?.managedServices?.mail,o=or(s),c=i.environmentType??(i.environment?n.environments?.[i.environment]?.type:void 0),u=o.mode??(c==="production"?"server":"catcher"),d=u==="server",p=cr(n,i.environment),y=o.hostname??(d?`mail.${p}`:"localhost"),h=o.ports??{},b=d?{smtp:h.smtp??25,submission:h.submission??587,submissions:h.submissions??465,imap:h.imap??143,imaps:h.imaps??993,webmail:h.webmail??8080,managesieve:h.managesieve}:{smtp:h.smtp??1025,submission:h.submission,submissions:h.submissions,imap:h.imap,imaps:h.imaps,webmail:h.webmail??8025,managesieve:h.managesieve},v=o.tls??{},A=v.enabled??d,T=!!(v.certPath&&v.keyPath),R=(o.accounts??[]).map((me)=>({address:me.address,password:me.password,passwordPolicy:me.passwordPolicy??"initial"})),P=typeof o.dkim==="object"&&o.dkim!==null?o.dkim:{},I=o.dkim===!1?!1:o.dkim===!0||d,M=typeof o.webmail==="object"&&o.webmail!==null?o.webmail:{},L=o.webmail===!1?!1:M.enabled??!0,N=y.includes(".")&&!y.endsWith(".local")&&!/^\d+\.\d+\.\d+\.\d+$/.test(y),O=M.domain===!1?void 0:M.domain??(d&&N?y:void 0),B=M.tls??(O?!1:A),F=[...new Set(M.aliases??[])].filter((me)=>me!==O),U=o.spam??{},j=o.delivery??(d?"direct":"none"),H=o.expose??d,z=yr(y),ae=[...new Set([y,...z?[z]:[],...o.domains??[]])],Te=M.attachments?.maxFileBytes??20971520,oe=M.attachments?.maxTotalBytes??20971520,pe=M.attachments?.maxCount??20,se=M.undoSendSeconds??10;for(let[me,Ie,Le]of[["maxFileBytes",Te,104857600],["maxTotalBytes",oe,104857600],["maxCount",pe,100],["undoSendSeconds",se,30]])if(!Number.isInteger(Ie)||Ie<0||Ie>Le)throw Error(`Mail webmail ${me} must be an integer from 0 to ${Le}`);return{enabled:ey(s),mode:u,version:o.version,hostname:y,domains:ae,ports:b,tls:{enabled:A,acme:A&&!T&&(v.acme??!0),certPath:v.certPath,keyPath:v.keyPath,requireForAuth:v.requireForAuth??(A&&d),acmeEmail:v.acmeEmail??R[0]?.address},dkim:{enabled:I,selector:P.selector??"default",rotate:P.rotate??!1,rotateIntervalDays:P.rotateIntervalDays??90},webmail:{enabled:L,port:M.port??b.webmail,domain:O,aliases:F,tls:B,secureCookies:M.secureCookies??(!!O||B),attachmentMaxFileBytes:Te,attachmentMaxTotalBytes:oe,attachmentMaxCount:pe,undoSendSeconds:se},delivery:j,sesRegion:o.sesRegion??"us-east-1",accounts:R,storagePath:o.storagePath??"/var/lib/mail",maxMessageSize:o.maxMessageSize??26214400,spam:{enabled:U.enabled??d,enforce:U.enforce??!1,junkScore:U.junkScore??5,rejectScore:U.rejectScore??12,dnsbl:U.dnsbl??d,greylist:U.greylist??!1},webhookUrl:o.webhookUrl,expose:H,bindAddress:H?"0.0.0.0":"127.0.0.1"}}function Xe(n){if(!n.enabled||!n.expose)return[];let i=[n.ports.smtp,n.ports.submission,n.ports.submissions,n.ports.imap,n.ports.imaps,n.ports.managesieve].filter((s)=>typeof s==="number");if(n.webmail.enabled&&!n.webmail.domain)i.push(n.webmail.port);return[...new Set(i)].sort((s,o)=>s-o)}function Ji(n){if(!n.enabled)return{};let i=n.ports.submission??n.ports.smtp,s={MAIL_MAILER:"smtp",MAIL_HOST:"127.0.0.1",MAIL_PORT:String(i)};if(n.mode==="server"){s.MAIL_ENCRYPTION=n.tls.enabled?"tls":"null";let o=n.accounts[0];if(o)s.MAIL_USERNAME=o.address,s.MAIL_PASSWORD=o.password}else s.MAIL_ENCRYPTION="null",s.MAIL_USERNAME="null",s.MAIL_PASSWORD="null";return s}function dn(n){if(!n.enabled||!n.webmail.enabled||!n.webmail.domain)return{};let i=[n.webmail.domain,...n.webmail.aliases];if(!Number.isInteger(n.webmail.port)||n.webmail.port<1||n.webmail.port>65535)throw Error("Mail webmail port must be between 1 and 65535");return Object.fromEntries(i.map((s,o)=>{if(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(s))throw Error(`Invalid mail webmail hostname: ${s}`);return[`__mail_webmail_${o}`,{domain:s,proxyTo:`localhost:${n.webmail.port}`}]}))}function w(n,i={}){let s=n.infrastructure?.compute?.proxy,o=C(n,i);if(!o.enabled||!o.webmail.enabled||!o.webmail.domain)return s;return{engine:"rpx",onDemandTls:!0,onDemandTlsEmail:o.tls.acmeEmail??`webmaster@${o.webmail.domain}`,...s}}function be(n){if(n.cloud?.provider)return n.cloud.provider;if(n.ssh?.hosts?.length)return"ssh";if(n.hetzner?.apiToken)return"hetzner";return"aws"}class al{template;constructor(n){this.template={AWSTemplateFormatVersion:"2010-09-09",Description:n,Resources:{}}}addResource(n,i){return this.template.Resources[n]=i,this}addResources(n){return Object.assign(this.template.Resources,n),this}addParameter(n,i){if(!this.template.Parameters)this.template.Parameters={};return this.template.Parameters[n]=i,this}addOutput(n,i){if(!this.template.Outputs)this.template.Outputs={};return this.template.Outputs[n]=i,this}addMetadata(n,i){if(!this.template.Metadata)this.template.Metadata={};return this.template.Metadata[n]=i,this}hasResource(n){return n in this.template.Resources}getResources(){return this.template.Resources}build(){return this.template}toJSON(n=!0){return JSON.stringify(this.template,null,n?2:0)}toYAML(){return this.convertToYAML(this.template)}convertToYAML(n,i=0){let s=" ".repeat(i),o="";for(let[c,u]of Object.entries(n)){if(u===null||u===void 0)continue;if(typeof u==="object"&&!Array.isArray(u))o+=`${s}${c}:
1
+ import{k,ra}from"./chunk-m2a60evh.js";import{hn,nt}from"./chunk-83fy36fn.js";var km={};hn(km,{default:()=>Rr,handler:()=>At});var Nm={};hn(Nm,{default:()=>Pr,handler:()=>Ct});var Cf={};hn(Cf,{EmailAnalyticsModule:()=>it,EmailRules:()=>Ut,EmailScheduling:()=>Wt,EmailSearch:()=>Gt,EmailTemplates:()=>ke,EmailThreading:()=>_t,SharedMailboxes:()=>Vt});var Ef={};hn(Ef,{default:()=>ki,handler:()=>xi});var vf={};hn(vf,{CallAnalytics:()=>jt,CallRecording:()=>Ht,Callbacks:()=>mt,IVRBuilder:()=>Be});var Tf={};hn(Tf,{AbTesting:()=>Ee,LinkTracking:()=>Jt,MmsSupport:()=>zt,SmsAnalytics:()=>qt,SmsCampaigns:()=>Kt,SmsChatbot:()=>Qt});var LI={backgroundJobs:{visibilityTimeout:120,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fifo:{fifo:!0,contentBasedDeduplication:!0,visibilityTimeout:30,encrypted:!0},highThroughput:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0},delayed:{delaySeconds:60,visibilityTimeout:60,encrypted:!0},longRunning:{visibilityTimeout:900,messageRetentionPeriod:1209600,deadLetterQueue:!0,maxReceiveCount:2,encrypted:!0},monitored:{visibilityTimeout:60,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0,alarms:{enabled:!0,queueDepthThreshold:1000,messageAgeThreshold:3600,dlqAlarm:!0}},lambdaOptimized:{visibilityTimeout:360,receiveMessageWaitTime:20,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fanOut:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0}},$I={serverless:{development:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:!0},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:1000,handlerMemory:128}},production:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:30,inactivityTimeout:60}},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST",pointInTimeRecovery:!0,connectionTTL:86400}},scaling:{maxConnections:50000,messagesPerSecond:5000,handlerMemory:256,handlerTimeout:30},monitoring:{enabled:!0,connectionThreshold:40000,errorThreshold:100,latencyThreshold:500},keepAlive:!0,keepAliveInterval:30,idleTimeout:600},notifications:{enabled:!0,mode:"serverless",channels:{public:!1,private:!0,presence:!1},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:50000,messagesPerSecond:2000,handlerMemory:128},keepAlive:!0,keepAliveInterval:60,idleTimeout:1800}},server:{development:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"ws",driver:"bun",idleTimeout:120,perMessageDeflate:!1,metrics:!1}},production:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,maxPayloadLength:16777216,backpressureLimit:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"broadcasting:"},rateLimit:{enabled:!0,max:100,window:60000,perChannel:!0,perUser:!0},loadManagement:{enabled:!0,maxConnections:1e4,maxSubscriptionsPerConnection:100,shedLoadThreshold:0.8},metrics:!0,autoScaling:{min:2,max:10,targetCPU:70}},monitoring:{enabled:!0,connectionThreshold:8000,errorThreshold:100}},highPerformance:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:60,maxPayloadLength:8388608,backpressureLimit:2097152,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!0,instances:4,redis:{enabled:!0,useElastiCache:!0,keyPrefix:"rt:"},rateLimit:{enabled:!0,max:200,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:25000,maxSubscriptionsPerConnection:50,shedLoadThreshold:0.7},metrics:{enabled:!0,path:"/metrics"},autoScaling:{min:4,max:20,targetCPU:60,targetConnections:20000}},monitoring:{enabled:!0,connectionThreshold:80000,errorThreshold:50,latencyThreshold:50}},chat:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:200,heartbeatInterval:20,inactivityTimeout:60}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:300,maxPayloadLength:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"chat:"},rateLimit:{enabled:!0,max:60,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:15000,maxSubscriptionsPerConnection:20},metrics:!0},keepAlive:!0,keepAliveInterval:25,idleTimeout:900},gaming:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:10,inactivityTimeout:30}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:30,maxPayloadLength:65536,backpressureLimit:524288,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!1,instances:4,redis:{enabled:!0,useElastiCache:!0},rateLimit:{enabled:!0,max:120,window:60000},loadManagement:{enabled:!0,maxConnections:5000,maxSubscriptionsPerConnection:10,shedLoadThreshold:0.6},metrics:!0,autoScaling:{min:4,max:16,targetCPU:50}},keepAlive:!0,keepAliveInterval:10,idleTimeout:60},single:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,sendPings:!0,perMessageDeflate:!0,instances:1,rateLimit:{enabled:!0,max:100,window:60000},loadManagement:{enabled:!0,maxConnections:1e4},metrics:!0}}}};import{isAbsolute as bt,join as at,relative as sr}from"node:path";var rl=".ts-cloud",ym="TS_CLOUD_STATE_DIR",St=null;function nl(n){St=n?.trim()||null}function il(){return Boolean(process.env[ym]?.trim()||St)}function cn(){return process.env[ym]?.trim()||St||rl}function Q(...n){return at(cn(),...n)}function l(n,...i){let s=cn();return bt(s)?at(s,...i):at(n,s,...i)}function sl(n,i=process.cwd()){let s=(c,u)=>{let d=sr(c,u);return d===""||!d.startsWith("..")&&!bt(d)},o=bt(n)?n:at(i,n);return s(l(i),o)}function Sm(n){let i=n.infrastructure?.compute!=null,s=Object.values(n.environments??{}).some((o)=>o?.app!=null);return{server:i,serverless:s}}function K(n){if(n.mode==="server"||n.mode==="serverless")return n.mode;let{serverless:i}=Sm(n);return i?"serverless":"server"}function ol(n){let{server:i,serverless:s}=Sm(n);if(i&&s)return"A project cannot be both a server and a serverless deployment. Found `infrastructure.compute` (server) AND `environments.<env>.app` (serverless Lambda). Keep one: remove `infrastructure.compute` for a serverless app, or remove `environments.<env>.app` for a server.";if(n.mode==="server"&&s&&!i)return"Config sets `mode: 'server'` but declares a serverless app (`environments.<env>.app`). Remove the app or change the mode.";if(n.mode==="serverless"&&i&&!s)return"Config sets `mode: 'serverless'` but declares a server (`infrastructure.compute`). Remove the compute block or change the mode.";return null}function g(n){return n.infrastructure?.appDatabase??n.infrastructure?.compute?.database}function or(n){return typeof n==="object"&&n!==null?n:{}}function ty(n){return n===!0||typeof n==="object"&&n!==null}function cr(n,i){let s=i?n.environments?.[i]:void 0;if(s?.domain)return s.domain;let o=Object.values(n.sites??{}),c=n.sites?.main?.domain??o.find((u)=>u.domain)?.domain;if(c)return c;return`${n.project?.slug??"app"}.local`}function yr(n){let i=n.indexOf(".");return i>0?n.slice(i+1):void 0}function C(n,i={}){let s=n.infrastructure?.compute?.managedServices?.mail,o=or(s),c=i.environmentType??(i.environment?n.environments?.[i.environment]?.type:void 0),u=o.mode??(c==="production"?"server":"catcher"),d=u==="server",p=cr(n,i.environment),y=o.hostname??(d?`mail.${p}`:"localhost"),h=o.ports??{},b=d?{smtp:h.smtp??25,submission:h.submission??587,submissions:h.submissions??465,imap:h.imap??143,imaps:h.imaps??993,webmail:h.webmail??8080,managesieve:h.managesieve}:{smtp:h.smtp??1025,submission:h.submission,submissions:h.submissions,imap:h.imap,imaps:h.imaps,webmail:h.webmail??8025,managesieve:h.managesieve},v=o.tls??{},A=v.enabled??d,T=!!(v.certPath&&v.keyPath),R=(o.accounts??[]).map((me)=>({address:me.address,password:me.password,passwordPolicy:me.passwordPolicy??"initial"})),P=typeof o.dkim==="object"&&o.dkim!==null?o.dkim:{},I=o.dkim===!1?!1:o.dkim===!0||d,M=typeof o.webmail==="object"&&o.webmail!==null?o.webmail:{},L=o.webmail===!1?!1:M.enabled??!0,N=y.includes(".")&&!y.endsWith(".local")&&!/^\d+\.\d+\.\d+\.\d+$/.test(y),O=M.domain===!1?void 0:M.domain??(d&&N?y:void 0),B=M.tls??(O?!1:A),F=[...new Set(M.aliases??[])].filter((me)=>me!==O),U=o.spam??{},j=o.delivery??(d?"direct":"none"),H=o.expose??d,z=yr(y),ae=[...new Set([y,...z?[z]:[],...o.domains??[]])],Te=M.attachments?.maxFileBytes??20971520,oe=M.attachments?.maxTotalBytes??20971520,pe=M.attachments?.maxCount??20,se=M.undoSendSeconds??10;for(let[me,Ie,Le]of[["maxFileBytes",Te,104857600],["maxTotalBytes",oe,104857600],["maxCount",pe,100],["undoSendSeconds",se,30]])if(!Number.isInteger(Ie)||Ie<0||Ie>Le)throw Error(`Mail webmail ${me} must be an integer from 0 to ${Le}`);return{enabled:ty(s),mode:u,version:o.version,hostname:y,domains:ae,ports:b,tls:{enabled:A,acme:A&&!T&&(v.acme??!0),certPath:v.certPath,keyPath:v.keyPath,requireForAuth:v.requireForAuth??(A&&d),acmeEmail:v.acmeEmail??R[0]?.address},dkim:{enabled:I,selector:P.selector??"default",rotate:P.rotate??!1,rotateIntervalDays:P.rotateIntervalDays??90},webmail:{enabled:L,port:M.port??b.webmail,domain:O,aliases:F,tls:B,secureCookies:M.secureCookies??(!!O||B),attachmentMaxFileBytes:Te,attachmentMaxTotalBytes:oe,attachmentMaxCount:pe,undoSendSeconds:se},delivery:j,sesRegion:o.sesRegion??"us-east-1",accounts:R,storagePath:o.storagePath??"/var/lib/mail",maxMessageSize:o.maxMessageSize??26214400,spam:{enabled:U.enabled??d,enforce:U.enforce??!1,junkScore:U.junkScore??5,rejectScore:U.rejectScore??12,dnsbl:U.dnsbl??d,greylist:U.greylist??!1},webhookUrl:o.webhookUrl,expose:H,bindAddress:H?"0.0.0.0":"127.0.0.1"}}function Xe(n){if(!n.enabled||!n.expose)return[];let i=[n.ports.smtp,n.ports.submission,n.ports.submissions,n.ports.imap,n.ports.imaps,n.ports.managesieve].filter((s)=>typeof s==="number");if(n.webmail.enabled&&!n.webmail.domain)i.push(n.webmail.port);return[...new Set(i)].sort((s,o)=>s-o)}function Ji(n){if(!n.enabled)return{};let i=n.ports.submission??n.ports.smtp,s={MAIL_MAILER:"smtp",MAIL_HOST:"127.0.0.1",MAIL_PORT:String(i)};if(n.mode==="server"){s.MAIL_ENCRYPTION=n.tls.enabled?"tls":"null";let o=n.accounts[0];if(o)s.MAIL_USERNAME=o.address,s.MAIL_PASSWORD=o.password}else s.MAIL_ENCRYPTION="null",s.MAIL_USERNAME="null",s.MAIL_PASSWORD="null";return s}function dn(n){if(!n.enabled||!n.webmail.enabled||!n.webmail.domain)return{};let i=[n.webmail.domain,...n.webmail.aliases];if(!Number.isInteger(n.webmail.port)||n.webmail.port<1||n.webmail.port>65535)throw Error("Mail webmail port must be between 1 and 65535");return Object.fromEntries(i.map((s,o)=>{if(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(s))throw Error(`Invalid mail webmail hostname: ${s}`);return[`__mail_webmail_${o}`,{domain:s,proxyTo:`localhost:${n.webmail.port}`}]}))}function w(n,i={}){let s=n.infrastructure?.compute?.proxy,o=C(n,i);if(!o.enabled||!o.webmail.enabled||!o.webmail.domain)return s;return{engine:"rpx",onDemandTls:!0,onDemandTlsEmail:o.tls.acmeEmail??`webmaster@${o.webmail.domain}`,...s}}function be(n){if(n.cloud?.provider)return n.cloud.provider;if(n.ssh?.hosts?.length)return"ssh";if(n.hetzner?.apiToken)return"hetzner";return"aws"}class al{template;constructor(n){this.template={AWSTemplateFormatVersion:"2010-09-09",Description:n,Resources:{}}}addResource(n,i){return this.template.Resources[n]=i,this}addResources(n){return Object.assign(this.template.Resources,n),this}addParameter(n,i){if(!this.template.Parameters)this.template.Parameters={};return this.template.Parameters[n]=i,this}addOutput(n,i){if(!this.template.Outputs)this.template.Outputs={};return this.template.Outputs[n]=i,this}addMetadata(n,i){if(!this.template.Metadata)this.template.Metadata={};return this.template.Metadata[n]=i,this}hasResource(n){return n in this.template.Resources}getResources(){return this.template.Resources}build(){return this.template}toJSON(n=!0){return JSON.stringify(this.template,null,n?2:0)}toYAML(){return this.convertToYAML(this.template)}convertToYAML(n,i=0){let s=" ".repeat(i),o="";for(let[c,u]of Object.entries(n)){if(u===null||u===void 0)continue;if(typeof u==="object"&&!Array.isArray(u))o+=`${s}${c}:
2
2
  ${this.convertToYAML(u,i+1)}`;else if(Array.isArray(u)){o+=`${s}${c}:
3
3
  `;for(let d of u)if(typeof d==="object")o+=`${s} -
4
4
  ${this.convertToYAML(d,i+2)}`;else o+=`${s} - ${d}
5
5
  `}else o+=`${s}${c}: ${u}
6
- `}return o}}var x={Ref:(n)=>({Ref:n}),GetAtt:(n,i)=>({"Fn::GetAtt":[n,i]}),Sub:(n,i)=>{if(i)return{"Fn::Sub":[n,i]};return{"Fn::Sub":n}},Join:(n,i)=>({"Fn::Join":[n,i]}),Select:(n,i)=>({"Fn::Select":[n,i]}),Split:(n,i)=>({"Fn::Split":[n,i]}),GetAZs:(n="")=>({"Fn::GetAZs":n}),ImportValue:(n)=>({"Fn::ImportValue":n}),If:(n,i,s)=>({"Fn::If":[n,i,s]}),Equals:(n,i)=>({"Fn::Equals":[n,i]}),And:(...n)=>({"Fn::And":n}),Or:(...n)=>({"Fn::Or":n}),Not:(n)=>({"Fn::Not":[n]}),Base64:(n)=>({"Fn::Base64":n})},ty={AccountId:{Ref:"AWS::AccountId"},Region:{Ref:"AWS::Region"},StackId:{Ref:"AWS::StackId"},StackName:{Ref:"AWS::StackName"},NotificationARNs:{Ref:"AWS::NotificationARNs"},Partition:{Ref:"AWS::Partition"},URLSuffix:{Ref:"AWS::URLSuffix"},NoValue:{Ref:"AWS::NoValue"}};function r(n){let{slug:i,environment:s,resourceType:o,timestamp:c,suffix:u}=n,d=[i,s,o];if(c)d.push(c);if(u)d.push(u);return d.join("-")}function t(n){return n.split("-").map((i)=>i.charAt(0).toUpperCase()+i.slice(1)).join("")}function $I(){return Date.now().toString()}function MI(n){return n.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-+|-+$/g,"").replace(/-+/g,"-")}function m(n,i){return n.project.stackName??`${n.project.slug}-${i}`}function FI(n,i,s,o){return s.stackName??`${n.project.slug}-${o}-${i}-site`}function UI(n,i){return`${n.project.slug}-${i}`}function QI(n,i,s,o){if(o)return o;if(s==="main")return`${n}-${i}-site`;return`${n}-${i}-${s}`}function HI(n,i,s,o){return o??`${n}-${i}-${s}`}function GI(n,i){return`${n}-${i}-deploy`}function dr(n,i){return`${n.project.slug}-${i}-app`}function cl(n,i){return`${n}-${i}-deployments`}function Xi(n,i){return`${n}-${i}-assets`}class ry{nodes=new Map;addResource(n,i){let s=this.extractDependencies(i);this.nodes.set(n,{logicalId:n,resource:i,dependencies:s})}extractDependencies(n){let i=new Set;if(n.DependsOn)if(Array.isArray(n.DependsOn))n.DependsOn.forEach((s)=>i.add(s));else i.add(n.DependsOn);return this.findReferences(n.Properties||{},i),i}findReferences(n,i){if(!n||typeof n!=="object")return;if("Ref"in n&&typeof n.Ref==="string"){if(!n.Ref.startsWith("AWS::"))i.add(n.Ref)}if("Fn::GetAtt"in n&&Array.isArray(n["Fn::GetAtt"]))i.add(n["Fn::GetAtt"][0]);for(let s of Object.values(n))if(typeof s==="object")this.findReferences(s,i)}topologicalSort(){let n=[],i=new Set,s=new Set,o=(c)=>{if(i.has(c))return;if(s.has(c))throw Error(`Circular dependency detected: ${c}`);s.add(c);let u=this.nodes.get(c);if(u)for(let d of u.dependencies)o(d);s.delete(c),i.add(c),n.push(c)};for(let c of this.nodes.keys())o(c);return n}validate(){for(let[n,i]of this.nodes.entries())for(let s of i.dependencies)if(!this.nodes.has(s))throw Error(`Resource "${n}" depends on "${s}" which does not exist`)}getDependents(n){let i=[];for(let[s,o]of this.nodes.entries())if(o.dependencies.has(n))i.push(s);return i}}function VI(n,i){let s=[],o=[],c=[],u=[],d=[],p=n.Resources||{},y=i.Resources||{},h=new Set([...Object.keys(p),...Object.keys(y)]);for(let v of h){let A=p[v],T=y[v];if(!A&&T)s.push({logicalId:v,action:"add",resourceType:T.Type});else if(A&&!T)o.push({logicalId:v,action:"remove",resourceType:A.Type});else if(A&&T)if(A.Type!==T.Type)u.push({logicalId:v,action:"replace",resourceType:T.Type,reason:`Type changed from ${A.Type} to ${T.Type}`});else{let R=tn(A.Properties||{},T.Properties||{});if(R.length>0)if(br(A.Type,R))u.push({logicalId:v,action:"replace",resourceType:T.Type,changes:R,reason:"Property changes require replacement"});else c.push({logicalId:v,action:"update",resourceType:T.Type,changes:R});else d.push(v)}}let b=Sr([...o,...u,...c]);return{added:s,removed:o,updated:c,replaced:u,unchanged:d,summary:{totalChanges:s.length+o.length+c.length+u.length,requiresReplacement:u.length>0,dangerousChanges:b}}}function tn(n,i,s=""){let o=[],c=new Set([...Object.keys(n),...Object.keys(i)]);for(let u of c){let d=s?`${s}.${u}`:u,p=n[u],y=i[u];if(p===void 0&&y!==void 0)o.push({path:d,oldValue:void 0,newValue:y});else if(p!==void 0&&y===void 0)o.push({path:d,oldValue:p,newValue:void 0});else if(typeof p!==typeof y)o.push({path:d,oldValue:p,newValue:y});else if(typeof p==="object"&&p!==null)if(Array.isArray(p)&&Array.isArray(y)){if(JSON.stringify(p)!==JSON.stringify(y))o.push({path:d,oldValue:p,newValue:y})}else if(!Array.isArray(p)&&!Array.isArray(y)){let h=tn(p,y,d);o.push(...h)}else o.push({path:d,oldValue:p,newValue:y});else if(p!==y)o.push({path:d,oldValue:p,newValue:y})}return o}function br(n,i){let o={"AWS::S3::Bucket":new Set(["BucketName"]),"AWS::DynamoDB::Table":new Set(["TableName","KeySchema"]),"AWS::RDS::DBInstance":new Set(["DBInstanceIdentifier","DBName","Engine"]),"AWS::Lambda::Function":new Set(["FunctionName"]),"AWS::EC2::Instance":new Set(["ImageId","InstanceType","KeyName"]),"AWS::ECS::TaskDefinition":new Set(["Family","ContainerDefinitions"]),"AWS::ElastiCache::CacheCluster":new Set(["CacheNodeType","Engine"]),"AWS::CloudFront::Distribution":new Set([]),"AWS::Route53::HostedZone":new Set(["Name"]),"AWS::IAM::Role":new Set(["RoleName","Path"]),"AWS::KMS::Key":new Set(["KeyPolicy"]),"AWS::Cognito::UserPool":new Set(["UserPoolName"]),"AWS::OpenSearchService::Domain":new Set(["DomainName"])}[n];if(!o)return!1;for(let c of i){let u=c.path.split(".")[0];if(o.has(u))return!0}return!1}function Sr(n){let i=[];for(let s of n){if(s.action==="remove"&&(s.resourceType==="AWS::RDS::DBInstance"||s.resourceType==="AWS::DynamoDB::Table"||s.resourceType==="AWS::ElastiCache::CacheCluster"))i.push(`Removing ${s.resourceType} ${s.logicalId} - data loss risk!`);if(s.action==="replace"&&(s.resourceType==="AWS::RDS::DBInstance"||s.resourceType==="AWS::DynamoDB::Table"))i.push(`Replacing ${s.resourceType} ${s.logicalId} - data loss risk!`);if((s.action==="remove"||s.action==="replace")&&s.resourceType==="AWS::S3::Bucket")i.push(`${s.action==="remove"?"Removing":"Replacing"} S3 bucket ${s.logicalId} - data loss risk!`);if(s.action==="replace"&&s.resourceType==="AWS::EC2::Instance")i.push(`Replacing EC2 instance ${s.logicalId} - downtime expected`);if(s.action==="update"&&s.resourceType==="AWS::EC2::SecurityGroup")i.push(`Updating security group ${s.logicalId} - may affect connectivity`);if((s.action==="update"||s.action==="replace")&&(s.resourceType==="AWS::IAM::Role"||s.resourceType==="AWS::IAM::Policy"))i.push(`Modifying IAM ${s.resourceType.split("::")[2]} ${s.logicalId} - may affect permissions`)}return i}function qI(n){let i=[];if(i.push(`=== Stack Update Analysis ===
6
+ `}return o}}var x={Ref:(n)=>({Ref:n}),GetAtt:(n,i)=>({"Fn::GetAtt":[n,i]}),Sub:(n,i)=>{if(i)return{"Fn::Sub":[n,i]};return{"Fn::Sub":n}},Join:(n,i)=>({"Fn::Join":[n,i]}),Select:(n,i)=>({"Fn::Select":[n,i]}),Split:(n,i)=>({"Fn::Split":[n,i]}),GetAZs:(n="")=>({"Fn::GetAZs":n}),ImportValue:(n)=>({"Fn::ImportValue":n}),If:(n,i,s)=>({"Fn::If":[n,i,s]}),Equals:(n,i)=>({"Fn::Equals":[n,i]}),And:(...n)=>({"Fn::And":n}),Or:(...n)=>({"Fn::Or":n}),Not:(n)=>({"Fn::Not":[n]}),Base64:(n)=>({"Fn::Base64":n})},ry={AccountId:{Ref:"AWS::AccountId"},Region:{Ref:"AWS::Region"},StackId:{Ref:"AWS::StackId"},StackName:{Ref:"AWS::StackName"},NotificationARNs:{Ref:"AWS::NotificationARNs"},Partition:{Ref:"AWS::Partition"},URLSuffix:{Ref:"AWS::URLSuffix"},NoValue:{Ref:"AWS::NoValue"}};function r(n){let{slug:i,environment:s,resourceType:o,timestamp:c,suffix:u}=n,d=[i,s,o];if(c)d.push(c);if(u)d.push(u);return d.join("-")}function t(n){return n.split("-").map((i)=>i.charAt(0).toUpperCase()+i.slice(1)).join("")}function MI(){return Date.now().toString()}function FI(n){return n.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-+|-+$/g,"").replace(/-+/g,"-")}function m(n,i){return n.project.stackName??`${n.project.slug}-${i}`}function UI(n,i,s,o){return s.stackName??`${n.project.slug}-${o}-${i}-site`}function QI(n,i){return`${n.project.slug}-${i}`}function HI(n,i,s,o){if(o)return o;if(s==="main")return`${n}-${i}-site`;return`${n}-${i}-${s}`}function GI(n,i,s,o){return o??`${n}-${i}-${s}`}function VI(n,i){return`${n}-${i}-deploy`}function dr(n,i){return`${n.project.slug}-${i}-app`}function cl(n,i){return`${n}-${i}-deployments`}function Xi(n,i){return`${n}-${i}-assets`}class ny{nodes=new Map;addResource(n,i){let s=this.extractDependencies(i);this.nodes.set(n,{logicalId:n,resource:i,dependencies:s})}extractDependencies(n){let i=new Set;if(n.DependsOn)if(Array.isArray(n.DependsOn))n.DependsOn.forEach((s)=>i.add(s));else i.add(n.DependsOn);return this.findReferences(n.Properties||{},i),i}findReferences(n,i){if(!n||typeof n!=="object")return;if("Ref"in n&&typeof n.Ref==="string"){if(!n.Ref.startsWith("AWS::"))i.add(n.Ref)}if("Fn::GetAtt"in n&&Array.isArray(n["Fn::GetAtt"]))i.add(n["Fn::GetAtt"][0]);for(let s of Object.values(n))if(typeof s==="object")this.findReferences(s,i)}topologicalSort(){let n=[],i=new Set,s=new Set,o=(c)=>{if(i.has(c))return;if(s.has(c))throw Error(`Circular dependency detected: ${c}`);s.add(c);let u=this.nodes.get(c);if(u)for(let d of u.dependencies)o(d);s.delete(c),i.add(c),n.push(c)};for(let c of this.nodes.keys())o(c);return n}validate(){for(let[n,i]of this.nodes.entries())for(let s of i.dependencies)if(!this.nodes.has(s))throw Error(`Resource "${n}" depends on "${s}" which does not exist`)}getDependents(n){let i=[];for(let[s,o]of this.nodes.entries())if(o.dependencies.has(n))i.push(s);return i}}function qI(n,i){let s=[],o=[],c=[],u=[],d=[],p=n.Resources||{},y=i.Resources||{},h=new Set([...Object.keys(p),...Object.keys(y)]);for(let v of h){let A=p[v],T=y[v];if(!A&&T)s.push({logicalId:v,action:"add",resourceType:T.Type});else if(A&&!T)o.push({logicalId:v,action:"remove",resourceType:A.Type});else if(A&&T)if(A.Type!==T.Type)u.push({logicalId:v,action:"replace",resourceType:T.Type,reason:`Type changed from ${A.Type} to ${T.Type}`});else{let R=tn(A.Properties||{},T.Properties||{});if(R.length>0)if(br(A.Type,R))u.push({logicalId:v,action:"replace",resourceType:T.Type,changes:R,reason:"Property changes require replacement"});else c.push({logicalId:v,action:"update",resourceType:T.Type,changes:R});else d.push(v)}}let b=Sr([...o,...u,...c]);return{added:s,removed:o,updated:c,replaced:u,unchanged:d,summary:{totalChanges:s.length+o.length+c.length+u.length,requiresReplacement:u.length>0,dangerousChanges:b}}}function tn(n,i,s=""){let o=[],c=new Set([...Object.keys(n),...Object.keys(i)]);for(let u of c){let d=s?`${s}.${u}`:u,p=n[u],y=i[u];if(p===void 0&&y!==void 0)o.push({path:d,oldValue:void 0,newValue:y});else if(p!==void 0&&y===void 0)o.push({path:d,oldValue:p,newValue:void 0});else if(typeof p!==typeof y)o.push({path:d,oldValue:p,newValue:y});else if(typeof p==="object"&&p!==null)if(Array.isArray(p)&&Array.isArray(y)){if(JSON.stringify(p)!==JSON.stringify(y))o.push({path:d,oldValue:p,newValue:y})}else if(!Array.isArray(p)&&!Array.isArray(y)){let h=tn(p,y,d);o.push(...h)}else o.push({path:d,oldValue:p,newValue:y});else if(p!==y)o.push({path:d,oldValue:p,newValue:y})}return o}function br(n,i){let o={"AWS::S3::Bucket":new Set(["BucketName"]),"AWS::DynamoDB::Table":new Set(["TableName","KeySchema"]),"AWS::RDS::DBInstance":new Set(["DBInstanceIdentifier","DBName","Engine"]),"AWS::Lambda::Function":new Set(["FunctionName"]),"AWS::EC2::Instance":new Set(["ImageId","InstanceType","KeyName"]),"AWS::ECS::TaskDefinition":new Set(["Family","ContainerDefinitions"]),"AWS::ElastiCache::CacheCluster":new Set(["CacheNodeType","Engine"]),"AWS::CloudFront::Distribution":new Set([]),"AWS::Route53::HostedZone":new Set(["Name"]),"AWS::IAM::Role":new Set(["RoleName","Path"]),"AWS::KMS::Key":new Set(["KeyPolicy"]),"AWS::Cognito::UserPool":new Set(["UserPoolName"]),"AWS::OpenSearchService::Domain":new Set(["DomainName"])}[n];if(!o)return!1;for(let c of i){let u=c.path.split(".")[0];if(o.has(u))return!0}return!1}function Sr(n){let i=[];for(let s of n){if(s.action==="remove"&&(s.resourceType==="AWS::RDS::DBInstance"||s.resourceType==="AWS::DynamoDB::Table"||s.resourceType==="AWS::ElastiCache::CacheCluster"))i.push(`Removing ${s.resourceType} ${s.logicalId} - data loss risk!`);if(s.action==="replace"&&(s.resourceType==="AWS::RDS::DBInstance"||s.resourceType==="AWS::DynamoDB::Table"))i.push(`Replacing ${s.resourceType} ${s.logicalId} - data loss risk!`);if((s.action==="remove"||s.action==="replace")&&s.resourceType==="AWS::S3::Bucket")i.push(`${s.action==="remove"?"Removing":"Replacing"} S3 bucket ${s.logicalId} - data loss risk!`);if(s.action==="replace"&&s.resourceType==="AWS::EC2::Instance")i.push(`Replacing EC2 instance ${s.logicalId} - downtime expected`);if(s.action==="update"&&s.resourceType==="AWS::EC2::SecurityGroup")i.push(`Updating security group ${s.logicalId} - may affect connectivity`);if((s.action==="update"||s.action==="replace")&&(s.resourceType==="AWS::IAM::Role"||s.resourceType==="AWS::IAM::Policy"))i.push(`Modifying IAM ${s.resourceType.split("::")[2]} ${s.logicalId} - may affect permissions`)}return i}function jI(n){let i=[];if(i.push(`=== Stack Update Analysis ===
7
7
  `),n.summary.totalChanges===0)return i.push(`No changes detected.
8
8
  `),i.join(`
9
9
  `);if(i.push(`Total changes: ${n.summary.totalChanges}`),i.push(`Requires replacement: ${n.summary.requiresReplacement?"Yes":"No"}
@@ -91,7 +91,7 @@ echo "Image: $IMAGE_URI:${o}"
91
91
  docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
92
92
  docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest`},...n.ecsCluster&&n.ecsService?[{name:"Deploy to ECS",run:`aws ecs update-service --cluster ${n.ecsCluster} --service ${n.ecsService} --force-new-deployment`}]:[]]}}};return`# Generated by ts-cloud
93
93
  ${JSON.stringify(i,null,2).replace(/"/g,"").replace(/,\n/g,`
94
- `)}`}};static DockerfileTemplates={bunServer:(n,i=3000)=>Ye.generateBunDockerfile({serverPath:n,port:i}),bunWithBuild:(n,i,s=3000)=>Ye.generateBunDockerfile({serverPath:n,port:s,buildCommands:[i]}),bunFullStack:(n,i=3000)=>Ye.generateBunDockerfile({serverPath:n,port:i,additionalDirs:["public","views","dist"],buildCommands:["bun run build"]}),bunApi:(n,i=3000)=>Ye.generateBunDockerfile({serverPath:n,port:i,healthCheckEndpoint:"/api/health"})}}var dl=[400,403,404,416,429,500,502,503,504],Sm=[500,502,503,504],Im=["GET","HEAD","OPTIONS"],jI="-failover-group",bm=["default","media-quality-based"],Cm={min:1,max:3},Em={min:1,max:10};function Qo(n){if(n===void 0)return[...Sm];if(n.length===0)throw Error(`CloudFront origin failover: statusCodes must list at least one code (allowed: ${dl.join(", ")}). Omit it to use the default ${Sm.join(", ")}.`);let i=n.filter((s)=>!dl.includes(s));if(i.length>0)throw Error(`CloudFront origin failover: ${i.join(", ")} ${i.length===1?"is not a status code":"are not status codes"} CloudFront can fail over on. Allowed: ${dl.join(", ")}.`);return[...new Set(n)].sort((s,o)=>s-o)}function ll(n){let{primaryOriginId:i,secondaryOriginId:s}=n;if(!i||!s)throw Error("CloudFront origin failover: both a primary and a secondary origin id are required");if(i===s)throw Error(`CloudFront origin failover: the secondary origin must differ from the primary (both are "${i}")`);let o=Qo(n.statusCodes);return nn(n.selectionCriteria),{Id:n.groupId??`${i}-failover-group`,FailoverCriteria:{StatusCodes:{Quantity:o.length,Items:o}},Members:{Quantity:2,Items:[{OriginId:i},{OriginId:s}]},...n.selectionCriteria?{SelectionCriteria:n.selectionCriteria}:{}}}function nn(n,i="the origin group"){if(n===void 0)return;if(!bm.includes(n))throw Error(`CloudFront origin failover: ${i} has selection criteria ${JSON.stringify(n)}. Allowed: ${bm.join(", ")}.`)}function st(n,i,s){if(typeof n!=="number"||!Number.isInteger(n)||n<i.min||n>i.max)throw Error(`CloudFront origin: ${s} must be a whole number from ${i.min} to ${i.max}, got ${JSON.stringify(n)}.`)}function ce(n,i="the origin"){let s={};if(n?.connectionAttempts!==void 0)st(n.connectionAttempts,Cm,`${i} connectionAttempts`),s.ConnectionAttempts=n.connectionAttempts;if(n?.connectionTimeout!==void 0)st(n.connectionTimeout,Em,`${i} connectionTimeout (seconds)`),s.ConnectionTimeout=n.connectionTimeout;return s}function ln(n){return{Quantity:1,Items:[ll(n)]}}function Dt(n,i="the cache behavior"){let o=(Array.isArray(n)?n:n?.Items??[]).filter((c)=>!Im.includes(c.toUpperCase()));if(o.length>0)throw Error(`CloudFront origin failover: ${i} allows ${o.join(", ")}, but a cache behavior that targets an origin group may only allow ${Im.join(", ")}. CloudFront never fails over a write, so point the write paths at a single origin in their own cache behavior.`)}function Ho(n){return/\.s3[.-](?:[a-z0-9-]+\.)?amazonaws\.com(?:\.cn)?$/i.test(n)&&!/s3-website/i.test(n)}function je(n){if(!n)return[];if(Array.isArray(n))return n;return n.Items??[]}function Ae(n){return typeof n==="string"?n:void 0}var Cr=/\.mediapackagev2\.[a-z0-9-]+\.amazonaws\.com$/i;function Pt(n,i="the distribution"){let s=je(n.Origins),o=new Set(s.map((b)=>Ae(b.Id)).filter((b)=>!!b)),c=new Map(s.map((b)=>[Ae(b.Id)??"",b.DomainName])),u=s.some((b)=>Ae(b.Id)===void 0);for(let b of s){let v=Ae(b.Id)??"(unnamed origin)";if(b.ConnectionAttempts!==void 0)st(b.ConnectionAttempts,Cm,`${i} origin "${v}" ConnectionAttempts`);if(b.ConnectionTimeout!==void 0)st(b.ConnectionTimeout,Em,`${i} origin "${v}" ConnectionTimeout (seconds)`)}let d=n.OriginGroups,p=je(d);if(d&&!Array.isArray(d)&&d.Quantity!==void 0&&d.Quantity!==p.length)throw Error(`CloudFront origin failover: ${i} OriginGroups.Quantity is ${d.Quantity} but it lists ${p.length} group(s).`);let y=new Set;for(let b of p){let v=Ae(b.Id);if(b.Id===void 0||b.Id==="")throw Error(`CloudFront origin failover: ${i} has an origin group without an Id.`);let A=`${i} origin group "${v??"(intrinsic id)"}"`;if(v){if(y.has(v))throw Error(`CloudFront origin failover: ${i} declares origin group "${v}" twice.`);if(o.has(v))throw Error(`CloudFront origin failover: ${A} has the same id as an origin. Cache behaviors target groups and origins by id, so the two must differ.`);y.add(v)}let T=b.Members,R=je(T);if(R.length!==2||T?.Quantity!==void 0&&T.Quantity!==R.length)throw Error(`CloudFront origin failover: ${A} must have exactly 2 members (a primary and a secondary), it has ${R.length}${T?.Quantity!==void 0&&T.Quantity!==R.length?` with Quantity ${T.Quantity}`:""}.`);let P=R.map((L)=>Ae(L.OriginId));for(let L of P)if(L&&!o.has(L)&&!u)throw Error(`CloudFront origin failover: ${A} lists member "${L}", which is not an origin of this distribution. Origins: ${[...o].join(", ")||"(none)"}.`);if(P[0]&&P[0]===P[1])throw Error(`CloudFront origin failover: ${A} lists "${P[0]}" as both primary and secondary.`);let I=b.FailoverCriteria?.StatusCodes,M=je(I);if(Qo(M),I?.Quantity!==void 0&&I.Quantity!==M.length)throw Error(`CloudFront origin failover: ${A} FailoverCriteria.StatusCodes.Quantity is ${I.Quantity} but it lists ${M.length} code(s).`);if(nn(b.SelectionCriteria,A),b.SelectionCriteria==="media-quality-based")for(let L of P){let N=L?Ae(c.get(L)):void 0;if(N&&!Cr.test(N))throw Error(`CloudFront origin failover: ${A} uses media-quality-based selection, which only works between AWS Elemental MediaPackage v2 origins, but member "${L}" is ${N}. Use 'default'.`)}}let h=[];if(n.DefaultCacheBehavior)h.push({behavior:n.DefaultCacheBehavior,name:"the default cache behavior"});for(let b of je(n.CacheBehaviors))h.push({behavior:b,name:`the cache behavior for ${JSON.stringify(b.PathPattern)}`});for(let{behavior:b,name:v}of h){let A=Ae(b.TargetOriginId);if(!A)continue;if(y.has(A))Dt(b.AllowedMethods??["GET","HEAD"],`${v} of ${i} (origin group "${A}")`);else if(!o.has(A)&&!u&&p.every((T)=>Ae(T.Id)!==void 0))throw Error(`CloudFront: ${v} of ${i} targets "${A}", which is neither an origin nor an origin group of this distribution.`)}}class Ce{static createDistribution(n){let{slug:i,environment:s,origin:o,customDomain:c,certificateArn:u,errorPages:d,cachePolicy:p,edgeFunctions:y,http3:h=!1,comment:b,failoverOrigin:v}=n,A=r({slug:i,environment:s,resourceType:"cdn"}),T=t(A),R={Id:"DefaultOrigin",DomainName:o.domainName,OriginPath:o.originPath||"",...ce(o,"the CDN origin")},P;if(o.type==="s3"){let M=`${T}OAC`;P={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${A}-oac`,Description:`Origin Access Control for ${A}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},R.OriginAccessControlId=x.Ref(M)}else if(o.type==="alb"||o.type==="custom")R.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};let I={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:b||`CDN for ${A}`,DefaultRootObject:"index.html",Origins:[R],DefaultCacheBehavior:{TargetOriginId:"DefaultOrigin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},PriceClass:"PriceClass_100",HttpVersion:h?"http2and3":"http2"}}};if(c&&u)I.Properties.DistributionConfig.Aliases=[c],I.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:u,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};if(d&&d.length>0)I.Properties.DistributionConfig.CustomErrorResponses=d.map((M)=>({ErrorCode:M.errorCode,ResponseCode:M.responseCode,ResponsePagePath:M.responsePagePath}));if(y&&y.length>0)I.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=y.map((M)=>({EventType:M.event,LambdaFunctionARN:M.functionArn}));if(v)Ce.addOriginFailover(I,v);return{distribution:I,originAccessControl:P,logicalId:T}}static addOriginFailover(n,i){let s=n.Properties.DistributionConfig,o=s.DefaultCacheBehavior,c=o.TargetOriginId,u=i.id??"FailoverOrigin";if(s.OriginGroups&&s.OriginGroups.Quantity>0)throw Error("CloudFront origin failover: this distribution already has an origin group");if(Dt(o.AllowedMethods??["GET","HEAD"],"the default cache behavior"),s.Origins.some((b)=>b.Id===u))throw Error(`CloudFront origin failover: an origin with id "${u}" already exists`);let d=ll({primaryOriginId:c,secondaryOriginId:u,statusCodes:i.statusCodes,selectionCriteria:i.selectionCriteria}),p=i.type??(Ho(i.domainName)?"s3":"custom"),y={Id:u,DomainName:i.domainName,OriginPath:i.originPath||"",...ce(i,"the failover origin")},h=ce(i.primary,"the primary origin");if(Object.keys(h).length>0){let b=s.Origins.find((v)=>v.Id===c);if(b)Object.assign(b,h)}if(p==="s3"){let b=s.Origins.find((v)=>v.Id===c);if(y.S3OriginConfig={OriginAccessIdentity:""},b?.OriginAccessControlId)y.OriginAccessControlId=b.OriginAccessControlId}else y.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};return s.Origins.push(y),s.OriginGroups={Quantity:1,Items:[d]},o.TargetOriginId=d.Id,Pt(s),n}static setCustomDomain(n,i,s){return n.Properties.DistributionConfig.Aliases=[i],n.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:s,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"},n}static setErrorPages(n,i){return n.Properties.DistributionConfig.CustomErrorResponses=i.map((s)=>({ErrorCode:s.errorCode,ResponseCode:s.responseCode,ResponsePagePath:s.responsePagePath})),n}static enableHttp3(n){return n.Properties.DistributionConfig.HttpVersion="http2and3",n}static addEdgeFunction(n,i,s){if(!n.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations)n.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=[];return n.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations.push({EventType:i,LambdaFunctionARN:s}),n}static setCachePolicy(n,i){return n.Properties.DistributionConfig.Comment=`${n.Properties.DistributionConfig.Comment||""} (TTL: ${i.default||86400}s)`,n}static createSpaDistribution(n){return Ce.createDistribution({...n,errorPages:[{errorCode:404,responseCode:200,responsePagePath:"/index.html"},{errorCode:403,responseCode:200,responsePagePath:"/index.html"}]})}static createDocsOriginRequestFunction(n){let{slug:i,environment:s}=n,o=r({slug:i,environment:s,resourceType:"edge-docs"}),c=t(o),u=t(`${o}-role`),d=t(`${o}-version`),p={Type:"AWS::IAM::Role",Properties:{RoleName:`${o}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["lambda.amazonaws.com","edgelambda.amazonaws.com"]},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}},y=`
94
+ `)}`}};static DockerfileTemplates={bunServer:(n,i=3000)=>Ye.generateBunDockerfile({serverPath:n,port:i}),bunWithBuild:(n,i,s=3000)=>Ye.generateBunDockerfile({serverPath:n,port:s,buildCommands:[i]}),bunFullStack:(n,i=3000)=>Ye.generateBunDockerfile({serverPath:n,port:i,additionalDirs:["public","views","dist"],buildCommands:["bun run build"]}),bunApi:(n,i=3000)=>Ye.generateBunDockerfile({serverPath:n,port:i,healthCheckEndpoint:"/api/health"})}}var dl=[400,403,404,416,429,500,502,503,504],Im=[500,502,503,504],bm=["GET","HEAD","OPTIONS"],zI="-failover-group",Cm=["default","media-quality-based"],Em={min:1,max:3},vm={min:1,max:10};function Qo(n){if(n===void 0)return[...Im];if(n.length===0)throw Error(`CloudFront origin failover: statusCodes must list at least one code (allowed: ${dl.join(", ")}). Omit it to use the default ${Im.join(", ")}.`);let i=n.filter((s)=>!dl.includes(s));if(i.length>0)throw Error(`CloudFront origin failover: ${i.join(", ")} ${i.length===1?"is not a status code":"are not status codes"} CloudFront can fail over on. Allowed: ${dl.join(", ")}.`);return[...new Set(n)].sort((s,o)=>s-o)}function ll(n){let{primaryOriginId:i,secondaryOriginId:s}=n;if(!i||!s)throw Error("CloudFront origin failover: both a primary and a secondary origin id are required");if(i===s)throw Error(`CloudFront origin failover: the secondary origin must differ from the primary (both are "${i}")`);let o=Qo(n.statusCodes);return nn(n.selectionCriteria),{Id:n.groupId??`${i}-failover-group`,FailoverCriteria:{StatusCodes:{Quantity:o.length,Items:o}},Members:{Quantity:2,Items:[{OriginId:i},{OriginId:s}]},...n.selectionCriteria?{SelectionCriteria:n.selectionCriteria}:{}}}function nn(n,i="the origin group"){if(n===void 0)return;if(!Cm.includes(n))throw Error(`CloudFront origin failover: ${i} has selection criteria ${JSON.stringify(n)}. Allowed: ${Cm.join(", ")}.`)}function st(n,i,s){if(typeof n!=="number"||!Number.isInteger(n)||n<i.min||n>i.max)throw Error(`CloudFront origin: ${s} must be a whole number from ${i.min} to ${i.max}, got ${JSON.stringify(n)}.`)}function ce(n,i="the origin"){let s={};if(n?.connectionAttempts!==void 0)st(n.connectionAttempts,Em,`${i} connectionAttempts`),s.ConnectionAttempts=n.connectionAttempts;if(n?.connectionTimeout!==void 0)st(n.connectionTimeout,vm,`${i} connectionTimeout (seconds)`),s.ConnectionTimeout=n.connectionTimeout;return s}function ln(n){return{Quantity:1,Items:[ll(n)]}}function Dt(n,i="the cache behavior"){let o=(Array.isArray(n)?n:n?.Items??[]).filter((c)=>!bm.includes(c.toUpperCase()));if(o.length>0)throw Error(`CloudFront origin failover: ${i} allows ${o.join(", ")}, but a cache behavior that targets an origin group may only allow ${bm.join(", ")}. CloudFront never fails over a write, so point the write paths at a single origin in their own cache behavior.`)}function Ho(n){return/\.s3[.-](?:[a-z0-9-]+\.)?amazonaws\.com(?:\.cn)?$/i.test(n)&&!/s3-website/i.test(n)}function je(n){if(!n)return[];if(Array.isArray(n))return n;return n.Items??[]}function Ae(n){return typeof n==="string"?n:void 0}var Cr=/\.mediapackagev2\.[a-z0-9-]+\.amazonaws\.com$/i;function Pt(n,i="the distribution"){let s=je(n.Origins),o=new Set(s.map((b)=>Ae(b.Id)).filter((b)=>!!b)),c=new Map(s.map((b)=>[Ae(b.Id)??"",b.DomainName])),u=s.some((b)=>Ae(b.Id)===void 0);for(let b of s){let v=Ae(b.Id)??"(unnamed origin)";if(b.ConnectionAttempts!==void 0)st(b.ConnectionAttempts,Em,`${i} origin "${v}" ConnectionAttempts`);if(b.ConnectionTimeout!==void 0)st(b.ConnectionTimeout,vm,`${i} origin "${v}" ConnectionTimeout (seconds)`)}let d=n.OriginGroups,p=je(d);if(d&&!Array.isArray(d)&&d.Quantity!==void 0&&d.Quantity!==p.length)throw Error(`CloudFront origin failover: ${i} OriginGroups.Quantity is ${d.Quantity} but it lists ${p.length} group(s).`);let y=new Set;for(let b of p){let v=Ae(b.Id);if(b.Id===void 0||b.Id==="")throw Error(`CloudFront origin failover: ${i} has an origin group without an Id.`);let A=`${i} origin group "${v??"(intrinsic id)"}"`;if(v){if(y.has(v))throw Error(`CloudFront origin failover: ${i} declares origin group "${v}" twice.`);if(o.has(v))throw Error(`CloudFront origin failover: ${A} has the same id as an origin. Cache behaviors target groups and origins by id, so the two must differ.`);y.add(v)}let T=b.Members,R=je(T);if(R.length!==2||T?.Quantity!==void 0&&T.Quantity!==R.length)throw Error(`CloudFront origin failover: ${A} must have exactly 2 members (a primary and a secondary), it has ${R.length}${T?.Quantity!==void 0&&T.Quantity!==R.length?` with Quantity ${T.Quantity}`:""}.`);let P=R.map((L)=>Ae(L.OriginId));for(let L of P)if(L&&!o.has(L)&&!u)throw Error(`CloudFront origin failover: ${A} lists member "${L}", which is not an origin of this distribution. Origins: ${[...o].join(", ")||"(none)"}.`);if(P[0]&&P[0]===P[1])throw Error(`CloudFront origin failover: ${A} lists "${P[0]}" as both primary and secondary.`);let I=b.FailoverCriteria?.StatusCodes,M=je(I);if(Qo(M),I?.Quantity!==void 0&&I.Quantity!==M.length)throw Error(`CloudFront origin failover: ${A} FailoverCriteria.StatusCodes.Quantity is ${I.Quantity} but it lists ${M.length} code(s).`);if(nn(b.SelectionCriteria,A),b.SelectionCriteria==="media-quality-based")for(let L of P){let N=L?Ae(c.get(L)):void 0;if(N&&!Cr.test(N))throw Error(`CloudFront origin failover: ${A} uses media-quality-based selection, which only works between AWS Elemental MediaPackage v2 origins, but member "${L}" is ${N}. Use 'default'.`)}}let h=[];if(n.DefaultCacheBehavior)h.push({behavior:n.DefaultCacheBehavior,name:"the default cache behavior"});for(let b of je(n.CacheBehaviors))h.push({behavior:b,name:`the cache behavior for ${JSON.stringify(b.PathPattern)}`});for(let{behavior:b,name:v}of h){let A=Ae(b.TargetOriginId);if(!A)continue;if(y.has(A))Dt(b.AllowedMethods??["GET","HEAD"],`${v} of ${i} (origin group "${A}")`);else if(!o.has(A)&&!u&&p.every((T)=>Ae(T.Id)!==void 0))throw Error(`CloudFront: ${v} of ${i} targets "${A}", which is neither an origin nor an origin group of this distribution.`)}}class Ce{static createDistribution(n){let{slug:i,environment:s,origin:o,customDomain:c,certificateArn:u,errorPages:d,cachePolicy:p,edgeFunctions:y,http3:h=!1,comment:b,failoverOrigin:v}=n,A=r({slug:i,environment:s,resourceType:"cdn"}),T=t(A),R={Id:"DefaultOrigin",DomainName:o.domainName,OriginPath:o.originPath||"",...ce(o,"the CDN origin")},P;if(o.type==="s3"){let M=`${T}OAC`;P={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${A}-oac`,Description:`Origin Access Control for ${A}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},R.OriginAccessControlId=x.Ref(M)}else if(o.type==="alb"||o.type==="custom")R.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};let I={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:b||`CDN for ${A}`,DefaultRootObject:"index.html",Origins:[R],DefaultCacheBehavior:{TargetOriginId:"DefaultOrigin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},PriceClass:"PriceClass_100",HttpVersion:h?"http2and3":"http2"}}};if(c&&u)I.Properties.DistributionConfig.Aliases=[c],I.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:u,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};if(d&&d.length>0)I.Properties.DistributionConfig.CustomErrorResponses=d.map((M)=>({ErrorCode:M.errorCode,ResponseCode:M.responseCode,ResponsePagePath:M.responsePagePath}));if(y&&y.length>0)I.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=y.map((M)=>({EventType:M.event,LambdaFunctionARN:M.functionArn}));if(v)Ce.addOriginFailover(I,v);return{distribution:I,originAccessControl:P,logicalId:T}}static addOriginFailover(n,i){let s=n.Properties.DistributionConfig,o=s.DefaultCacheBehavior,c=o.TargetOriginId,u=i.id??"FailoverOrigin";if(s.OriginGroups&&s.OriginGroups.Quantity>0)throw Error("CloudFront origin failover: this distribution already has an origin group");if(Dt(o.AllowedMethods??["GET","HEAD"],"the default cache behavior"),s.Origins.some((b)=>b.Id===u))throw Error(`CloudFront origin failover: an origin with id "${u}" already exists`);let d=ll({primaryOriginId:c,secondaryOriginId:u,statusCodes:i.statusCodes,selectionCriteria:i.selectionCriteria}),p=i.type??(Ho(i.domainName)?"s3":"custom"),y={Id:u,DomainName:i.domainName,OriginPath:i.originPath||"",...ce(i,"the failover origin")},h=ce(i.primary,"the primary origin");if(Object.keys(h).length>0){let b=s.Origins.find((v)=>v.Id===c);if(b)Object.assign(b,h)}if(p==="s3"){let b=s.Origins.find((v)=>v.Id===c);if(y.S3OriginConfig={OriginAccessIdentity:""},b?.OriginAccessControlId)y.OriginAccessControlId=b.OriginAccessControlId}else y.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};return s.Origins.push(y),s.OriginGroups={Quantity:1,Items:[d]},o.TargetOriginId=d.Id,Pt(s),n}static setCustomDomain(n,i,s){return n.Properties.DistributionConfig.Aliases=[i],n.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:s,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"},n}static setErrorPages(n,i){return n.Properties.DistributionConfig.CustomErrorResponses=i.map((s)=>({ErrorCode:s.errorCode,ResponseCode:s.responseCode,ResponsePagePath:s.responsePagePath})),n}static enableHttp3(n){return n.Properties.DistributionConfig.HttpVersion="http2and3",n}static addEdgeFunction(n,i,s){if(!n.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations)n.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=[];return n.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations.push({EventType:i,LambdaFunctionARN:s}),n}static setCachePolicy(n,i){return n.Properties.DistributionConfig.Comment=`${n.Properties.DistributionConfig.Comment||""} (TTL: ${i.default||86400}s)`,n}static createSpaDistribution(n){return Ce.createDistribution({...n,errorPages:[{errorCode:404,responseCode:200,responsePagePath:"/index.html"},{errorCode:403,responseCode:200,responsePagePath:"/index.html"}]})}static createDocsOriginRequestFunction(n){let{slug:i,environment:s}=n,o=r({slug:i,environment:s,resourceType:"edge-docs"}),c=t(o),u=t(`${o}-role`),d=t(`${o}-version`),p={Type:"AWS::IAM::Role",Properties:{RoleName:`${o}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["lambda.amazonaws.com","edgelambda.amazonaws.com"]},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}},y=`
95
95
  'use strict';
96
96
 
97
97
  exports.handler = async (event) => {
@@ -197,7 +197,7 @@ exports.handler = async (event) => {
197
197
 
198
198
  return request;
199
199
  };
200
- `.trim()};static Config={ttl:(n)=>{let{min:i=0,max:s=86400,default:o=86400}=n;return{MinTTL:i,MaxTTL:s,DefaultTTL:o}},cookies:(n,i)=>{let s={Forward:n==="allowList"?"whitelist":n};if(n==="allowList"&&i)s.WhitelistedNames=i;return s},allowedMethods:(n)=>{let i={ALL:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return i[n]||i.GET_HEAD},cachedMethods:(n)=>{let i={GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return i[n]||i.GET_HEAD},ttlPresets:{static:{min:0,max:31536000,default:31536000},dynamic:{min:0,max:0,default:0},api:{min:0,max:3600,default:60},html:{min:0,max:86400,default:86400},images:{min:0,max:604800,default:604800}},cacheBehavior:(n)=>{let{ttl:i={min:0,max:86400,default:86400},cookies:s="none",allowedCookies:o,allowedMethods:c="GET_HEAD",cachedMethods:u="GET_HEAD",compress:d=!0,forwardQueryString:p=!0,forwardHeaders:y=[]}=n;return{MinTTL:i.min,MaxTTL:i.max,DefaultTTL:i.default,Compress:d,AllowedMethods:Ce.Config.allowedMethods(c),CachedMethods:Ce.Config.cachedMethods(u),ForwardedValues:{QueryString:p,Headers:y,Cookies:Ce.Config.cookies(s,o)}}}};static applyConfig(n,i){let s=n.Properties.DistributionConfig.DefaultCacheBehavior;if(i.ttl)s.MinTTL=i.ttl.min,s.MaxTTL=i.ttl.max,s.DefaultTTL=i.ttl.default;if(i.compress!==void 0)s.Compress=i.compress;if(i.allowedMethods)s.AllowedMethods=Ce.Config.allowedMethods(i.allowedMethods);if(i.cachedMethods)s.CachedMethods=Ce.Config.cachedMethods(i.cachedMethods);if(i.cookies){if(!s.ForwardedValues)s.ForwardedValues={QueryString:!0};s.ForwardedValues.Cookies=Ce.Config.cookies(i.cookies,i.allowedCookies)}return n}}var ny=[403,404,500,502,503,504],ul="TsCloud::StorageFailover",Go="AllowCloudFrontFailoverRead",vr=/^[a-z]{2}(?:-gov)?-[a-z]+-\d$/,Tr=/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;function vm(n){let{failover:i,primaryBucket:s,primaryRegion:o}=n,c=n.where??"storage failover";if(!i||typeof i!=="object")throw Error(`${c}.failover must be an object such as { region: 'us-west-2' }.`);if(!i.region||!vr.test(i.region))throw Error(`${c}.failover.region must be an AWS region such as 'us-west-2', got ${JSON.stringify(i.region)}.`);if(i.region===o)throw Error(`${c}.failover.region is ${i.region}, the same region as the primary bucket. Failover only helps when the replica is in another region.`);let u=i.bucket??`${s}-${i.region}`;if(!Tr.test(u)||u.includes("..")){let d=i.bucket===void 0&&u.length>63?` The default name (<primary bucket>-<region>) is ${u.length} characters; S3 allows 63. Set ${c}.failover.bucket.`:"";throw Error(`${c}.failover: "${u}" is not a valid S3 bucket name.${d}`)}if(u===s)throw Error(`${c}.failover.bucket must differ from the primary bucket "${s}".`);return{replicaBucket:u,replicaRegion:i.region,replicate:i.replicate!==!1,statusCodes:Qo(i.statusCodes??ny),primaryConnection:ce(i,`${c}.failover`)}}function Tm(n,i){return`${n}.s3.${i}.amazonaws.com`}function wm(n){let i=`arn:aws:s3:::${n.primaryBucket}`,s=`arn:aws:s3:::${n.replicaBucket}`;return{Type:"AWS::IAM::Role",Properties:{...n.roleName?{RoleName:n.roleName}:{},AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"s3.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"failover-replication",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:GetReplicationConfiguration","s3:ListBucket"],Resource:i},{Effect:"Allow",Action:["s3:GetObjectVersionForReplication","s3:GetObjectVersionAcl","s3:GetObjectVersionTagging"],Resource:`${i}/*`},{Effect:"Allow",Action:["s3:ReplicateObject","s3:ReplicateDelete","s3:ReplicateTags"],Resource:`${s}/*`}]}}]}}}function Rm(n){return{Role:n.roleArn,Rules:[{Id:"cloudfront-failover-replica",Status:"Enabled",Priority:1,Filter:{Prefix:""},DeleteMarkerReplication:{Status:"Enabled"},Destination:{Bucket:`arn:aws:s3:::${n.replicaBucket}`}}]}}function gl(n){return{Sid:Go,Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:`arn:aws:s3:::${n.replicaBucket}/*`,Condition:{StringEquals:{"AWS:SourceArn":n.distributionArn}}}}function zI(n){let s=(typeof n==="string"?JSON.parse(n):n)?.Metadata?.[ul];return Array.isArray(s)?s:[]}class W{static createHostedZone(n){let{domain:i,slug:s,environment:o,comment:c}=n,u=r({slug:s,environment:o,resourceType:"hostedzone"}),d=t(`${u}-${i.replace(/\./g,"")}`);return{zone:{Type:"AWS::Route53::HostedZone",Properties:{Name:i,HostedZoneConfig:{Comment:c||`Hosted zone for ${i}`}}},logicalId:d}}static createRecord(n){let{hostedZoneId:i,hostedZoneName:s,name:o,type:c,ttl:u,values:d,aliasTarget:p}=n,y=t(`record-${o.replace(/\./g,"")}-${c}`),h={Type:"AWS::Route53::RecordSet",Properties:{Name:o,Type:c}};if(i)h.Properties.HostedZoneId=i;else if(s)h.Properties.HostedZoneName=s;if(p)h.Properties.AliasTarget={DNSName:p.dnsName,HostedZoneId:p.hostedZoneId,EvaluateTargetHealth:p.evaluateTargetHealth??!1};else h.Properties.TTL=u||300,h.Properties.ResourceRecords=d||[];return{record:h,logicalId:y}}static createCloudFrontAlias(n,i,s){return W.createRecord({hostedZoneId:s,name:n,type:"A",aliasTarget:{dnsName:i,hostedZoneId:"Z2FDTNDATAQYW2",evaluateTargetHealth:!1}})}static createAlbAlias(n,i,s,o){return W.createRecord({hostedZoneId:o,name:n,type:"A",aliasTarget:{dnsName:i,hostedZoneId:s,evaluateTargetHealth:!0}})}static createCname(n,i,s,o=300){return W.createRecord({hostedZoneId:s,name:n,type:"CNAME",ttl:o,values:[i]})}static createWwwRedirect(n,i){return W.createRecord({hostedZoneId:i,name:`www.${n}`,type:"CNAME",ttl:300,values:[n]})}static createMxRecords(n,i,s,o=300){return W.createRecord({hostedZoneId:s,name:n,type:"MX",ttl:o,values:i.map((c)=>`${c.priority} ${c.server}`)})}static createTxtRecord(n,i,s,o=300){return W.createRecord({hostedZoneId:s,name:n,type:"TXT",ttl:o,values:[`"${i}"`]})}static createSpfRecord(n,i,s){return W.createTxtRecord(n,i,s)}static createDmarcRecord(n,i,s,o){let c=`v=DMARC1; p=${i}; rua=mailto:${s}`;return W.createTxtRecord(`_dmarc.${n}`,c,o)}static createS3WebsiteAlias(n,i,s,o){return W.createRecord({hostedZoneId:o,name:n,type:"A",aliasTarget:{dnsName:i,hostedZoneId:s,evaluateTargetHealth:!1}})}static S3WebsiteHostedZoneIds={"us-east-1":"Z3AQBSTGFYJSTF","us-east-2":"Z2O1EMRO9K5GLX","us-west-1":"Z2F56UZL2M1ACD","us-west-2":"Z3BJ6K6RIION7M","af-south-1":"Z83WF9RJE8B12","ap-east-1":"ZNB98KWMFR0R6","ap-south-1":"Z11RGJOFQNVJUP","ap-south-2":"Z02976202B4EZMXIPMXF7","ap-northeast-1":"Z2M4EHUR26P7ZW","ap-northeast-2":"Z3W03O7B5YMIYP","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"Z3O0J2DXBE1FTB","ap-southeast-2":"Z1WCIBER6CPFUU","ap-southeast-3":"Z01613992JD795ZI93075","ca-central-1":"Z1QDHH18159H29","eu-central-1":"Z21DNDUVLTQW6Q","eu-central-2":"Z030506016YDQGETNASS","eu-west-1":"Z1BKCTXD74EZPE","eu-west-2":"Z3GKZC51ZF0DB4","eu-west-3":"Z3R1K369G5AVDG","eu-north-1":"Z3BAZG2TWCNX0D","eu-south-1":"Z30OZKI7KPW7MI","eu-south-2":"Z0081959F7139GRJC19J","me-south-1":"Z1MPMWCPA7YB62","me-central-1":"Z06143092I8HRBER9VXCO","sa-east-1":"Z7KQH4QJS55SO"};static getS3WebsiteEndpoint(n,i){return`${n}.s3-website-${i}.amazonaws.com`}static createStoreRecord(n,i,s){return W.createCname(`store.${n}`,i,s)}static createApiRecord(n,i,s){return W.createCname(`api.${n}`,i,s)}static createDocsRecord(n,i,s){return W.createCname(`docs.${n}`,i,s)}static CloudFrontHostedZoneId="Z2FDTNDATAQYW2"}class E{static createCertificate(n){let{domain:i,subdomains:s=[],slug:o,environment:c,validationMethod:u="DNS",hostedZoneId:d}=n,p=r({slug:o,environment:c,resourceType:"acm"}),y=t(`${p}-${i.replace(/\./g,"")}`),h=[i];for(let v of s)if(v==="*")h.push(`*.${i}`);else h.push(`${v}.${i}`);let b={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:i,SubjectAlternativeNames:h,ValidationMethod:u}};if(u==="DNS"&&d)b.Properties.DomainValidationOptions=h.map((v)=>({DomainName:v,HostedZoneId:d}));return{certificate:b,logicalId:y}}static createKmsKey(n){let{description:i,slug:s,environment:o,enableRotation:c=!0,multiRegion:u=!1}=n,d=r({slug:s,environment:o,resourceType:"kms"}),p=t(d),y={Version:"2012-10-17",Statement:[{Sid:"Enable IAM User Permissions",Effect:"Allow",Principal:{AWS:x.Sub("arn:aws:iam::${AWS::AccountId}:root")},Action:"kms:*",Resource:"*"},{Sid:"Allow services to use the key",Effect:"Allow",Principal:{Service:["s3.amazonaws.com","cloudfront.amazonaws.com","logs.amazonaws.com","secretsmanager.amazonaws.com"]},Action:["kms:Decrypt","kms:GenerateDataKey"],Resource:"*"}]},h={Type:"AWS::KMS::Key",Properties:{Description:i,Enabled:!0,EnableKeyRotation:c,KeyPolicy:y,KeySpec:"SYMMETRIC_DEFAULT",KeyUsage:"ENCRYPT_DECRYPT",MultiRegion:u}},b=t(`${d}-alias`),v={Type:"AWS::KMS::Alias",Properties:{AliasName:`alias/${s}-${o}`,TargetKeyId:x.Ref(p)}};return{key:h,alias:v,logicalId:p,aliasId:b}}static createFirewall(n){let{slug:i,environment:s,scope:o="CLOUDFRONT",defaultAction:c="allow"}=n,u=r({slug:i,environment:s,resourceType:"waf"}),d=t(u);return{webAcl:{Type:"AWS::WAFv2::WebACL",Properties:{Name:u,Scope:o,DefaultAction:c==="allow"?{Allow:{}}:{Block:{}},Description:`WAF for ${i} ${s}`,Rules:[],VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${u}-metric`}}},logicalId:d}}static setRateLimit(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{RateBasedStatement:{Limit:i.requestsPerWindow,AggregateKeyType:i.aggregateKeyType||"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static blockCountries(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{GeoMatchStatement:{CountryCodes:i.countryCodes}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static blockIpAddresses(n,i,s,o){let c=r({slug:s,environment:o,resourceType:"ipset"}),u=t(`${c}-${i.name}`),d={Type:"AWS::WAFv2::IPSet",Properties:{Name:`${c}-${i.name}`,Scope:n.Properties.Scope,IPAddressVersion:i.ipVersion||"IPV4",Addresses:i.ipAddresses,Description:`Blocked IPs for ${i.name}`}};if(!n.Properties.Rules)n.Properties.Rules=[];return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{IPSetReferenceStatement:{Arn:x.GetAtt(u,"Arn")}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),{webAcl:n,ipSet:d,ipSetLogicalId:u}}static addManagedRules(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];let s={ManagedRuleGroupStatement:{VendorName:i.vendorName,Name:i.ruleName}};if(i.excludedRules&&i.excludedRules.length>0)s.ManagedRuleGroupStatement.ExcludedRules=i.excludedRules.map((o)=>({Name:o}));return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:s,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static ManagedRuleGroups={CoreRuleSet:{vendorName:"AWS",ruleName:"AWSManagedRulesCommonRuleSet"},KnownBadInputs:{vendorName:"AWS",ruleName:"AWSManagedRulesKnownBadInputsRuleSet"},SqlDatabase:{vendorName:"AWS",ruleName:"AWSManagedRulesSQLiRuleSet"},LinuxOS:{vendorName:"AWS",ruleName:"AWSManagedRulesLinuxRuleSet"},PosixOS:{vendorName:"AWS",ruleName:"AWSManagedRulesUnixRuleSet"},AmazonIpReputation:{vendorName:"AWS",ruleName:"AWSManagedRulesAmazonIpReputationList"},AnonymousIpList:{vendorName:"AWS",ruleName:"AWSManagedRulesAnonymousIpList"},BotControl:{vendorName:"AWS",ruleName:"AWSManagedRulesBotControlRuleSet"}};static setPathRateLimit(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];let s=i.paths.map((o)=>({SearchString:o,FieldToMatch:{UriPath:{}},TextTransformation:[{Priority:0,Type:"LOWERCASE"}],PositionalConstraint:"STARTS_WITH"}));return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{RateBasedStatement:{Limit:i.requestsPerWindow,AggregateKeyType:i.aggregateKeyType||"IP",ScopeDownStatement:{OrStatement:{Statements:s.map((o)=>({ByteMatchStatement:o}))}}}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static setHeaderRateLimit(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];let s={RateBasedStatement:{Limit:i.requestsPerWindow,AggregateKeyType:"CUSTOM_KEYS",CustomKeys:[{Header:{Name:i.headerName,TextTransformations:[{Priority:0,Type:"NONE"}]}}]}};if(i.headerValue)s.RateBasedStatement.ScopeDownStatement={ByteMatchStatement:{SearchString:i.headerValue,FieldToMatch:{SingleHeader:{Name:i.headerName}},TextTransformation:[{Priority:0,Type:"NONE"}],PositionalConstraint:"EXACTLY"}};return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:s,Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static protectLoginEndpoint(n,i){let{loginPaths:s,priority:o,requestsPerMinute:c=10}=i;return E.setPathRateLimit(n,{name:"LoginRateLimit",priority:o,requestsPerWindow:c*5,paths:s}),n}static protectApiEndpoints(n,i){let{apiPaths:s,priority:o,requestsPerMinute:c=100}=i;return E.setPathRateLimit(n,{name:"ApiRateLimit",priority:o,requestsPerWindow:c*5,paths:s}),n}static createProtectedFirewall(n){let{slug:i,environment:s,scope:o="CLOUDFRONT",enableBotControl:c=!1,enableRateLimiting:u=!0,rateLimitPerMinute:d=2000}=n,{webAcl:p,logicalId:y}=E.createFirewall({slug:i,environment:s,scope:o,defaultAction:"allow"}),h=0;if(p=E.addManagedRules(p,{name:"AWSIPReputationList",priority:h++,...E.ManagedRuleGroups.AmazonIpReputation}),p=E.addManagedRules(p,{name:"AWSAnonymousIPList",priority:h++,...E.ManagedRuleGroups.AnonymousIpList}),p=E.addManagedRules(p,{name:"AWSCoreRuleSet",priority:h++,...E.ManagedRuleGroups.CoreRuleSet}),p=E.addManagedRules(p,{name:"AWSKnownBadInputs",priority:h++,...E.ManagedRuleGroups.KnownBadInputs}),p=E.addManagedRules(p,{name:"AWSSQLi",priority:h++,...E.ManagedRuleGroups.SqlDatabase}),c)p=E.addManagedRules(p,{name:"AWSBotControl",priority:h++,...E.ManagedRuleGroups.BotControl});if(u)p=E.setRateLimit(p,{name:"GlobalRateLimit",priority:h++,requestsPerWindow:d*5});return{webAcl:p,logicalId:y}}static RateLimitPresets={STANDARD:2000,HIGH_TRAFFIC:1e4,STRICT:100,LOGIN:10,API:100}}function iy(n){let i=n.split(".")[0]??"";return i==="a1"||/^[a-z]+\d+g[a-z]*$/.test(i)}function sy(n="t3.micro"){return`/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-${iy(n)?"arm64":"x86_64"}`}function Dm(n="t3.micro"){return`{{resolve:ssm:${sy(n)}}}`}class a{static createServer(n){let{slug:i,environment:s,instanceType:o="t3.micro",imageId:c=Dm(o),keyName:u,securityGroupIds:d,subnetId:p,userData:y,volumeSize:h=20,volumeType:b="gp3",encrypted:v=!0}=n,A=r({slug:i,environment:s,resourceType:"ec2"}),T=t(A),R={Type:"AWS::EC2::Instance",Properties:{ImageId:c,InstanceType:o,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:s}]}};if(u)R.Properties.KeyName=u;if(d)R.Properties.SecurityGroupIds=d;if(p)R.Properties.SubnetId=p;if(y)R.Properties.UserData=x.Base64(y);return R.Properties.BlockDeviceMappings=[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:h,VolumeType:b,Encrypted:v,DeleteOnTermination:!0}}],{instance:R,logicalId:T}}static createSecurityGroup(n){let{slug:i,environment:s,vpcId:o,description:c,ingress:u=[],egress:d=[]}=n,p=r({slug:i,environment:s,resourceType:"sg"}),y=t(p),h={Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:c||`Security group for ${i} ${s}`,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(o)h.Properties.VpcId=o;if(u.length>0)h.Properties.SecurityGroupIngress=u.map((b)=>({IpProtocol:b.protocol,FromPort:b.fromPort,ToPort:b.toPort,CidrIp:b.cidr,SourceSecurityGroupId:b.sourceSecurityGroupId}));if(d.length>0)h.Properties.SecurityGroupEgress=d.map((b)=>({IpProtocol:b.protocol,FromPort:b.fromPort,ToPort:b.toPort,CidrIp:b.cidr,DestinationSecurityGroupId:b.sourceSecurityGroupId}));return{securityGroup:h,logicalId:y}}static createWebServerSecurityGroup(n,i,s){return a.createSecurityGroup({slug:n,environment:i,vpcId:s,description:"Security group for web servers - HTTP, HTTPS, SSH",ingress:[{protocol:"tcp",fromPort:80,toPort:80,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:443,toPort:443,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:22,toPort:22,cidr:"0.0.0.0/0"}],egress:[{protocol:"-1",fromPort:0,toPort:0,cidr:"0.0.0.0/0"}]})}static createLoadBalancer(n){let{slug:i,environment:s,scheme:o="internet-facing",subnets:c,securityGroups:u,type:d="application"}=n,p=r({slug:i,environment:s,resourceType:"alb"}),y=t(p),h={Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:p,Scheme:o,Type:d,Subnets:c,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(u)h.Properties.SecurityGroups=u;return{loadBalancer:h,logicalId:y}}static createTargetGroup(n){let{slug:i,environment:s,port:o,protocol:c="HTTP",vpcId:u,targetType:d="ip",healthCheckPath:p="/",healthCheckInterval:y=30,healthCheckTimeout:h=5,healthyThreshold:b=2,unhealthyThreshold:v=3}=n,A=r({slug:i,environment:s,resourceType:"tg"}),T=t(A);return{targetGroup:{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:A,Port:o,Protocol:c,VpcId:u,TargetType:d,HealthCheckEnabled:!0,HealthCheckProtocol:c,HealthCheckPath:p,HealthCheckIntervalSeconds:y,HealthCheckTimeoutSeconds:h,HealthyThresholdCount:b,UnhealthyThresholdCount:v,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:s}]}},logicalId:T}}static createListener(n,i){let{port:s,protocol:o="HTTP",certificateArn:c,defaultTargetGroupArn:u}=i,d=t(`listener-${n}-${s}`),p={Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:x.Ref(n),Port:s,Protocol:o,DefaultActions:[{Type:"forward",TargetGroupArn:u}]}};if(o==="HTTPS"&&c)p.Properties.Certificates=[{CertificateArn:c}],p.Properties.SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06";return{listener:p,logicalId:d}}static createEcsCluster(n,i){let s=r({slug:n,environment:i,resourceType:"ecs-cluster"}),o=t(s);return{cluster:{Type:"AWS::ECS::Cluster",Properties:{ClusterName:s,Tags:[{Key:"Name",Value:s},{Key:"Environment",Value:i}]}},logicalId:o}}static createFargateService(n){let{slug:i,environment:s,image:o,cpu:c="256",memory:u="512",desiredCount:d=1,containerPort:p=8080,environmentVariables:y={},secrets:h=[],healthCheck:b,logGroup:v,subnets:A,securityGroups:T,targetGroupArn:R}=n,{cluster:P,logicalId:I}=a.createEcsCluster(i,s),M=r({slug:i,environment:s,resourceType:"fargate"}),L=t(`${M}-execution-role`),N={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]}},O=t(`${M}-task-role`),B={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]}}},F=t(`${M}-task`),U={Type:"AWS::ECS::TaskDefinition",Properties:{Family:M,TaskRoleArn:x.GetAtt(O,"Arn"),ExecutionRoleArn:x.GetAtt(L,"Arn"),NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:c,Memory:u,ContainerDefinitions:[{Name:i,Image:o,Essential:!0,PortMappings:[{ContainerPort:p,Protocol:"tcp"}],Environment:Object.entries(y).map(([z,ae])=>({Name:z,Value:ae})),Secrets:h.map((z)=>({Name:z.name,ValueFrom:z.valueFrom}))}],Tags:[{Key:"Name",Value:M},{Key:"Environment",Value:s}]}};if(b)U.Properties.ContainerDefinitions[0].HealthCheck={Command:b.command,Interval:b.interval||30,Timeout:b.timeout||5,Retries:b.retries||3,StartPeriod:60};if(v)U.Properties.ContainerDefinitions[0].LogConfiguration={LogDriver:"awslogs",Options:{"awslogs-group":v,"awslogs-region":x.Ref("AWS::Region"),"awslogs-stream-prefix":i}};let j=t(`${M}-service`),H={Type:"AWS::ECS::Service",Properties:{ServiceName:M,Cluster:x.Ref(I),TaskDefinition:x.Ref(F),DesiredCount:d,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{Subnets:A,SecurityGroups:T,AssignPublicIp:"ENABLED"}},Tags:[{Key:"Name",Value:M},{Key:"Environment",Value:s}]}};if(R)H.Properties.LoadBalancers=[{TargetGroupArn:R,ContainerName:i,ContainerPort:p}];return{cluster:P,taskDefinition:U,service:H,taskRole:B,executionRole:N,clusterLogicalId:I,taskDefinitionLogicalId:F,serviceLogicalId:j,taskRoleLogicalId:O,executionRoleLogicalId:L}}static createLambdaFunction(n){let{slug:i,environment:s,runtime:o,handler:c,code:u,timeout:d=30,memorySize:p=128,environmentVariables:y={},vpcConfig:h}=n,b=r({slug:i,environment:s,resourceType:"lambda"}),v=t(b),A=t(`${b}-role`),T={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}};if(h)T.Properties.ManagedPolicyArns.push("arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole");let R={Type:"AWS::Lambda::Function",Properties:{FunctionName:b,Runtime:o,Role:x.GetAtt(A,"Arn"),Handler:c,Code:{...u.s3Bucket&&{S3Bucket:u.s3Bucket},...u.s3Key&&{S3Key:u.s3Key},...u.zipFile&&{ZipFile:u.zipFile}},Timeout:d,MemorySize:p,Tags:[{Key:"Name",Value:b},{Key:"Environment",Value:s}]}};if(Object.keys(y).length>0)R.Properties.Environment={Variables:y};if(h)R.Properties.VpcConfig={SecurityGroupIds:h.securityGroupIds,SubnetIds:h.subnetIds};return{lambdaFunction:R,role:T,logicalId:v,roleLogicalId:A}}static generateNodeServerUserData(n={}){let{nodeVersion:i="20",appRepo:s,environment:o={}}=n,c=Object.entries(o).map(([u,d])=>`echo "export ${u}='${d}'" >> /etc/environment`).join(`
200
+ `.trim()};static Config={ttl:(n)=>{let{min:i=0,max:s=86400,default:o=86400}=n;return{MinTTL:i,MaxTTL:s,DefaultTTL:o}},cookies:(n,i)=>{let s={Forward:n==="allowList"?"whitelist":n};if(n==="allowList"&&i)s.WhitelistedNames=i;return s},allowedMethods:(n)=>{let i={ALL:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return i[n]||i.GET_HEAD},cachedMethods:(n)=>{let i={GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return i[n]||i.GET_HEAD},ttlPresets:{static:{min:0,max:31536000,default:31536000},dynamic:{min:0,max:0,default:0},api:{min:0,max:3600,default:60},html:{min:0,max:86400,default:86400},images:{min:0,max:604800,default:604800}},cacheBehavior:(n)=>{let{ttl:i={min:0,max:86400,default:86400},cookies:s="none",allowedCookies:o,allowedMethods:c="GET_HEAD",cachedMethods:u="GET_HEAD",compress:d=!0,forwardQueryString:p=!0,forwardHeaders:y=[]}=n;return{MinTTL:i.min,MaxTTL:i.max,DefaultTTL:i.default,Compress:d,AllowedMethods:Ce.Config.allowedMethods(c),CachedMethods:Ce.Config.cachedMethods(u),ForwardedValues:{QueryString:p,Headers:y,Cookies:Ce.Config.cookies(s,o)}}}};static applyConfig(n,i){let s=n.Properties.DistributionConfig.DefaultCacheBehavior;if(i.ttl)s.MinTTL=i.ttl.min,s.MaxTTL=i.ttl.max,s.DefaultTTL=i.ttl.default;if(i.compress!==void 0)s.Compress=i.compress;if(i.allowedMethods)s.AllowedMethods=Ce.Config.allowedMethods(i.allowedMethods);if(i.cachedMethods)s.CachedMethods=Ce.Config.cachedMethods(i.cachedMethods);if(i.cookies){if(!s.ForwardedValues)s.ForwardedValues={QueryString:!0};s.ForwardedValues.Cookies=Ce.Config.cookies(i.cookies,i.allowedCookies)}return n}}var iy=[403,404,500,502,503,504],ul="TsCloud::StorageFailover",Go="AllowCloudFrontFailoverRead",vr=/^[a-z]{2}(?:-gov)?-[a-z]+-\d$/,Tr=/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;function Tm(n){let{failover:i,primaryBucket:s,primaryRegion:o}=n,c=n.where??"storage failover";if(!i||typeof i!=="object")throw Error(`${c}.failover must be an object such as { region: 'us-west-2' }.`);if(!i.region||!vr.test(i.region))throw Error(`${c}.failover.region must be an AWS region such as 'us-west-2', got ${JSON.stringify(i.region)}.`);if(i.region===o)throw Error(`${c}.failover.region is ${i.region}, the same region as the primary bucket. Failover only helps when the replica is in another region.`);let u=i.bucket??`${s}-${i.region}`;if(!Tr.test(u)||u.includes("..")){let d=i.bucket===void 0&&u.length>63?` The default name (<primary bucket>-<region>) is ${u.length} characters; S3 allows 63. Set ${c}.failover.bucket.`:"";throw Error(`${c}.failover: "${u}" is not a valid S3 bucket name.${d}`)}if(u===s)throw Error(`${c}.failover.bucket must differ from the primary bucket "${s}".`);return{replicaBucket:u,replicaRegion:i.region,replicate:i.replicate!==!1,statusCodes:Qo(i.statusCodes??iy),primaryConnection:ce(i,`${c}.failover`)}}function wm(n,i){return`${n}.s3.${i}.amazonaws.com`}function Rm(n){let i=`arn:aws:s3:::${n.primaryBucket}`,s=`arn:aws:s3:::${n.replicaBucket}`;return{Type:"AWS::IAM::Role",Properties:{...n.roleName?{RoleName:n.roleName}:{},AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"s3.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"failover-replication",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:GetReplicationConfiguration","s3:ListBucket"],Resource:i},{Effect:"Allow",Action:["s3:GetObjectVersionForReplication","s3:GetObjectVersionAcl","s3:GetObjectVersionTagging"],Resource:`${i}/*`},{Effect:"Allow",Action:["s3:ReplicateObject","s3:ReplicateDelete","s3:ReplicateTags"],Resource:`${s}/*`}]}}]}}}function Dm(n){return{Role:n.roleArn,Rules:[{Id:"cloudfront-failover-replica",Status:"Enabled",Priority:1,Filter:{Prefix:""},DeleteMarkerReplication:{Status:"Enabled"},Destination:{Bucket:`arn:aws:s3:::${n.replicaBucket}`}}]}}function gl(n){return{Sid:Go,Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:`arn:aws:s3:::${n.replicaBucket}/*`,Condition:{StringEquals:{"AWS:SourceArn":n.distributionArn}}}}function KI(n){let s=(typeof n==="string"?JSON.parse(n):n)?.Metadata?.[ul];return Array.isArray(s)?s:[]}class W{static createHostedZone(n){let{domain:i,slug:s,environment:o,comment:c}=n,u=r({slug:s,environment:o,resourceType:"hostedzone"}),d=t(`${u}-${i.replace(/\./g,"")}`);return{zone:{Type:"AWS::Route53::HostedZone",Properties:{Name:i,HostedZoneConfig:{Comment:c||`Hosted zone for ${i}`}}},logicalId:d}}static createRecord(n){let{hostedZoneId:i,hostedZoneName:s,name:o,type:c,ttl:u,values:d,aliasTarget:p}=n,y=t(`record-${o.replace(/\./g,"")}-${c}`),h={Type:"AWS::Route53::RecordSet",Properties:{Name:o,Type:c}};if(i)h.Properties.HostedZoneId=i;else if(s)h.Properties.HostedZoneName=s;if(p)h.Properties.AliasTarget={DNSName:p.dnsName,HostedZoneId:p.hostedZoneId,EvaluateTargetHealth:p.evaluateTargetHealth??!1};else h.Properties.TTL=u||300,h.Properties.ResourceRecords=d||[];return{record:h,logicalId:y}}static createCloudFrontAlias(n,i,s){return W.createRecord({hostedZoneId:s,name:n,type:"A",aliasTarget:{dnsName:i,hostedZoneId:"Z2FDTNDATAQYW2",evaluateTargetHealth:!1}})}static createAlbAlias(n,i,s,o){return W.createRecord({hostedZoneId:o,name:n,type:"A",aliasTarget:{dnsName:i,hostedZoneId:s,evaluateTargetHealth:!0}})}static createCname(n,i,s,o=300){return W.createRecord({hostedZoneId:s,name:n,type:"CNAME",ttl:o,values:[i]})}static createWwwRedirect(n,i){return W.createRecord({hostedZoneId:i,name:`www.${n}`,type:"CNAME",ttl:300,values:[n]})}static createMxRecords(n,i,s,o=300){return W.createRecord({hostedZoneId:s,name:n,type:"MX",ttl:o,values:i.map((c)=>`${c.priority} ${c.server}`)})}static createTxtRecord(n,i,s,o=300){return W.createRecord({hostedZoneId:s,name:n,type:"TXT",ttl:o,values:[`"${i}"`]})}static createSpfRecord(n,i,s){return W.createTxtRecord(n,i,s)}static createDmarcRecord(n,i,s,o){let c=`v=DMARC1; p=${i}; rua=mailto:${s}`;return W.createTxtRecord(`_dmarc.${n}`,c,o)}static createS3WebsiteAlias(n,i,s,o){return W.createRecord({hostedZoneId:o,name:n,type:"A",aliasTarget:{dnsName:i,hostedZoneId:s,evaluateTargetHealth:!1}})}static S3WebsiteHostedZoneIds={"us-east-1":"Z3AQBSTGFYJSTF","us-east-2":"Z2O1EMRO9K5GLX","us-west-1":"Z2F56UZL2M1ACD","us-west-2":"Z3BJ6K6RIION7M","af-south-1":"Z83WF9RJE8B12","ap-east-1":"ZNB98KWMFR0R6","ap-south-1":"Z11RGJOFQNVJUP","ap-south-2":"Z02976202B4EZMXIPMXF7","ap-northeast-1":"Z2M4EHUR26P7ZW","ap-northeast-2":"Z3W03O7B5YMIYP","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"Z3O0J2DXBE1FTB","ap-southeast-2":"Z1WCIBER6CPFUU","ap-southeast-3":"Z01613992JD795ZI93075","ca-central-1":"Z1QDHH18159H29","eu-central-1":"Z21DNDUVLTQW6Q","eu-central-2":"Z030506016YDQGETNASS","eu-west-1":"Z1BKCTXD74EZPE","eu-west-2":"Z3GKZC51ZF0DB4","eu-west-3":"Z3R1K369G5AVDG","eu-north-1":"Z3BAZG2TWCNX0D","eu-south-1":"Z30OZKI7KPW7MI","eu-south-2":"Z0081959F7139GRJC19J","me-south-1":"Z1MPMWCPA7YB62","me-central-1":"Z06143092I8HRBER9VXCO","sa-east-1":"Z7KQH4QJS55SO"};static getS3WebsiteEndpoint(n,i){return`${n}.s3-website-${i}.amazonaws.com`}static createStoreRecord(n,i,s){return W.createCname(`store.${n}`,i,s)}static createApiRecord(n,i,s){return W.createCname(`api.${n}`,i,s)}static createDocsRecord(n,i,s){return W.createCname(`docs.${n}`,i,s)}static CloudFrontHostedZoneId="Z2FDTNDATAQYW2"}class E{static createCertificate(n){let{domain:i,subdomains:s=[],slug:o,environment:c,validationMethod:u="DNS",hostedZoneId:d}=n,p=r({slug:o,environment:c,resourceType:"acm"}),y=t(`${p}-${i.replace(/\./g,"")}`),h=[i];for(let v of s)if(v==="*")h.push(`*.${i}`);else h.push(`${v}.${i}`);let b={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:i,SubjectAlternativeNames:h,ValidationMethod:u}};if(u==="DNS"&&d)b.Properties.DomainValidationOptions=h.map((v)=>({DomainName:v,HostedZoneId:d}));return{certificate:b,logicalId:y}}static createKmsKey(n){let{description:i,slug:s,environment:o,enableRotation:c=!0,multiRegion:u=!1}=n,d=r({slug:s,environment:o,resourceType:"kms"}),p=t(d),y={Version:"2012-10-17",Statement:[{Sid:"Enable IAM User Permissions",Effect:"Allow",Principal:{AWS:x.Sub("arn:aws:iam::${AWS::AccountId}:root")},Action:"kms:*",Resource:"*"},{Sid:"Allow services to use the key",Effect:"Allow",Principal:{Service:["s3.amazonaws.com","cloudfront.amazonaws.com","logs.amazonaws.com","secretsmanager.amazonaws.com"]},Action:["kms:Decrypt","kms:GenerateDataKey"],Resource:"*"}]},h={Type:"AWS::KMS::Key",Properties:{Description:i,Enabled:!0,EnableKeyRotation:c,KeyPolicy:y,KeySpec:"SYMMETRIC_DEFAULT",KeyUsage:"ENCRYPT_DECRYPT",MultiRegion:u}},b=t(`${d}-alias`),v={Type:"AWS::KMS::Alias",Properties:{AliasName:`alias/${s}-${o}`,TargetKeyId:x.Ref(p)}};return{key:h,alias:v,logicalId:p,aliasId:b}}static createFirewall(n){let{slug:i,environment:s,scope:o="CLOUDFRONT",defaultAction:c="allow"}=n,u=r({slug:i,environment:s,resourceType:"waf"}),d=t(u);return{webAcl:{Type:"AWS::WAFv2::WebACL",Properties:{Name:u,Scope:o,DefaultAction:c==="allow"?{Allow:{}}:{Block:{}},Description:`WAF for ${i} ${s}`,Rules:[],VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${u}-metric`}}},logicalId:d}}static setRateLimit(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{RateBasedStatement:{Limit:i.requestsPerWindow,AggregateKeyType:i.aggregateKeyType||"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static blockCountries(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{GeoMatchStatement:{CountryCodes:i.countryCodes}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static blockIpAddresses(n,i,s,o){let c=r({slug:s,environment:o,resourceType:"ipset"}),u=t(`${c}-${i.name}`),d={Type:"AWS::WAFv2::IPSet",Properties:{Name:`${c}-${i.name}`,Scope:n.Properties.Scope,IPAddressVersion:i.ipVersion||"IPV4",Addresses:i.ipAddresses,Description:`Blocked IPs for ${i.name}`}};if(!n.Properties.Rules)n.Properties.Rules=[];return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{IPSetReferenceStatement:{Arn:x.GetAtt(u,"Arn")}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),{webAcl:n,ipSet:d,ipSetLogicalId:u}}static addManagedRules(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];let s={ManagedRuleGroupStatement:{VendorName:i.vendorName,Name:i.ruleName}};if(i.excludedRules&&i.excludedRules.length>0)s.ManagedRuleGroupStatement.ExcludedRules=i.excludedRules.map((o)=>({Name:o}));return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:s,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static ManagedRuleGroups={CoreRuleSet:{vendorName:"AWS",ruleName:"AWSManagedRulesCommonRuleSet"},KnownBadInputs:{vendorName:"AWS",ruleName:"AWSManagedRulesKnownBadInputsRuleSet"},SqlDatabase:{vendorName:"AWS",ruleName:"AWSManagedRulesSQLiRuleSet"},LinuxOS:{vendorName:"AWS",ruleName:"AWSManagedRulesLinuxRuleSet"},PosixOS:{vendorName:"AWS",ruleName:"AWSManagedRulesUnixRuleSet"},AmazonIpReputation:{vendorName:"AWS",ruleName:"AWSManagedRulesAmazonIpReputationList"},AnonymousIpList:{vendorName:"AWS",ruleName:"AWSManagedRulesAnonymousIpList"},BotControl:{vendorName:"AWS",ruleName:"AWSManagedRulesBotControlRuleSet"}};static setPathRateLimit(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];let s=i.paths.map((o)=>({SearchString:o,FieldToMatch:{UriPath:{}},TextTransformation:[{Priority:0,Type:"LOWERCASE"}],PositionalConstraint:"STARTS_WITH"}));return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:{RateBasedStatement:{Limit:i.requestsPerWindow,AggregateKeyType:i.aggregateKeyType||"IP",ScopeDownStatement:{OrStatement:{Statements:s.map((o)=>({ByteMatchStatement:o}))}}}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static setHeaderRateLimit(n,i){if(!n.Properties.Rules)n.Properties.Rules=[];let s={RateBasedStatement:{Limit:i.requestsPerWindow,AggregateKeyType:"CUSTOM_KEYS",CustomKeys:[{Header:{Name:i.headerName,TextTransformations:[{Priority:0,Type:"NONE"}]}}]}};if(i.headerValue)s.RateBasedStatement.ScopeDownStatement={ByteMatchStatement:{SearchString:i.headerValue,FieldToMatch:{SingleHeader:{Name:i.headerName}},TextTransformation:[{Priority:0,Type:"NONE"}],PositionalConstraint:"EXACTLY"}};return n.Properties.Rules.push({Name:i.name,Priority:i.priority,Statement:s,Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${i.name}-metric`}}),n}static protectLoginEndpoint(n,i){let{loginPaths:s,priority:o,requestsPerMinute:c=10}=i;return E.setPathRateLimit(n,{name:"LoginRateLimit",priority:o,requestsPerWindow:c*5,paths:s}),n}static protectApiEndpoints(n,i){let{apiPaths:s,priority:o,requestsPerMinute:c=100}=i;return E.setPathRateLimit(n,{name:"ApiRateLimit",priority:o,requestsPerWindow:c*5,paths:s}),n}static createProtectedFirewall(n){let{slug:i,environment:s,scope:o="CLOUDFRONT",enableBotControl:c=!1,enableRateLimiting:u=!0,rateLimitPerMinute:d=2000}=n,{webAcl:p,logicalId:y}=E.createFirewall({slug:i,environment:s,scope:o,defaultAction:"allow"}),h=0;if(p=E.addManagedRules(p,{name:"AWSIPReputationList",priority:h++,...E.ManagedRuleGroups.AmazonIpReputation}),p=E.addManagedRules(p,{name:"AWSAnonymousIPList",priority:h++,...E.ManagedRuleGroups.AnonymousIpList}),p=E.addManagedRules(p,{name:"AWSCoreRuleSet",priority:h++,...E.ManagedRuleGroups.CoreRuleSet}),p=E.addManagedRules(p,{name:"AWSKnownBadInputs",priority:h++,...E.ManagedRuleGroups.KnownBadInputs}),p=E.addManagedRules(p,{name:"AWSSQLi",priority:h++,...E.ManagedRuleGroups.SqlDatabase}),c)p=E.addManagedRules(p,{name:"AWSBotControl",priority:h++,...E.ManagedRuleGroups.BotControl});if(u)p=E.setRateLimit(p,{name:"GlobalRateLimit",priority:h++,requestsPerWindow:d*5});return{webAcl:p,logicalId:y}}static RateLimitPresets={STANDARD:2000,HIGH_TRAFFIC:1e4,STRICT:100,LOGIN:10,API:100}}function sy(n){let i=n.split(".")[0]??"";return i==="a1"||/^[a-z]+\d+g[a-z]*$/.test(i)}function oy(n="t3.micro"){return`/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-${sy(n)?"arm64":"x86_64"}`}function Pm(n="t3.micro"){return`{{resolve:ssm:${oy(n)}}}`}class a{static createServer(n){let{slug:i,environment:s,instanceType:o="t3.micro",imageId:c=Pm(o),keyName:u,securityGroupIds:d,subnetId:p,userData:y,volumeSize:h=20,volumeType:b="gp3",encrypted:v=!0}=n,A=r({slug:i,environment:s,resourceType:"ec2"}),T=t(A),R={Type:"AWS::EC2::Instance",Properties:{ImageId:c,InstanceType:o,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:s}]}};if(u)R.Properties.KeyName=u;if(d)R.Properties.SecurityGroupIds=d;if(p)R.Properties.SubnetId=p;if(y)R.Properties.UserData=x.Base64(y);return R.Properties.BlockDeviceMappings=[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:h,VolumeType:b,Encrypted:v,DeleteOnTermination:!0}}],{instance:R,logicalId:T}}static createSecurityGroup(n){let{slug:i,environment:s,vpcId:o,description:c,ingress:u=[],egress:d=[]}=n,p=r({slug:i,environment:s,resourceType:"sg"}),y=t(p),h={Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:c||`Security group for ${i} ${s}`,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(o)h.Properties.VpcId=o;if(u.length>0)h.Properties.SecurityGroupIngress=u.map((b)=>({IpProtocol:b.protocol,FromPort:b.fromPort,ToPort:b.toPort,CidrIp:b.cidr,SourceSecurityGroupId:b.sourceSecurityGroupId}));if(d.length>0)h.Properties.SecurityGroupEgress=d.map((b)=>({IpProtocol:b.protocol,FromPort:b.fromPort,ToPort:b.toPort,CidrIp:b.cidr,DestinationSecurityGroupId:b.sourceSecurityGroupId}));return{securityGroup:h,logicalId:y}}static createWebServerSecurityGroup(n,i,s){return a.createSecurityGroup({slug:n,environment:i,vpcId:s,description:"Security group for web servers - HTTP, HTTPS, SSH",ingress:[{protocol:"tcp",fromPort:80,toPort:80,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:443,toPort:443,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:22,toPort:22,cidr:"0.0.0.0/0"}],egress:[{protocol:"-1",fromPort:0,toPort:0,cidr:"0.0.0.0/0"}]})}static createLoadBalancer(n){let{slug:i,environment:s,scheme:o="internet-facing",subnets:c,securityGroups:u,type:d="application"}=n,p=r({slug:i,environment:s,resourceType:"alb"}),y=t(p),h={Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:p,Scheme:o,Type:d,Subnets:c,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(u)h.Properties.SecurityGroups=u;return{loadBalancer:h,logicalId:y}}static createTargetGroup(n){let{slug:i,environment:s,port:o,protocol:c="HTTP",vpcId:u,targetType:d="ip",healthCheckPath:p="/",healthCheckInterval:y=30,healthCheckTimeout:h=5,healthyThreshold:b=2,unhealthyThreshold:v=3}=n,A=r({slug:i,environment:s,resourceType:"tg"}),T=t(A);return{targetGroup:{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:A,Port:o,Protocol:c,VpcId:u,TargetType:d,HealthCheckEnabled:!0,HealthCheckProtocol:c,HealthCheckPath:p,HealthCheckIntervalSeconds:y,HealthCheckTimeoutSeconds:h,HealthyThresholdCount:b,UnhealthyThresholdCount:v,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:s}]}},logicalId:T}}static createListener(n,i){let{port:s,protocol:o="HTTP",certificateArn:c,defaultTargetGroupArn:u}=i,d=t(`listener-${n}-${s}`),p={Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:x.Ref(n),Port:s,Protocol:o,DefaultActions:[{Type:"forward",TargetGroupArn:u}]}};if(o==="HTTPS"&&c)p.Properties.Certificates=[{CertificateArn:c}],p.Properties.SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06";return{listener:p,logicalId:d}}static createEcsCluster(n,i){let s=r({slug:n,environment:i,resourceType:"ecs-cluster"}),o=t(s);return{cluster:{Type:"AWS::ECS::Cluster",Properties:{ClusterName:s,Tags:[{Key:"Name",Value:s},{Key:"Environment",Value:i}]}},logicalId:o}}static createFargateService(n){let{slug:i,environment:s,image:o,cpu:c="256",memory:u="512",desiredCount:d=1,containerPort:p=8080,environmentVariables:y={},secrets:h=[],healthCheck:b,logGroup:v,subnets:A,securityGroups:T,targetGroupArn:R}=n,{cluster:P,logicalId:I}=a.createEcsCluster(i,s),M=r({slug:i,environment:s,resourceType:"fargate"}),L=t(`${M}-execution-role`),N={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]}},O=t(`${M}-task-role`),B={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]}}},F=t(`${M}-task`),U={Type:"AWS::ECS::TaskDefinition",Properties:{Family:M,TaskRoleArn:x.GetAtt(O,"Arn"),ExecutionRoleArn:x.GetAtt(L,"Arn"),NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:c,Memory:u,ContainerDefinitions:[{Name:i,Image:o,Essential:!0,PortMappings:[{ContainerPort:p,Protocol:"tcp"}],Environment:Object.entries(y).map(([z,ae])=>({Name:z,Value:ae})),Secrets:h.map((z)=>({Name:z.name,ValueFrom:z.valueFrom}))}],Tags:[{Key:"Name",Value:M},{Key:"Environment",Value:s}]}};if(b)U.Properties.ContainerDefinitions[0].HealthCheck={Command:b.command,Interval:b.interval||30,Timeout:b.timeout||5,Retries:b.retries||3,StartPeriod:60};if(v)U.Properties.ContainerDefinitions[0].LogConfiguration={LogDriver:"awslogs",Options:{"awslogs-group":v,"awslogs-region":x.Ref("AWS::Region"),"awslogs-stream-prefix":i}};let j=t(`${M}-service`),H={Type:"AWS::ECS::Service",Properties:{ServiceName:M,Cluster:x.Ref(I),TaskDefinition:x.Ref(F),DesiredCount:d,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{Subnets:A,SecurityGroups:T,AssignPublicIp:"ENABLED"}},Tags:[{Key:"Name",Value:M},{Key:"Environment",Value:s}]}};if(R)H.Properties.LoadBalancers=[{TargetGroupArn:R,ContainerName:i,ContainerPort:p}];return{cluster:P,taskDefinition:U,service:H,taskRole:B,executionRole:N,clusterLogicalId:I,taskDefinitionLogicalId:F,serviceLogicalId:j,taskRoleLogicalId:O,executionRoleLogicalId:L}}static createLambdaFunction(n){let{slug:i,environment:s,runtime:o,handler:c,code:u,timeout:d=30,memorySize:p=128,environmentVariables:y={},vpcConfig:h}=n,b=r({slug:i,environment:s,resourceType:"lambda"}),v=t(b),A=t(`${b}-role`),T={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}};if(h)T.Properties.ManagedPolicyArns.push("arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole");let R={Type:"AWS::Lambda::Function",Properties:{FunctionName:b,Runtime:o,Role:x.GetAtt(A,"Arn"),Handler:c,Code:{...u.s3Bucket&&{S3Bucket:u.s3Bucket},...u.s3Key&&{S3Key:u.s3Key},...u.zipFile&&{ZipFile:u.zipFile}},Timeout:d,MemorySize:p,Tags:[{Key:"Name",Value:b},{Key:"Environment",Value:s}]}};if(Object.keys(y).length>0)R.Properties.Environment={Variables:y};if(h)R.Properties.VpcConfig={SecurityGroupIds:h.securityGroupIds,SubnetIds:h.subnetIds};return{lambdaFunction:R,role:T,logicalId:v,roleLogicalId:A}}static generateNodeServerUserData(n={}){let{nodeVersion:i="20",appRepo:s,environment:o={}}=n,c=Object.entries(o).map(([u,d])=>`echo "export ${u}='${d}'" >> /etc/environment`).join(`
201
201
  `);return`#!/bin/bash
202
202
  # Update system
203
203
  yum update -y
@@ -298,7 +298,7 @@ systemctl enable caddy
298
298
  systemctl start caddy
299
299
 
300
300
  echo "Bun server setup complete!"
301
- `}static createLaunchConfiguration(n){let{slug:i,environment:s,imageId:o,instanceType:c,keyName:u,securityGroups:d,userData:p,volumeSize:y=20,volumeType:h="gp3",encrypted:b=!0,iamInstanceProfile:v}=n,A=r({slug:i,environment:s,resourceType:"launch-config"}),T=t(A),R={Type:"AWS::AutoScaling::LaunchConfiguration",Properties:{ImageId:o,InstanceType:c,BlockDeviceMappings:[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:y,VolumeType:h,Encrypted:b,DeleteOnTermination:!0}}]}};if(u)R.Properties.KeyName=u;if(d)R.Properties.SecurityGroups=d;if(p)R.Properties.UserData=x.Base64(p);if(v)R.Properties.IamInstanceProfile=v;return{launchConfiguration:R,logicalId:T}}static createAutoScalingGroup(n){let{slug:i,environment:s,launchConfigurationName:o,minSize:c,maxSize:u,desiredCapacity:d,vpcZoneIdentifier:p,targetGroupArns:y,healthCheckType:h="EC2",healthCheckGracePeriod:b=300,cooldown:v=300,tags:A={}}=n,T=r({slug:i,environment:s,resourceType:"asg"}),R=t(T),P={Type:"AWS::AutoScaling::AutoScalingGroup",Properties:{AutoScalingGroupName:T,LaunchConfigurationName:o,MinSize:c,MaxSize:u,HealthCheckType:h,HealthCheckGracePeriod:b,Cooldown:v,Tags:[{Key:"Name",Value:T,PropagateAtLaunch:!0},{Key:"Environment",Value:s,PropagateAtLaunch:!0},...Object.entries(A).map(([I,M])=>({Key:I,Value:M,PropagateAtLaunch:!0}))]}};if(d!==void 0)P.Properties.DesiredCapacity=d;if(p)P.Properties.VPCZoneIdentifier=p;if(y)P.Properties.TargetGroupARNs=y;return P.UpdatePolicy={AutoScalingRollingUpdate:{MaxBatchSize:1,MinInstancesInService:Math.max(0,c-1),PauseTime:"PT5M",WaitOnResourceSignals:!1}},{autoScalingGroup:P,logicalId:R}}static createScalingPolicy(n){let{slug:i,environment:s,autoScalingGroupName:o,policyType:c="TargetTrackingScaling",targetValue:u=70,predefinedMetricType:d="ASGAverageCPUUtilization"}=n,p=r({slug:i,environment:s,resourceType:"scaling-policy"}),y=t(p),h={Type:"AWS::AutoScaling::ScalingPolicy",Properties:{AutoScalingGroupName:o,PolicyType:c}};if(c==="TargetTrackingScaling")h.Properties.TargetTrackingConfiguration={PredefinedMetricSpecification:{PredefinedMetricType:d},TargetValue:u};return{scalingPolicy:h,logicalId:y}}static AutoScaling={smallWebServer:(n,i,s,o,c)=>a.createAutoScalingGroup({slug:n,environment:i,launchConfigurationName:s,minSize:2,maxSize:4,desiredCapacity:2,vpcZoneIdentifier:o,targetGroupArns:c,healthCheckType:c?"ELB":"EC2",healthCheckGracePeriod:300}),mediumWebServer:(n,i,s,o,c)=>a.createAutoScalingGroup({slug:n,environment:i,launchConfigurationName:s,minSize:3,maxSize:10,desiredCapacity:3,vpcZoneIdentifier:o,targetGroupArns:c,healthCheckType:c?"ELB":"EC2",healthCheckGracePeriod:300}),largeWebServer:(n,i,s,o,c)=>a.createAutoScalingGroup({slug:n,environment:i,launchConfigurationName:s,minSize:5,maxSize:20,desiredCapacity:5,vpcZoneIdentifier:o,targetGroupArns:c,healthCheckType:c?"ELB":"EC2",healthCheckGracePeriod:300}),cpuScaling:(n,i,s,o=70)=>a.createScalingPolicy({slug:n,environment:i,autoScalingGroupName:s,policyType:"TargetTrackingScaling",predefinedMetricType:"ASGAverageCPUUtilization",targetValue:o}),requestCountScaling:(n,i,s,o=1000)=>a.createScalingPolicy({slug:n,environment:i,autoScalingGroupName:s,policyType:"TargetTrackingScaling",predefinedMetricType:"ALBRequestCountPerTarget",targetValue:o})};static Secrets={fromSecretsManager:(n)=>Object.entries(n).map(([i,s])=>({name:i,valueFrom:s})),fromJsonSecret:(n,i)=>`${n}:${i}::`,fromSecretVersion:(n,i)=>`${n}::${i}:`,fromSecretVersionStage:(n,i)=>`${n}:::${i}`,createAccessPolicy:(n)=>({PolicyName:"SecretsManagerAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],Resource:n}]}}),createKmsPolicy:(n)=>({PolicyName:"KMSDecryptAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["kms:Decrypt"],Resource:n}]}}),buildSecretArn:(n)=>`arn:aws:secretsmanager:${n.region}:${n.accountId}:secret:${n.secretName}`,buildSecretArnPattern:(n)=>{let i=n.region||"*",s=n.accountId||"*";return`arn:aws:secretsmanager:${i}:${s}:secret:${n.secretNamePrefix}*`},commonAppSecrets:(n)=>({DATABASE_URL:`${n}/database-url`,DATABASE_PASSWORD:`${n}/database-password`,REDIS_URL:`${n}/redis-url`,REDIS_PASSWORD:`${n}/redis-password`,API_KEY:`${n}/api-key`,JWT_SECRET:`${n}/jwt-secret`,ENCRYPTION_KEY:`${n}/encryption-key`,AWS_ACCESS_KEY_ID:`${n}/aws-access-key-id`,AWS_SECRET_ACCESS_KEY:`${n}/aws-secret-access-key`,MAIL_PASSWORD:`${n}/mail-password`,STRIPE_SECRET_KEY:`${n}/stripe-secret-key`,STRIPE_WEBHOOK_SECRET:`${n}/stripe-webhook-secret`})};static createFargateServiceWithSecrets(n){let{secretArns:i=[],kmsKeyArns:s=[],...o}=n,c=a.createFargateService(o);if(i.length>0){if(!c.executionRole.Properties.Policies)c.executionRole.Properties.Policies=[];if(c.executionRole.Properties.Policies.push(a.Secrets.createAccessPolicy(i)),s.length>0)c.executionRole.Properties.Policies.push(a.Secrets.createKmsPolicy(s))}return c}static generateSecretReferences(n){return n.secrets.map((i)=>{let s=`arn:aws:secretsmanager:${n.region}:${n.accountId}:secret:${n.secretPrefix}/${i}`;return{name:i.toUpperCase().replace(/-/g,"_"),valueFrom:s}})}static EnvSecrets={database:(n)=>[{name:"DB_HOST",valueFrom:`${n}:host::`},{name:"DB_PORT",valueFrom:`${n}:port::`},{name:"DB_USERNAME",valueFrom:`${n}:username::`},{name:"DB_PASSWORD",valueFrom:`${n}:password::`},{name:"DB_NAME",valueFrom:`${n}:dbname::`}],redis:(n)=>[{name:"REDIS_HOST",valueFrom:`${n}:host::`},{name:"REDIS_PORT",valueFrom:`${n}:port::`},{name:"REDIS_PASSWORD",valueFrom:`${n}:password::`}],apiCredentials:(n)=>[{name:"API_KEY",valueFrom:`${n}:apiKey::`},{name:"API_SECRET",valueFrom:`${n}:apiSecret::`}],mail:(n)=>[{name:"MAIL_HOST",valueFrom:`${n}:host::`},{name:"MAIL_PORT",valueFrom:`${n}:port::`},{name:"MAIL_USERNAME",valueFrom:`${n}:username::`},{name:"MAIL_PASSWORD",valueFrom:`${n}:password::`}],awsCredentials:(n)=>[{name:"AWS_ACCESS_KEY_ID",valueFrom:`${n}:accessKeyId::`},{name:"AWS_SECRET_ACCESS_KEY",valueFrom:`${n}:secretAccessKey::`}]};static createJumpBox(n){let{slug:i,environment:s,vpcId:o,subnetId:c,keyName:u,instanceType:d="t3.micro",imageId:p=Dm(d),mountEfs:y,databaseTools:h=!1}=n,b=n.allowedCidrs??(u?["0.0.0.0/0"]:[]),v=r({slug:i,environment:s,resourceType:"jumpbox"}),A=t(`${v}-sg`),T={Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:`${v}-sg`,GroupDescription:`Security group for ${v} JumpBox access`,VpcId:o,SecurityGroupIngress:b.map((F)=>({IpProtocol:"tcp",FromPort:22,ToPort:22,CidrIp:F,Description:`SSH access from ${F}`})),SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound traffic"}],Tags:[{Key:"Name",Value:`${v}-sg`},{Key:"Environment",Value:s}]}},R=t(`${v}-role`),P={Type:"AWS::IAM::Role",Properties:{RoleName:`${v}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"],Policies:y?[{PolicyName:"EFSAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:ClientRootAccess"],Resource:"*"}]}}]:void 0}},I=t(`${v}-profile`),M={Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:`${v}-profile`,Roles:[x.Ref(R)]}},L=`#!/bin/bash
301
+ `}static createLaunchConfiguration(n){let{slug:i,environment:s,imageId:o,instanceType:c,keyName:u,securityGroups:d,userData:p,volumeSize:y=20,volumeType:h="gp3",encrypted:b=!0,iamInstanceProfile:v}=n,A=r({slug:i,environment:s,resourceType:"launch-config"}),T=t(A),R={Type:"AWS::AutoScaling::LaunchConfiguration",Properties:{ImageId:o,InstanceType:c,BlockDeviceMappings:[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:y,VolumeType:h,Encrypted:b,DeleteOnTermination:!0}}]}};if(u)R.Properties.KeyName=u;if(d)R.Properties.SecurityGroups=d;if(p)R.Properties.UserData=x.Base64(p);if(v)R.Properties.IamInstanceProfile=v;return{launchConfiguration:R,logicalId:T}}static createAutoScalingGroup(n){let{slug:i,environment:s,launchConfigurationName:o,minSize:c,maxSize:u,desiredCapacity:d,vpcZoneIdentifier:p,targetGroupArns:y,healthCheckType:h="EC2",healthCheckGracePeriod:b=300,cooldown:v=300,tags:A={}}=n,T=r({slug:i,environment:s,resourceType:"asg"}),R=t(T),P={Type:"AWS::AutoScaling::AutoScalingGroup",Properties:{AutoScalingGroupName:T,LaunchConfigurationName:o,MinSize:c,MaxSize:u,HealthCheckType:h,HealthCheckGracePeriod:b,Cooldown:v,Tags:[{Key:"Name",Value:T,PropagateAtLaunch:!0},{Key:"Environment",Value:s,PropagateAtLaunch:!0},...Object.entries(A).map(([I,M])=>({Key:I,Value:M,PropagateAtLaunch:!0}))]}};if(d!==void 0)P.Properties.DesiredCapacity=d;if(p)P.Properties.VPCZoneIdentifier=p;if(y)P.Properties.TargetGroupARNs=y;return P.UpdatePolicy={AutoScalingRollingUpdate:{MaxBatchSize:1,MinInstancesInService:Math.max(0,c-1),PauseTime:"PT5M",WaitOnResourceSignals:!1}},{autoScalingGroup:P,logicalId:R}}static createScalingPolicy(n){let{slug:i,environment:s,autoScalingGroupName:o,policyType:c="TargetTrackingScaling",targetValue:u=70,predefinedMetricType:d="ASGAverageCPUUtilization"}=n,p=r({slug:i,environment:s,resourceType:"scaling-policy"}),y=t(p),h={Type:"AWS::AutoScaling::ScalingPolicy",Properties:{AutoScalingGroupName:o,PolicyType:c}};if(c==="TargetTrackingScaling")h.Properties.TargetTrackingConfiguration={PredefinedMetricSpecification:{PredefinedMetricType:d},TargetValue:u};return{scalingPolicy:h,logicalId:y}}static AutoScaling={smallWebServer:(n,i,s,o,c)=>a.createAutoScalingGroup({slug:n,environment:i,launchConfigurationName:s,minSize:2,maxSize:4,desiredCapacity:2,vpcZoneIdentifier:o,targetGroupArns:c,healthCheckType:c?"ELB":"EC2",healthCheckGracePeriod:300}),mediumWebServer:(n,i,s,o,c)=>a.createAutoScalingGroup({slug:n,environment:i,launchConfigurationName:s,minSize:3,maxSize:10,desiredCapacity:3,vpcZoneIdentifier:o,targetGroupArns:c,healthCheckType:c?"ELB":"EC2",healthCheckGracePeriod:300}),largeWebServer:(n,i,s,o,c)=>a.createAutoScalingGroup({slug:n,environment:i,launchConfigurationName:s,minSize:5,maxSize:20,desiredCapacity:5,vpcZoneIdentifier:o,targetGroupArns:c,healthCheckType:c?"ELB":"EC2",healthCheckGracePeriod:300}),cpuScaling:(n,i,s,o=70)=>a.createScalingPolicy({slug:n,environment:i,autoScalingGroupName:s,policyType:"TargetTrackingScaling",predefinedMetricType:"ASGAverageCPUUtilization",targetValue:o}),requestCountScaling:(n,i,s,o=1000)=>a.createScalingPolicy({slug:n,environment:i,autoScalingGroupName:s,policyType:"TargetTrackingScaling",predefinedMetricType:"ALBRequestCountPerTarget",targetValue:o})};static Secrets={fromSecretsManager:(n)=>Object.entries(n).map(([i,s])=>({name:i,valueFrom:s})),fromJsonSecret:(n,i)=>`${n}:${i}::`,fromSecretVersion:(n,i)=>`${n}::${i}:`,fromSecretVersionStage:(n,i)=>`${n}:::${i}`,createAccessPolicy:(n)=>({PolicyName:"SecretsManagerAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],Resource:n}]}}),createKmsPolicy:(n)=>({PolicyName:"KMSDecryptAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["kms:Decrypt"],Resource:n}]}}),buildSecretArn:(n)=>`arn:aws:secretsmanager:${n.region}:${n.accountId}:secret:${n.secretName}`,buildSecretArnPattern:(n)=>{let i=n.region||"*",s=n.accountId||"*";return`arn:aws:secretsmanager:${i}:${s}:secret:${n.secretNamePrefix}*`},commonAppSecrets:(n)=>({DATABASE_URL:`${n}/database-url`,DATABASE_PASSWORD:`${n}/database-password`,REDIS_URL:`${n}/redis-url`,REDIS_PASSWORD:`${n}/redis-password`,API_KEY:`${n}/api-key`,JWT_SECRET:`${n}/jwt-secret`,ENCRYPTION_KEY:`${n}/encryption-key`,AWS_ACCESS_KEY_ID:`${n}/aws-access-key-id`,AWS_SECRET_ACCESS_KEY:`${n}/aws-secret-access-key`,MAIL_PASSWORD:`${n}/mail-password`,STRIPE_SECRET_KEY:`${n}/stripe-secret-key`,STRIPE_WEBHOOK_SECRET:`${n}/stripe-webhook-secret`})};static createFargateServiceWithSecrets(n){let{secretArns:i=[],kmsKeyArns:s=[],...o}=n,c=a.createFargateService(o);if(i.length>0){if(!c.executionRole.Properties.Policies)c.executionRole.Properties.Policies=[];if(c.executionRole.Properties.Policies.push(a.Secrets.createAccessPolicy(i)),s.length>0)c.executionRole.Properties.Policies.push(a.Secrets.createKmsPolicy(s))}return c}static generateSecretReferences(n){return n.secrets.map((i)=>{let s=`arn:aws:secretsmanager:${n.region}:${n.accountId}:secret:${n.secretPrefix}/${i}`;return{name:i.toUpperCase().replace(/-/g,"_"),valueFrom:s}})}static EnvSecrets={database:(n)=>[{name:"DB_HOST",valueFrom:`${n}:host::`},{name:"DB_PORT",valueFrom:`${n}:port::`},{name:"DB_USERNAME",valueFrom:`${n}:username::`},{name:"DB_PASSWORD",valueFrom:`${n}:password::`},{name:"DB_NAME",valueFrom:`${n}:dbname::`}],redis:(n)=>[{name:"REDIS_HOST",valueFrom:`${n}:host::`},{name:"REDIS_PORT",valueFrom:`${n}:port::`},{name:"REDIS_PASSWORD",valueFrom:`${n}:password::`}],apiCredentials:(n)=>[{name:"API_KEY",valueFrom:`${n}:apiKey::`},{name:"API_SECRET",valueFrom:`${n}:apiSecret::`}],mail:(n)=>[{name:"MAIL_HOST",valueFrom:`${n}:host::`},{name:"MAIL_PORT",valueFrom:`${n}:port::`},{name:"MAIL_USERNAME",valueFrom:`${n}:username::`},{name:"MAIL_PASSWORD",valueFrom:`${n}:password::`}],awsCredentials:(n)=>[{name:"AWS_ACCESS_KEY_ID",valueFrom:`${n}:accessKeyId::`},{name:"AWS_SECRET_ACCESS_KEY",valueFrom:`${n}:secretAccessKey::`}]};static createJumpBox(n){let{slug:i,environment:s,vpcId:o,subnetId:c,keyName:u,instanceType:d="t3.micro",imageId:p=Pm(d),mountEfs:y,databaseTools:h=!1}=n,b=n.allowedCidrs??(u?["0.0.0.0/0"]:[]),v=r({slug:i,environment:s,resourceType:"jumpbox"}),A=t(`${v}-sg`),T={Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:`${v}-sg`,GroupDescription:`Security group for ${v} JumpBox access`,VpcId:o,SecurityGroupIngress:b.map((F)=>({IpProtocol:"tcp",FromPort:22,ToPort:22,CidrIp:F,Description:`SSH access from ${F}`})),SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound traffic"}],Tags:[{Key:"Name",Value:`${v}-sg`},{Key:"Environment",Value:s}]}},R=t(`${v}-role`),P={Type:"AWS::IAM::Role",Properties:{RoleName:`${v}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"],Policies:y?[{PolicyName:"EFSAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:ClientRootAccess"],Resource:"*"}]}}]:void 0}},I=t(`${v}-profile`),M={Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:`${v}-profile`,Roles:[x.Ref(R)]}},L=`#!/bin/bash
302
302
  dnf install -y amazon-efs-utils nfs-utils jq wget htop
303
303
  `;if(h)L+=`
304
304
  # Database clients: psql, mysql (MariaDB), redis-cli
@@ -1668,7 +1668,7 @@ catch (error) {
1668
1668
  }
1669
1669
 
1670
1670
  run()
1671
- `}static async generateJobManifest(n){let i=await kt.discoverJobs(n),s=i.filter((o)=>o.schedule&&o.enabled);return{jobs:i,scheduledCount:s.length,totalCount:i.length}}}var KI={loadJobs:kt.discoverJobs,loadActions:kt.discoverActions,generateScheduledJobs:kt.generateScheduledJobResources,generateRunner:kt.generateJobRunnerScript,paths:{jobs:"app/Jobs",actions:"app/Actions",runner:"app/Jobs/runner.ts"}};var sn=`
1671
+ `}static async generateJobManifest(n){let i=await kt.discoverJobs(n),s=i.filter((o)=>o.schedule&&o.enabled);return{jobs:i,scheduledCount:s.length,totalCount:i.length}}}var WI={loadJobs:kt.discoverJobs,loadActions:kt.discoverActions,generateScheduledJobs:kt.generateScheduledJobResources,generateRunner:kt.generateJobRunnerScript,paths:{jobs:"app/Jobs",actions:"app/Actions",runner:"app/Jobs/runner.ts"}};var sn=`
1672
1672
  const { DynamoDBClient, UpdateItemCommand } = require('@aws-sdk/client-dynamodb');
1673
1673
  const { SNSClient, PublishCommand } = require('@aws-sdk/client-sns');
1674
1674
 
@@ -2271,7 +2271,7 @@ function resolveTemplate(template, data) {
2271
2271
  }
2272
2272
  return result;
2273
2273
  }
2274
- `;class X{static LambdaCode={send:Ct,receive:on,deliveryStatus:sn};static createPinpointApp(n){return{[`${n.slug}PinpointApp`]:{Type:"AWS::Pinpoint::App",Properties:{Name:n.name||`${n.slug}-sms`}}}}static createSmsChannel(n){let i={ApplicationId:n.applicationId,Enabled:n.enabled!==!1};if(n.senderId)i.SenderId=n.senderId;if(n.shortCode)i.ShortCode=n.shortCode;return{[`${n.slug}SmsChannel`]:{Type:"AWS::Pinpoint::SMSChannel",Properties:i}}}static createSmsLambdaRole(n){return{[`${n.slug}SmsLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${n.slug}-sms-lambda-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"SmsLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["mobiletargeting:SendMessages","mobiletargeting:GetSmsChannel"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem","dynamodb:DeleteItem"],Resource:"*"}]}}]}}}}static createSendLambda(n){return{[`${n.slug}SmsSendLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-sms-send`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:X.LambdaCode.send},Environment:{Variables:{PINPOINT_APP_ID:n.pinpointAppId,MESSAGE_LOG_TABLE:n.messageLogTable||"",SMS_SENDER_ID:n.senderId||"",SMS_ORIGINATION_NUMBER:n.originationNumber||""}}}}}}static createReceiveLambda(n){return{[`${n.slug}SmsReceiveLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-sms-receive`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:X.LambdaCode.receive},Environment:{Variables:{OPT_OUT_TABLE:n.optOutTable||"",MESSAGE_LOG_TABLE:n.messageLogTable||"",NOTIFICATION_TOPIC_ARN:n.notificationTopicArn||"",WEBHOOK_URL:n.webhookUrl||""}}}}}}static createDeliveryStatusLambda(n){return{[`${n.slug}SmsDeliveryStatusLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-sms-delivery-status`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:X.LambdaCode.deliveryStatus},Environment:{Variables:{MESSAGE_LOG_TABLE:n.messageLogTable||"",NOTIFICATION_TOPIC_ARN:n.notificationTopicArn||"",WEBHOOK_URL:n.webhookUrl||""}}}}}}static createMessageLogTable(n){return{[`${n.slug}SmsMessageLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${n.slug}-sms-messages`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"messageId",AttributeType:"S"}],KeySchema:[{AttributeName:"messageId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createOptOutTable(n){return{[`${n.slug}SmsOptOutTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${n.slug}-sms-optouts`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"phoneNumber",AttributeType:"S"}],KeySchema:[{AttributeName:"phoneNumber",KeyType:"HASH"}]}}}}static createNotificationTopic(n){return{[`${n.slug}SmsNotificationTopic`]:{Type:"AWS::SNS::Topic",Properties:{TopicName:`${n.slug}-sms-notifications`}}}}static createCompleteSetup(n){let i={},s={};Object.assign(i,X.createPinpointApp({slug:n.slug})),Object.assign(i,X.createSmsChannel({slug:n.slug,applicationId:{Ref:`${n.slug}PinpointApp`},senderId:n.senderId})),Object.assign(i,X.createSmsLambdaRole({slug:n.slug})),Object.assign(i,X.createMessageLogTable({slug:n.slug})),Object.assign(i,X.createOptOutTable({slug:n.slug})),Object.assign(i,X.createNotificationTopic({slug:n.slug}));let o={"Fn::GetAtt":[`${n.slug}SmsLambdaRole`,"Arn"]},c={Ref:`${n.slug}PinpointApp`},u={Ref:`${n.slug}SmsMessageLogTable`},d={Ref:`${n.slug}SmsOptOutTable`},p={Ref:`${n.slug}SmsNotificationTopic`};if(Object.assign(i,X.createSendLambda({slug:n.slug,roleArn:o,pinpointAppId:c,messageLogTable:u,senderId:n.senderId,originationNumber:n.originationNumber})),n.twoWayEnabled)Object.assign(i,X.createReceiveLambda({slug:n.slug,roleArn:o,optOutTable:d,messageLogTable:u,notificationTopicArn:p,webhookUrl:n.webhookUrl}));return Object.assign(i,X.createDeliveryStatusLambda({slug:n.slug,roleArn:o,messageLogTable:u,notificationTopicArn:p,webhookUrl:n.webhookUrl})),s[`${n.slug}PinpointAppId`]={Description:"Pinpoint application ID",Value:{Ref:`${n.slug}PinpointApp`}},s[`${n.slug}SmsSendLambdaArn`]={Description:"SMS send Lambda ARN",Value:{"Fn::GetAtt":[`${n.slug}SmsSendLambda`,"Arn"]}},s[`${n.slug}SmsNotificationTopicArn`]={Description:"SMS notification topic ARN",Value:{Ref:`${n.slug}SmsNotificationTopic`}},s[`${n.slug}SmsMessageLogTableName`]={Description:"SMS message log table name",Value:{Ref:`${n.slug}SmsMessageLogTable`}},{resources:i,outputs:s}}}function vt(n){return n.replace(/[^a-zA-Z0-9]/g," ").trim().split(/\s+/).map((o)=>o.charAt(0).toUpperCase()+o.slice(1)).join("")||"User"}function Er(n,i){let s=(n||i).replace(/^\/+|\/+$/g,"");if(!s||s.split("/").includes(".."))throw Error(`sftp: invalid homeDirectory for user ${i}`);return s}function wr(n){let i=n.storage;if(i?.type==="efs"){let o="fileSystemId"in i?i.fileSystemId:void 0;if(!o||typeof o==="string"&&!o.trim())throw Error("sftp: EFS storage requires fileSystemId, or a fileSystem name defined in infrastructure.fileSystem");return{type:"efs",fileSystemId:o,posixProfile:i.posixProfile}}let s=(i?.type==="s3"?i.bucket??n.bucket:n.bucket)?.trim();if(!s)throw Error("sftp: S3 storage requires bucket, or a storageBucket name defined in infrastructure.storage");return{type:"s3",bucket:s}}function Ir(n,i,s){let o=i.posixProfile??s;if(!o)throw Error(`sftp: user ${n} requires a posixProfile (uid/gid) on an EFS-backed server`);for(let c of[o.uid,o.gid,...o.secondaryGids??[]])if(!Number.isInteger(c)||c<0||c>4294967295)throw Error(`sftp: user ${n} has an invalid posixProfile id ${c}`);return{Uid:o.uid,Gid:o.gid,...o.secondaryGids?.length?{SecondaryGids:o.secondaryGids}:{}}}function Dr(n,i){return typeof n==="string"?`/${n}/${i}`:{"Fn::Sub":[`/\${FileSystemId}/${i}`,{FileSystemId:n}]}}function Nr(n){return typeof n==="string"?{"Fn::Sub":"arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/${FileSystemId}".replace("${FileSystemId}",n)}:{"Fn::Sub":["arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/${FileSystemId}",{FileSystemId:n}]}}class pl{static create(n){let i=wr(n),s=i.type==="efs"?"EFS":"S3",o=n.endpointType??"PUBLIC";if(o==="VPC"&&(!n.endpointDetails?.vpcId||!n.endpointDetails.subnetIds.length))throw Error("sftp: VPC endpoints require endpointDetails.vpcId and at least one subnet");let c=`${vt(n.slug)}${vt(n.environment)}Sftp`,u=`${c}Server`,d={},p;if(n.logging!==!1){let y=`${c}LoggingRole`;d[y]={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"transfer.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"TransferLogging",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogGroup","logs:CreateLogStream","logs:DescribeLogStreams","logs:PutLogEvents"],Resource:"arn:aws:logs:*:*:log-group:/aws/transfer/*"}]}}]}},p={"Fn::GetAtt":[y,"Arn"]}}d[u]={Type:"AWS::Transfer::Server",Properties:{Domain:s,EndpointType:o,IdentityProviderType:"SERVICE_MANAGED",Protocols:["SFTP"],...o==="VPC"?{EndpointDetails:{VpcId:n.endpointDetails.vpcId,SubnetIds:n.endpointDetails.subnetIds,...n.endpointDetails.securityGroupIds?.length?{SecurityGroupIds:n.endpointDetails.securityGroupIds}:{},...n.endpointDetails.addressAllocationIds?.length?{AddressAllocationIds:n.endpointDetails.addressAllocationIds}:{}}}:{},...n.securityPolicyName?{SecurityPolicyName:n.securityPolicyName}:{},...p?{LoggingRole:p}:{},Tags:[{Key:"Project",Value:n.slug},{Key:"Environment",Value:n.environment},{Key:"ManagedBy",Value:"ts-cloud"}]}};for(let[y,h]of Object.entries(n.users)){if(!/^[a-zA-Z0-9_.@-]{3,100}$/.test(y))throw Error(`sftp: invalid username ${y}`);if(!h.sshPublicKeys.length)throw Error(`sftp: user ${y} requires at least one SSH public key`);let b=vt(y),v=Er(h.homeDirectory,y),A=`${c}${b}User`,T=h.roleArn;if(!T){let R=`${c}${b}Role`,P;if(i.type==="efs")P=[{Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:DescribeMountTargets"],Resource:Nr(i.fileSystemId)}];else{let I=`arn:aws:s3:::${i.bucket}`;P=[{Effect:"Allow",Action:["s3:ListBucket","s3:GetBucketLocation"],Resource:I,Condition:{StringLike:{"s3:prefix":[v,`${v}/*`]}}},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:GetObjectVersion"],Resource:`${I}/${v}/*`}]}d[R]={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"transfer.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"SftpHomeDirectory",PolicyDocument:{Version:"2012-10-17",Statement:P}}]}},T={"Fn::GetAtt":[R,"Arn"]}}d[A]={Type:"AWS::Transfer::User",DependsOn:[u],Properties:{ServerId:{Ref:u},UserName:y,Role:T,HomeDirectoryType:"PATH",HomeDirectory:i.type==="efs"?Dr(i.fileSystemId,v):`/${i.bucket}/${v}`,...i.type==="efs"?{PosixProfile:Ir(y,h,i.posixProfile)}:{},SshPublicKeys:h.sshPublicKeys}}}return{resources:d,serverLogicalId:u,domain:s}}}class Oe{static createBedrockRole(n,i){let{slug:s,environment:o,name:c,models:u=["*"],allowStreaming:d=!0}=i,p=c||r({slug:s,environment:o,resourceType:"bedrock-role"}),y=t(p),h=["bedrock:InvokeModel"];if(d)h.push("bedrock:InvokeModelWithResponseStream");let b=u.map((A)=>A==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${A}`);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:p,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:n},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:`${p}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:h,Resource:b}]}}],Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:o}]}},logicalId:y}}static createBedrockPolicy(n){let{slug:i,environment:s,name:o,models:c=["*"],allowInvoke:u=!0,allowStreaming:d=!0,allowAsync:p=!1}=n,y=o||r({slug:i,environment:s,resourceType:"bedrock-policy"}),h=t(y),b=[];if(u)b.push("bedrock:InvokeModel");if(d)b.push("bedrock:InvokeModelWithResponseStream");if(p)b.push("bedrock:InvokeModelAsync");let v=c.map((T)=>T==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${T}`);return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:y,PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"BedrockModelInvocation",Effect:"Allow",Action:b,Resource:v}]}}},logicalId:h}}static enableBedrockForLambda(n){return Oe.createBedrockRole("lambda.amazonaws.com",n)}static enableBedrockForEcs(n){return Oe.createBedrockRole("ecs-tasks.amazonaws.com",n)}static enableBedrockForEc2(n){return Oe.createBedrockRole("ec2.amazonaws.com",n)}static addBedrockPermissions(n,i=["*"],s=!0){let o=["bedrock:InvokeModel"];if(s)o.push("bedrock:InvokeModelWithResponseStream");let c=i.map((u)=>u==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${u}`);if(!n.Properties.Policies)n.Properties.Policies=[];return n.Properties.Policies.push({PolicyName:"bedrock-permissions",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:o,Resource:c}]}}),n}static Models={Claude3_5_Sonnet:"anthropic.claude-3-5-sonnet-20241022-v2:0",Claude3_5_Haiku:"anthropic.claude-3-5-haiku-20241022-v1:0",Claude3_Opus:"anthropic.claude-3-opus-20240229-v1:0",Claude3_Sonnet:"anthropic.claude-3-sonnet-20240229-v1:0",Claude3_Haiku:"anthropic.claude-3-haiku-20240307-v1:0",TitanTextG1Express:"amazon.titan-text-express-v1",TitanTextG1Lite:"amazon.titan-text-lite-v1",TitanEmbedG1Text:"amazon.titan-embed-text-v1",TitanImageG1:"amazon.titan-image-generator-v1",JurassicUltra:"ai21.j2-ultra-v1",JurassicMid:"ai21.j2-mid-v1",CommandText:"cohere.command-text-v14",CommandLight:"cohere.command-light-text-v14",EmbedEnglish:"cohere.embed-english-v3",EmbedMultilingual:"cohere.embed-multilingual-v3",Llama3_2_1B:"meta.llama3-2-1b-instruct-v1:0",Llama3_2_3B:"meta.llama3-2-3b-instruct-v1:0",Llama3_2_11B:"meta.llama3-2-11b-instruct-v1:0",Llama3_2_90B:"meta.llama3-2-90b-instruct-v1:0",Llama3_1_8B:"meta.llama3-1-8b-instruct-v1:0",Llama3_1_70B:"meta.llama3-1-70b-instruct-v1:0",Llama3_1_405B:"meta.llama3-1-405b-instruct-v1:0",Mistral7B:"mistral.mistral-7b-instruct-v0:2",Mixtral8x7B:"mistral.mixtral-8x7b-instruct-v0:1",MistralLarge:"mistral.mistral-large-2402-v1:0",StableDiffusionXL:"stability.stable-diffusion-xl-v1"};static ModelGroups={AllClaude:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","anthropic.claude-3-opus-20240229-v1:0","anthropic.claude-3-sonnet-20240229-v1:0","anthropic.claude-3-haiku-20240307-v1:0"],AllTitan:["amazon.titan-text-express-v1","amazon.titan-text-lite-v1","amazon.titan-embed-text-v1","amazon.titan-image-generator-v1"],AllLlama:["meta.llama3-2-1b-instruct-v1:0","meta.llama3-2-3b-instruct-v1:0","meta.llama3-2-11b-instruct-v1:0","meta.llama3-2-90b-instruct-v1:0","meta.llama3-1-8b-instruct-v1:0","meta.llama3-1-70b-instruct-v1:0","meta.llama3-1-405b-instruct-v1:0"],TextModels:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","amazon.titan-text-express-v1","meta.llama3-2-11b-instruct-v1:0","mistral.mistral-7b-instruct-v0:2"],EmbeddingModels:["amazon.titan-embed-text-v1","cohere.embed-english-v3","cohere.embed-multilingual-v3"],ImageModels:["amazon.titan-image-generator-v1","stability.stable-diffusion-xl-v1"]}}class lr{static createPostgres(n){return lr.createRDSInstance("postgres","16.2",n)}static createMysql(n){return lr.createRDSInstance("mysql","8.0.35",n)}static createRDSInstance(n,i,s){let{slug:o,environment:c,instanceClass:u="db.t3.micro",allocatedStorage:d=20,storageType:p="gp3",masterUsername:y="admin",masterPassword:h,databaseName:b,subnetIds:v,securityGroupIds:A,encrypted:T=!0,kmsKeyId:R,multiAz:P=!1,backupRetentionDays:I=7,publiclyAccessible:M=!1,enableCloudwatchLogs:L=!0,deletionProtection:N=!0}=s,O=r({slug:o,environment:c,resourceType:`${n}-db`}),B=t(O),F,U;if(v&&v.length>0){let H=r({slug:o,environment:c,resourceType:"db-subnet-group"});U=t(H),F={Type:"AWS::RDS::DBSubnetGroup",Properties:{DBSubnetGroupName:H,DBSubnetGroupDescription:`Subnet group for ${O}`,SubnetIds:v,Tags:[{Key:"Name",Value:H},{Key:"Environment",Value:c}]}}}let j={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:O,DBInstanceClass:u,Engine:n,EngineVersion:i,MasterUsername:y,MasterUserPassword:h,AllocatedStorage:d,StorageType:p,StorageEncrypted:T,MultiAZ:P,BackupRetentionPeriod:I,PubliclyAccessible:M,DeletionProtection:N,Tags:[{Key:"Name",Value:O},{Key:"Environment",Value:c}]}};if(b)j.Properties.DBName=b;if(R)j.Properties.KmsKeyId=R;if(U)j.Properties.DBSubnetGroupName=x.Ref(U);if(A&&A.length>0)j.Properties.VPCSecurityGroups=A;if(L)j.Properties.EnableCloudwatchLogsExports=n==="postgres"?["postgresql"]:["error","general","slowquery"];return{dbInstance:j,subnetGroup:F,logicalId:B,subnetGroupId:U}}static createReadReplica(n,i){let{slug:s,environment:o,instanceClass:c="db.t3.micro",securityGroupIds:u,publiclyAccessible:d=!1}=i,p=r({slug:s,environment:o,resourceType:"db-replica"}),y=t(p),h={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:p,DBInstanceClass:c,SourceDBInstanceIdentifier:x.Ref(n),PubliclyAccessible:d,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:o},{Key:"Type",Value:"ReadReplica"}]}};if(u&&u.length>0)h.Properties.VPCSecurityGroups=u;return{replica:h,logicalId:y}}static createParameterGroup(n,i,s){let{slug:o,environment:c,parameters:u={}}=s,d=r({slug:o,environment:c,resourceType:"db-params"}),p=t(d),y=n==="postgres"?`postgres${i.split(".")[0]}`:`mysql${i.split(".")[0]}.${i.split(".")[1]}`;return{parameterGroup:{Type:"AWS::RDS::DBParameterGroup",Properties:{DBParameterGroupName:d,Description:`Parameter group for ${d}`,Family:y,Parameters:u,Tags:[{Key:"Name",Value:d},{Key:"Environment",Value:c}]}},logicalId:p}}static enableBackup(n,i=7){return n.Properties.BackupRetentionPeriod=i,n}static createTable(n){let{slug:i,environment:s,tableName:o,partitionKey:c,sortKey:u,billingMode:d="PAY_PER_REQUEST",readCapacity:p=5,writeCapacity:y=5,streamEnabled:h=!1,streamViewType:b="NEW_AND_OLD_IMAGES",encrypted:v=!0,kmsKeyId:A,pointInTimeRecovery:T=!0,ttlAttribute:R}=n,P=o||r({slug:i,environment:s,resourceType:"table"}),I=t(P),M=[{AttributeName:c.name,AttributeType:c.type}];if(u)M.push({AttributeName:u.name,AttributeType:u.type});let L=[{AttributeName:c.name,KeyType:"HASH"}];if(u)L.push({AttributeName:u.name,KeyType:"RANGE"});let N={Type:"AWS::DynamoDB::Table",Properties:{TableName:P,BillingMode:d,AttributeDefinitions:M,KeySchema:L,Tags:[{Key:"Name",Value:P},{Key:"Environment",Value:s}]}};if(d==="PROVISIONED")N.Properties.ProvisionedThroughput={ReadCapacityUnits:p,WriteCapacityUnits:y};if(h)N.Properties.StreamSpecification={StreamViewType:b};if(v)N.Properties.SSESpecification={SSEEnabled:!0,SSEType:A?"KMS":"AES256",KMSMasterKeyId:A};if(T)N.Properties.PointInTimeRecoverySpecification={PointInTimeRecoveryEnabled:!0};if(R)N.Properties.TimeToLiveSpecification={AttributeName:R,Enabled:!0};return{table:N,logicalId:I}}static addGlobalSecondaryIndex(n,i){let{indexName:s,partitionKey:o,sortKey:c,projectionType:u="ALL",nonKeyAttributes:d,readCapacity:p=5,writeCapacity:y=5}=i;if(!n.Properties.AttributeDefinitions.some((v)=>v.AttributeName===o.name))n.Properties.AttributeDefinitions.push({AttributeName:o.name,AttributeType:o.type});if(c&&!n.Properties.AttributeDefinitions.some((v)=>v.AttributeName===c.name))n.Properties.AttributeDefinitions.push({AttributeName:c.name,AttributeType:c.type});let h=[{AttributeName:o.name,KeyType:"HASH"}];if(c)h.push({AttributeName:c.name,KeyType:"RANGE"});let b={IndexName:s,KeySchema:h,Projection:{ProjectionType:u,NonKeyAttributes:u==="INCLUDE"?d:void 0},ProvisionedThroughput:void 0};if(n.Properties.BillingMode==="PROVISIONED")b.ProvisionedThroughput={ReadCapacityUnits:p,WriteCapacityUnits:y};if(!n.Properties.GlobalSecondaryIndexes)n.Properties.GlobalSecondaryIndexes=[];return n.Properties.GlobalSecondaryIndexes.push(b),n}static enableStreams(n,i="NEW_AND_OLD_IMAGES"){return n.Properties.StreamSpecification={StreamViewType:i},n}static InstanceClasses={T3_Micro:"db.t3.micro",T3_Small:"db.t3.small",T3_Medium:"db.t3.medium",T3_Large:"db.t3.large",T4g_Micro:"db.t4g.micro",T4g_Small:"db.t4g.small",T4g_Medium:"db.t4g.medium",M5_Large:"db.m5.large",M5_XLarge:"db.m5.xlarge",M5_2XLarge:"db.m5.2xlarge",R5_Large:"db.r5.large",R5_XLarge:"db.r5.xlarge",R5_2XLarge:"db.r5.2xlarge"}}class Vo{static createRedis(n){let{slug:i,environment:s,nodeType:o="cache.t3.micro",engineVersion:c="7.1",port:u=6379,subnetIds:d,securityGroupIds:p,numCacheClusters:y=2,automaticFailover:h=!0,multiAz:b=!0,clusterMode:v=!1,numNodeGroups:A=1,replicasPerNodeGroup:T=1,atRestEncryption:R=!0,transitEncryption:P=!0,authToken:I,kmsKeyId:M,snapshotRetentionDays:L=7,snapshotWindow:N,maintenanceWindow:O}=n,B=r({slug:i,environment:s,resourceType:"redis"}),F=t(B),U,j;if(d&&d.length>0){let z=r({slug:i,environment:s,resourceType:"cache-subnet-group"});j=t(z),U={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:z,Description:`Subnet group for ${B}`,SubnetIds:d,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:s}]}}}let H={Type:"AWS::ElastiCache::ReplicationGroup",Properties:{ReplicationGroupId:B,ReplicationGroupDescription:`Redis cluster for ${i} ${s}`,Engine:"redis",EngineVersion:c,CacheNodeType:o,Port:u,AutomaticFailoverEnabled:h,MultiAZEnabled:b,AtRestEncryptionEnabled:R,TransitEncryptionEnabled:P,SnapshotRetentionLimit:L,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:s}]}};if(v)H.Properties.NumNodeGroups=A,H.Properties.ReplicasPerNodeGroup=T;else H.Properties.NumCacheClusters=y;if(I)H.Properties.AuthToken=I;if(M)H.Properties.KmsKeyId=M;if(j)H.Properties.CacheSubnetGroupName=x.Ref(j);if(p&&p.length>0)H.Properties.SecurityGroupIds=p;if(N)H.Properties.SnapshotWindow=N;if(O)H.Properties.PreferredMaintenanceWindow=O;return{replicationGroup:H,subnetGroup:U,logicalId:F,subnetGroupId:j}}static createMemcached(n){let{slug:i,environment:s,nodeType:o="cache.t3.micro",engineVersion:c="1.6.22",port:u=11211,numCacheNodes:d=2,subnetIds:p,securityGroupIds:y,azMode:h="cross-az",preferredAzs:b,maintenanceWindow:v}=n,A=r({slug:i,environment:s,resourceType:"memcached"}),T=t(A),R,P;if(p&&p.length>0){let M=r({slug:i,environment:s,resourceType:"cache-subnet-group"});P=t(M),R={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:M,Description:`Subnet group for ${A}`,SubnetIds:p,Tags:[{Key:"Name",Value:M},{Key:"Environment",Value:s}]}}}let I={Type:"AWS::ElastiCache::CacheCluster",Properties:{ClusterName:A,CacheNodeType:o,Engine:"memcached",EngineVersion:c,NumCacheNodes:d,Port:u,AZMode:h,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:s}]}};if(P)I.Properties.CacheSubnetGroupName=x.Ref(P);if(y&&y.length>0)I.Properties.VpcSecurityGroupIds=y;if(b&&b.length>0)I.Properties.PreferredAvailabilityZones=b;if(v)I.Properties.PreferredMaintenanceWindow=v;return{cluster:I,subnetGroup:R,logicalId:T,subnetGroupId:P}}static enableClusterMode(n,i=3,s=2){return delete n.Properties.NumCacheClusters,n.Properties.NumNodeGroups=i,n.Properties.ReplicasPerNodeGroup=s,n}static createRedisParameterGroup(n,i){let{slug:s,environment:o,parameters:c={}}=i,u=r({slug:s,environment:o,resourceType:"redis-params"}),d=t(u);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`redis${n.split(".")[0]}.x`,Description:`Parameter group for ${u}`,Properties:c,Tags:[{Key:"Name",Value:u},{Key:"Environment",Value:o}]}},logicalId:d}}static createMemcachedParameterGroup(n,i){let{slug:s,environment:o,parameters:c={}}=i,u=r({slug:s,environment:o,resourceType:"memcached-params"}),d=t(u);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`memcached${n.split(".")[0]}.${n.split(".")[1]}`,Description:`Parameter group for ${u}`,Properties:c,Tags:[{Key:"Name",Value:u},{Key:"Environment",Value:o}]}},logicalId:d}}static NodeTypes={T3_Micro:"cache.t3.micro",T3_Small:"cache.t3.small",T3_Medium:"cache.t3.medium",T4g_Micro:"cache.t4g.micro",T4g_Small:"cache.t4g.small",T4g_Medium:"cache.t4g.medium",M5_Large:"cache.m5.large",M5_XLarge:"cache.m5.xlarge",M5_2XLarge:"cache.m5.2xlarge",R5_Large:"cache.r5.large",R5_XLarge:"cache.r5.xlarge",R5_2XLarge:"cache.r5.2xlarge",R5_4XLarge:"cache.r5.4xlarge",R6g_Large:"cache.r6g.large",R6g_XLarge:"cache.r6g.xlarge",R6g_2XLarge:"cache.r6g.2xlarge"}}class de{static createUser(n){let{slug:i,environment:s,userName:o,groups:c,managedPolicyArns:u}=n,d=o||r({slug:i,environment:s,resourceType:"user"}),p=t(d),y={Type:"AWS::IAM::User",Properties:{UserName:d,Tags:[{Key:"Name",Value:d},{Key:"Environment",Value:s}]}};if(c&&c.length>0)y.Properties.Groups=c;if(u&&u.length>0)y.Properties.ManagedPolicyArns=u;return{user:y,logicalId:p}}static createRole(n){let{slug:i,environment:s,roleName:o,servicePrincipal:c,awsPrincipal:u,managedPolicyArns:d}=n,p=o||r({slug:i,environment:s,resourceType:"role"}),y=t(p),h={};if(c)h.Service=c;if(u)h.AWS=u;let b={Type:"AWS::IAM::Role",Properties:{RoleName:p,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:h,Action:"sts:AssumeRole"}]},Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(d&&d.length>0)b.Properties.ManagedPolicyArns=d;return{role:b,logicalId:y}}static createGroup(n){let{slug:i,environment:s,groupName:o,managedPolicyArns:c}=n,u=o||r({slug:i,environment:s,resourceType:"group"}),d=t(u),p={Type:"AWS::IAM::Group",Properties:{GroupName:u}};if(c&&c.length>0)p.Properties.ManagedPolicyArns=c;return{group:p,logicalId:d}}static createPolicy(n){let{slug:i,environment:s,policyName:o,description:c,statements:u}=n,d=o||r({slug:i,environment:s,resourceType:"policy"}),p=t(d),y=u.map((b)=>({Sid:b.sid,Effect:b.effect||"Allow",Action:b.actions,Resource:b.resources,Condition:b.conditions}));return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:d,Description:c||`Managed policy for ${d}`,PolicyDocument:{Version:"2012-10-17",Statement:y}}},logicalId:p}}static attachPolicyToRole(n,i){if(!n.Properties.ManagedPolicyArns)n.Properties.ManagedPolicyArns=[];if(!n.Properties.ManagedPolicyArns.includes(i))n.Properties.ManagedPolicyArns.push(i);return n}static attachPolicyToUser(n,i){if(!n.Properties.ManagedPolicyArns)n.Properties.ManagedPolicyArns=[];if(!n.Properties.ManagedPolicyArns.includes(i))n.Properties.ManagedPolicyArns.push(i);return n}static attachPolicyToGroup(n,i){if(!n.Properties.ManagedPolicyArns)n.Properties.ManagedPolicyArns=[];if(!n.Properties.ManagedPolicyArns.includes(i))n.Properties.ManagedPolicyArns.push(i);return n}static addInlinePolicyToRole(n,i,s){if(!n.Properties.Policies)n.Properties.Policies=[];let o=s.map((c)=>({Effect:c.effect||"Allow",Action:c.actions,Resource:c.resources}));return n.Properties.Policies.push({PolicyName:i,PolicyDocument:{Version:"2012-10-17",Statement:o}}),n}static addInlinePolicyToUser(n,i,s){if(!n.Properties.Policies)n.Properties.Policies=[];let o=s.map((c)=>({Effect:c.effect||"Allow",Action:c.actions,Resource:c.resources}));return n.Properties.Policies.push({PolicyName:i,PolicyDocument:{Version:"2012-10-17",Statement:o}}),n}static createAccessKey(n,i){let{slug:s,environment:o,status:c="Active"}=i,u=r({slug:s,environment:o,resourceType:"access-key"}),d=t(u);return{accessKey:{Type:"AWS::IAM::AccessKey",Properties:{UserName:x.Ref(n),Status:c}},logicalId:d}}static createInstanceProfile(n,i){let{slug:s,environment:o,profileName:c}=i,u=c||r({slug:s,environment:o,resourceType:"instance-profile"}),d=t(u);return{instanceProfile:{Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:u,Roles:[x.Ref(n)]}},logicalId:d}}static ManagedPolicies={AdministratorAccess:"arn:aws:iam::aws:policy/AdministratorAccess",PowerUserAccess:"arn:aws:iam::aws:policy/PowerUserAccess",ReadOnlyAccess:"arn:aws:iam::aws:policy/ReadOnlyAccess",S3FullAccess:"arn:aws:iam::aws:policy/AmazonS3FullAccess",S3ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess",DynamoDBFullAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess",DynamoDBReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess",RDSFullAccess:"arn:aws:iam::aws:policy/AmazonRDSFullAccess",RDSReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess",LambdaFullAccess:"arn:aws:iam::aws:policy/AWSLambda_FullAccess",LambdaReadOnlyAccess:"arn:aws:iam::aws:policy/AWSLambda_ReadOnlyAccess",LambdaBasicExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",LambdaVPCAccessExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole",EC2FullAccess:"arn:aws:iam::aws:policy/AmazonEC2FullAccess",EC2ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess",EC2ContainerRegistryReadOnly:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",EC2ContainerRegistryPowerUser:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser",ECSTaskExecutionRole:"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",ECSFullAccess:"arn:aws:iam::aws:policy/AmazonECS_FullAccess",CloudWatchFullAccess:"arn:aws:iam::aws:policy/CloudWatchFullAccess",CloudWatchLogsFullAccess:"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess",SESFullAccess:"arn:aws:iam::aws:policy/AmazonSESFullAccess",SNSFullAccess:"arn:aws:iam::aws:policy/AmazonSNSFullAccess",SQSFullAccess:"arn:aws:iam::aws:policy/AmazonSQSFullAccess",SecretsManagerReadWrite:"arn:aws:iam::aws:policy/SecretsManagerReadWrite"};static ServicePrincipals={Lambda:"lambda.amazonaws.com",EC2:"ec2.amazonaws.com",ECS:"ecs.amazonaws.com",ECSTaskExecution:"ecs-tasks.amazonaws.com",APIGateway:"apigateway.amazonaws.com",Events:"events.amazonaws.com",States:"states.amazonaws.com",CodeBuild:"codebuild.amazonaws.com",CodeDeploy:"codedeploy.amazonaws.com",CloudFormation:"cloudformation.amazonaws.com"};static createCiCdUser(n){let{slug:i,environment:s,permissions:o,createAccessKey:c=!0}=n,u={},d=[];if(o.s3Buckets&&o.s3Buckets.length>0)d.push({sid:"S3Access",actions:["s3:GetBucketLocation","s3:ListBucket","s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucketMultipartUploads","s3:AbortMultipartUpload"],resources:[...o.s3Buckets,...o.s3Buckets.map((T)=>`${T}/*`)]});if(o.cloudFrontDistributions&&o.cloudFrontDistributions.length>0)d.push({sid:"CloudFrontAccess",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations","cloudfront:GetDistribution"],resources:o.cloudFrontDistributions});if(o.ecrRepositories&&o.ecrRepositories.length>0)d.push({sid:"ECRAccess",actions:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:DescribeRepositories","ecr:ListImages","ecr:DescribeImages","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:o.ecrRepositories}),d.push({sid:"ECRLogin",actions:["ecr:GetAuthorizationToken"],resources:"*"});if(o.ecsServices&&o.ecsServices.length>0)d.push({sid:"ECSAccess",actions:["ecs:DescribeServices","ecs:DescribeTaskDefinition","ecs:DescribeTasks","ecs:ListTasks","ecs:RegisterTaskDefinition","ecs:UpdateService","ecs:RunTask","ecs:StopTask"],resources:o.ecsServices}),d.push({sid:"ECSTaskDefinitions",actions:["ecs:RegisterTaskDefinition","ecs:DeregisterTaskDefinition"],resources:"*"}),d.push({sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}});if(o.cloudFormationStacks&&o.cloudFormationStacks.length>0)d.push({sid:"CloudFormationAccess",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:DescribeStackResources","cloudformation:GetTemplate","cloudformation:ListStackResources","cloudformation:ValidateTemplate"],resources:o.cloudFormationStacks});if(o.lambdaFunctions&&o.lambdaFunctions.length>0)d.push({sid:"LambdaAccess",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion","lambda:UpdateAlias","lambda:CreateAlias"],resources:o.lambdaFunctions});if(o.secretsManagerSecrets&&o.secretsManagerSecrets.length>0)d.push({sid:"SecretsManagerAccess",actions:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],resources:o.secretsManagerSecrets});let{policy:p,logicalId:y}=de.createPolicy({slug:i,environment:s,policyName:r({slug:i,environment:s,resourceType:"cicd-policy"}),description:`CI/CD deployment policy for ${i} (${s})`,statements:d});u[y]=p;let{user:h,logicalId:b}=de.createUser({slug:i,environment:s,userName:r({slug:i,environment:s,resourceType:"cicd-user"}),managedPolicyArns:[x.Ref(y)]});u[b]=h;let v,A;if(c){let T=de.createAccessKey(b,{slug:i,environment:s});v=T.accessKey,A=T.logicalId,u[A]=v}return{user:h,accessKey:v,policy:p,userLogicalId:b,accessKeyLogicalId:A,policyLogicalId:y,resources:u}}static createCrossAccountRole(n){let{slug:i,environment:s,trustedAccountIds:o,externalId:c,permissions:u,maxSessionDuration:d=3600}=n,p={},{policy:y,logicalId:h}=de.createPolicy({slug:i,environment:s,policyName:r({slug:i,environment:s,resourceType:"cross-account-policy"}),description:`Cross-account access policy for ${i} (${s})`,statements:u});p[h]=y;let b=r({slug:i,environment:s,resourceType:"cross-account-role"}),v=t(b),A={};if(c)A.StringEquals={"sts:ExternalId":c};let T={Type:"AWS::IAM::Role",Properties:{RoleName:b,MaxSessionDuration:d,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:o.map((R)=>`arn:aws:iam::${R}:root`)},Action:"sts:AssumeRole",...Object.keys(A).length>0?{Condition:A}:{}}]},ManagedPolicyArns:[x.Ref(h)],Tags:[{Key:"Name",Value:b},{Key:"Environment",Value:s},{Key:"Purpose",Value:"Cross-Account Access"}]}};return p[v]=T,{role:T,policy:y,roleLogicalId:v,policyLogicalId:h,resources:p}}static createCliUser(n){let{slug:i,environment:s,permissions:o="readonly"}=n,c={},u=[],d=[];switch(o){case"readonly":d=[de.ManagedPolicies.ReadOnlyAccess];break;case"deploy":u=[{sid:"S3Deploy",actions:["s3:*"],resources:"*"},{sid:"CloudFrontDeploy",actions:["cloudfront:*"],resources:"*"},{sid:"ECSDeploy",actions:["ecs:*"],resources:"*"},{sid:"ECRDeploy",actions:["ecr:*"],resources:"*"},{sid:"LambdaDeploy",actions:["lambda:*"],resources:"*"},{sid:"CloudFormationDeploy",actions:["cloudformation:*"],resources:"*"},{sid:"IAMPassRole",actions:["iam:PassRole"],resources:"*"}];break;case"admin":d=[de.ManagedPolicies.AdministratorAccess];break}let p,y;if(u.length>0){let T=de.createPolicy({slug:i,environment:s,policyName:r({slug:i,environment:s,resourceType:"cli-policy"}),description:`CLI access policy for ${i} (${s})`,statements:u});p=T.policy,y=T.logicalId,c[y]=p,d=[x.Ref(y)]}let{user:h,logicalId:b}=de.createUser({slug:i,environment:s,userName:r({slug:i,environment:s,resourceType:"cli-user"}),managedPolicyArns:d});c[b]=h;let{accessKey:v,logicalId:A}=de.createAccessKey(b,{slug:i,environment:s});return c[A]=v,{user:h,accessKey:v,policy:p,userLogicalId:b,accessKeyLogicalId:A,policyLogicalId:y,resources:c}}static CiCdPolicies={s3Deployment:(n)=>[{sid:"S3ListBuckets",actions:["s3:ListBucket","s3:GetBucketLocation"],resources:n},{sid:"S3Objects",actions:["s3:GetObject","s3:PutObject","s3:DeleteObject"],resources:n.map((i)=>`${i}/*`)}],cloudFrontInvalidation:(n)=>[{sid:"CloudFrontInvalidation",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations"],resources:n}],ecsDeployment:()=>[{sid:"ECSServices",actions:["ecs:DescribeServices","ecs:UpdateService","ecs:DescribeTaskDefinition","ecs:RegisterTaskDefinition"],resources:"*"},{sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}}],ecrPush:(n)=>[{sid:"ECRAuth",actions:["ecr:GetAuthorizationToken"],resources:"*"},{sid:"ECRPush",actions:["ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:n}],lambdaDeployment:(n)=>[{sid:"LambdaDeploy",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion"],resources:n}],cloudFormationDeployment:(n)=>[{sid:"CloudFormationDeploy",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:GetTemplate"],resources:n}]}}class ml{static createRestApi(n){let{slug:i,environment:s,name:o,description:c,endpointType:u="REGIONAL",binaryMediaTypes:d,compressionSize:p}=n,y=o||r({slug:i,environment:s,resourceType:"rest-api"}),h=t(y),b={Type:"AWS::ApiGateway::RestApi",Properties:{Name:y,Description:c||`REST API for ${i} ${s}`,EndpointConfiguration:{Types:[u]},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:s}]}};if(d&&d.length>0)b.Properties.BinaryMediaTypes=d;if(p!==void 0)b.Properties.MinimumCompressionSize=p;return{restApi:b,logicalId:h}}static createHttpApi(n){let{slug:i,environment:s,name:o,description:c,corsEnabled:u=!0,corsOrigins:d=["*"],corsMethods:p=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],corsHeaders:y=["*"],corsMaxAge:h=86400,corsAllowCredentials:b=!1}=n,v=o||r({slug:i,environment:s,resourceType:"http-api"}),A=t(v),T={Type:"AWS::ApiGatewayV2::Api",Properties:{Name:v,Description:c||`HTTP API for ${i} ${s}`,ProtocolType:"HTTP",Tags:{Name:v,Environment:s}}};if(u)T.Properties.CorsConfiguration={AllowOrigins:d,AllowMethods:p,AllowHeaders:y,MaxAge:h,AllowCredentials:b};return{httpApi:T,logicalId:A}}static createWebSocketApi(n){let{slug:i,environment:s,name:o,description:c}=n,u=o||r({slug:i,environment:s,resourceType:"ws-api"}),d=t(u);return{webSocketApi:{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:u,Description:c||`WebSocket API for ${i} ${s}`,ProtocolType:"WEBSOCKET",Tags:{Name:u,Environment:s}}},logicalId:d}}static createDeployment(n,i){let{slug:s,environment:o,description:c}=i,u=r({slug:s,environment:o,resourceType:"api-deployment"}),d=t(u);return{deployment:{Type:"AWS::ApiGateway::Deployment",Properties:{RestApiId:x.Ref(n),Description:c||`Deployment for ${u}`}},logicalId:d}}static createStage(n,i,s){let{slug:o,environment:c,stageName:u,description:d,cacheEnabled:p=!1,cacheSize:y="0.5",variables:h,throttling:b}=s,v=r({slug:o,environment:c,resourceType:"api-stage"}),A=t(v),T={Type:"AWS::ApiGateway::Stage",Properties:{StageName:u||c,RestApiId:x.Ref(n),DeploymentId:x.Ref(i),Description:d,CacheClusterEnabled:p,Tags:[{Key:"Name",Value:v},{Key:"Environment",Value:c}]}};if(p)T.Properties.CacheClusterSize=y;if(h)T.Properties.Variables=h;if(b)T.Properties.MethodSettings=[{HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:b.burstLimit,ThrottlingRateLimit:b.rateLimit}];return{stage:T,logicalId:A}}static createAuthorizer(n,i){let{slug:s,environment:o,name:c,type:u,functionArn:d,identitySource:p,userPoolArns:y,ttl:h=300}=i,b=c||r({slug:s,environment:o,resourceType:"api-authorizer"}),v=t(b),A={Type:"AWS::ApiGateway::Authorizer",Properties:{Name:b,Type:u,RestApiId:x.Ref(n),AuthorizerResultTtlInSeconds:h}};if(u==="TOKEN"||u==="REQUEST"){if(!d)throw Error("Lambda authorizer requires functionArn");A.Properties.AuthorizerUri=d,A.Properties.IdentitySource=p||"method.request.header.Authorization"}if(u==="COGNITO_USER_POOLS"){if(!y||y.length===0)throw Error("Cognito authorizer requires userPoolArns");A.Properties.ProviderARNs=y,A.Properties.IdentitySource=p||"method.request.header.Authorization"}return{authorizer:A,logicalId:v}}static setCors(n,i={}){let{origins:s=["*"],methods:o=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],headers:c=["*"],maxAge:u=86400,allowCredentials:d=!1}=i;return n.Properties.CorsConfiguration={AllowOrigins:s,AllowMethods:o,AllowHeaders:c,MaxAge:u,AllowCredentials:d},n}static addThrottling(n,i=5000,s=1e4){if(!n.Properties.MethodSettings)n.Properties.MethodSettings=[];return n.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:i,ThrottlingRateLimit:s}),n}static enableCaching(n,i="0.5",s=300){if(n.Properties.CacheClusterEnabled=!0,n.Properties.CacheClusterSize=i,!n.Properties.MethodSettings)n.Properties.MethodSettings=[];return n.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",CachingEnabled:!0,CacheTtlInSeconds:s}),n}static CacheSizes={Small:"0.5",Medium:"1.6",Large:"6.1",XLarge:"13.5",XXLarge:"28.4",XXXLarge:"58.2",Huge:"118",Massive:"237"};static ThrottlingPresets={Light:{burstLimit:100,rateLimit:50},Medium:{burstLimit:500,rateLimit:250},Heavy:{burstLimit:2000,rateLimit:1000},Default:{burstLimit:5000,rateLimit:1e4}}}class le{static createTopic(n){let{slug:i,environment:s,topicName:o,displayName:c,encrypted:u=!1,kmsKeyId:d}=n,p=o||r({slug:i,environment:s,resourceType:"topic"}),y=t(p),h={Type:"AWS::SNS::Topic",Properties:{TopicName:p,DisplayName:c||p,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(u&&d)h.Properties.KmsMasterKeyId=d;return{topic:h,logicalId:y}}static subscribe(n,i){let{slug:s,environment:o,protocol:c,endpoint:u,filterPolicy:d,rawMessageDelivery:p=!1}=i,y=r({slug:s,environment:o,resourceType:"subscription"}),h=u.replace(/[^a-zA-Z0-9]/g,""),b=h.length>12?h.slice(-12):h,v=t(`${y}-${c}-${b}`),A={Type:"AWS::SNS::Subscription",Properties:{TopicArn:x.Ref(n),Protocol:c,Endpoint:u,RawMessageDelivery:p}};if(d)A.Properties.FilterPolicy=d;return{subscription:A,logicalId:v}}static subscribeEmail(n,i,s){return le.subscribe(n,{...s,protocol:"email",endpoint:i})}static subscribeLambda(n,i,s){return le.subscribe(n,{...s,protocol:"lambda",endpoint:i,rawMessageDelivery:!0})}static subscribeSqs(n,i,s){return le.subscribe(n,{...s,protocol:"sqs",endpoint:i})}static subscribeHttp(n,i,s){let o=i.startsWith("https://")?"https":"http";return le.subscribe(n,{...s,protocol:o,endpoint:i})}static subscribeSms(n,i,s){return le.subscribe(n,{...s,protocol:"sms",endpoint:i})}static setTopicPolicy(n,i){let{slug:s,environment:o,allowedPrincipals:c,allowedServices:u,actions:d="SNS:Publish"}=i,p=r({slug:s,environment:o,resourceType:"topic-policy"}),y=t(p),h={};if(c)h.AWS=c;if(u)h.Service=u;return{policy:{Type:"AWS::SNS::TopicPolicy",Properties:{Topics:[x.Ref(n)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:h,Action:d,Resource:x.Ref(n)}]}}},logicalId:y}}static allowCloudWatchAlarms(n,i){return le.setTopicPolicy(n,{...i,allowedServices:"cloudwatch.amazonaws.com",actions:"SNS:Publish"})}static allowEventBridge(n,i){return le.setTopicPolicy(n,{...i,allowedServices:"events.amazonaws.com",actions:"SNS:Publish"})}static allowS3(n,i){return le.setTopicPolicy(n,{...i,allowedServices:"s3.amazonaws.com",actions:"SNS:Publish"})}static enableEncryption(n,i){if(!n.Properties)n.Properties={};return n.Properties.KmsMasterKeyId=i,n}static addInlineSubscription(n,i,s){if(!n.Properties)n.Properties={};if(!n.Properties.Subscription)n.Properties.Subscription=[];return n.Properties.Subscription.push({Protocol:i,Endpoint:s}),n}static FilterPolicies={eventType:(n)=>({eventType:n}),status:(n)=>({status:n}),numericRange:(n,i,s)=>({[n]:[{numeric:[">=",i,"<=",s]}]}),prefix:(n,i)=>({[n]:[{prefix:i}]}),and:(...n)=>Object.assign({},...n),exists:(n,i)=>({[n]:[{exists:i}]})};static UseCases={createAlertTopic:(n)=>le.createTopic({...n,topicName:n.topicName||`${n.slug}-${n.environment}-alerts`,displayName:n.displayName||"Alert Notifications"}),createEventFanout:(n)=>le.createTopic({...n,topicName:n.topicName||`${n.slug}-${n.environment}-events`,displayName:n.displayName||"Event Fanout"}),createNotificationTopic:(n)=>le.createTopic({...n,topicName:n.topicName||`${n.slug}-${n.environment}-notifications`,displayName:n.displayName||"User Notifications"})}}class oy{static createStateMachine(n){let{slug:i,environment:s,stateMachineName:o,type:c="STANDARD",definition:u,roleArn:d,loggingConfiguration:p,tracingConfiguration:y}=n,h=o||r({slug:i,environment:s,resourceType:"state-machine"}),b=t(h),v,A,T;if(d)T=d;else{let P=r({slug:i,environment:s,resourceType:"state-machine-role"});A=t(P),v={Type:"AWS::IAM::Role",Properties:{RoleName:P,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"states.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"],Tags:[{Key:"Name",Value:P},{Key:"Environment",Value:s}]}},T=x.GetAtt(A,"Arn")}let R={Type:"AWS::StepFunctions::StateMachine",Properties:{StateMachineName:h,StateMachineType:c,DefinitionString:JSON.stringify(u),RoleArn:T,Tags:[{Key:"Name",Value:h},{Key:"Environment",Value:s}]}};if(p)R.Properties.LoggingConfiguration={Level:p.level,IncludeExecutionData:p.includeExecutionData,Destinations:p.destinations?.map((P)=>({CloudWatchLogsLogGroup:{LogGroupArn:P}}))};if(y)R.Properties.TracingConfiguration={Enabled:y.enabled};return{stateMachine:R,logicalId:b,role:v,roleLogicalId:A}}static createLambdaTask(n,i){return{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Parameters:{FunctionName:n,Payload:i?.parameters||{"Input.$":"$"}},ResultPath:i?.resultPath,Retry:i?.retry,Catch:i?.catch,Next:i?.next,End:i?.end}}static createDynamoDBTask(n,i,s,o){return{Type:"Task",Resource:{GetItem:"arn:aws:states:::dynamodb:getItem",PutItem:"arn:aws:states:::dynamodb:putItem",UpdateItem:"arn:aws:states:::dynamodb:updateItem",DeleteItem:"arn:aws:states:::dynamodb:deleteItem"}[n],Parameters:{TableName:i,...s},ResultPath:o?.resultPath,Retry:o?.retry,Catch:o?.catch,Next:o?.next,End:o?.end}}static createSNSPublishTask(n,i,s){return{Type:"Task",Resource:"arn:aws:states:::sns:publish",Parameters:{TopicArn:n,Message:i},ResultPath:s?.resultPath,Retry:s?.retry,Catch:s?.catch,Next:s?.next,End:s?.end}}static createSQSSendMessageTask(n,i,s){return{Type:"Task",Resource:"arn:aws:states:::sqs:sendMessage",Parameters:{QueueUrl:n,MessageBody:i},ResultPath:s?.resultPath,Retry:s?.retry,Catch:s?.catch,Next:s?.next,End:s?.end}}static createPassState(n){return{Type:"Pass",Result:n?.result,ResultPath:n?.resultPath,Parameters:n?.parameters,Next:n?.next,End:n?.end}}static createWaitState(n){return{Type:"Wait",Seconds:n.seconds,Timestamp:n.timestamp,SecondsPath:n.secondsPath,TimestampPath:n.timestampPath,Next:n.next,End:n.end}}static createChoiceState(n,i){return{Type:"Choice",Choices:n,Default:i}}static createParallelState(n,i){return{Type:"Parallel",Branches:n,ResultPath:i?.resultPath,Retry:i?.retry,Catch:i?.catch,Next:i?.next,End:i?.end}}static createMapState(n,i){return{Type:"Map",ItemsPath:i?.itemsPath||"$.items",Iterator:n,MaxConcurrency:i?.maxConcurrency,ResultPath:i?.resultPath,Retry:i?.retry,Catch:i?.catch,Next:i?.next,End:i?.end}}static createSucceedState(){return{Type:"Succeed"}}static createFailState(n,i){return{Type:"Fail",Error:n,Cause:i}}static RetryPolicies={standard:()=>({ErrorEquals:["States.ALL"],IntervalSeconds:2,MaxAttempts:3,BackoffRate:2}),aggressive:()=>({ErrorEquals:["States.TaskFailed","States.Timeout"],IntervalSeconds:1,MaxAttempts:5,BackoffRate:1.5}),custom:(n,i,s,o)=>({ErrorEquals:n,IntervalSeconds:i,MaxAttempts:s,BackoffRate:o})};static CatchPolicies={all:(n,i)=>({ErrorEquals:["States.ALL"],Next:n,ResultPath:i||"$.error"}),specific:(n,i,s)=>({ErrorEquals:n,Next:i,ResultPath:s||"$.error"})};static Patterns={sequential:(n,i,s)=>{let o={};return s.forEach((c,u)=>{let d=u===s.length-1;o[c.name]={...c.state,Next:d?void 0:s[u+1].name,End:d}}),{Comment:"Sequential workflow",StartAt:s[0].name,States:o}},fanout:(n,i,s)=>({Comment:"Fan-out workflow",StartAt:"Parallel",States:{Parallel:{Type:"Parallel",Branches:s.map((o)=>o.definition),End:!0}}}),map:(n,i,s,o)=>({Comment:"Map workflow",StartAt:"Map",States:{Map:{Type:"Map",ItemsPath:"$.items",Iterator:s,MaxConcurrency:o,End:!0}}}),withErrorHandling:(n,i,s,o)=>({Comment:"Workflow with error handling",StartAt:"Main",States:{Main:{...s,Catch:[{ErrorEquals:["States.ALL"],Next:"ErrorHandler"}],Next:"Success"},ErrorHandler:o,Success:{Type:"Succeed"}}})}}class qo{static createAlarm(n){let{slug:i,environment:s,alarmName:o,metricName:c,namespace:u,statistic:d="Average",period:p=300,evaluationPeriods:y=1,threshold:h,comparisonOperator:b,treatMissingData:v="notBreaching",actionsEnabled:A=!0,alarmActions:T,okActions:R,insufficientDataActions:P,dimensions:I,unit:M,datapointsToAlarm:L}=n,N=o||r({slug:i,environment:s,resourceType:"alarm"}),O=t(N),B={Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:N,MetricName:c,Namespace:u,Statistic:d,Period:p,EvaluationPeriods:y,Threshold:h,ComparisonOperator:b,TreatMissingData:v,ActionsEnabled:A}};if(T&&T.length>0)B.Properties.AlarmActions=T;if(R&&R.length>0)B.Properties.OKActions=R;if(P&&P.length>0)B.Properties.InsufficientDataActions=P;if(I)B.Properties.Dimensions=Object.entries(I).map(([F,U])=>({Name:F,Value:U}));if(M)B.Properties.Unit=M;if(L!==void 0)B.Properties.DatapointsToAlarm=L;return{alarm:B,logicalId:O}}static createCompositeAlarm(n){let{slug:i,environment:s,alarmName:o,alarmRule:c,actionsEnabled:u=!0,alarmActions:d,okActions:p,insufficientDataActions:y}=n,h=o||r({slug:i,environment:s,resourceType:"composite-alarm"}),b=t(h),v={Type:"AWS::CloudWatch::CompositeAlarm",Properties:{AlarmName:h,AlarmRule:c,ActionsEnabled:u}};if(d&&d.length>0)v.Properties.AlarmActions=d;if(p&&p.length>0)v.Properties.OKActions=p;if(y&&y.length>0)v.Properties.InsufficientDataActions=y;return{alarm:v,logicalId:b}}static createDashboard(n){let{slug:i,environment:s,dashboardName:o,widgets:c}=n,u=o||r({slug:i,environment:s,resourceType:"dashboard"}),d=t(u),p={widgets:c.map((h)=>({type:h.type,x:h.x,y:h.y,width:h.width,height:h.height,properties:h.properties}))};return{dashboard:{Type:"AWS::CloudWatch::Dashboard",Properties:{DashboardName:u,DashboardBody:JSON.stringify(p)}},logicalId:d}}static createLogGroup(n){let{slug:i,environment:s,logGroupName:o,retentionInDays:c,kmsKeyId:u}=n,d=o||r({slug:i,environment:s,resourceType:"log-group"}),p=t(d),y={Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:d}};if(c!==void 0)y.Properties.RetentionInDays=c;if(u)y.Properties.KmsKeyId=u;return{logGroup:y,logicalId:p}}static createLogStream(n,i){let{slug:s,environment:o,logStreamName:c}=i,u=c||r({slug:s,environment:o,resourceType:"log-stream"}),d=t(u);return{logStream:{Type:"AWS::Logs::LogStream",Properties:{LogGroupName:x.Ref(n),LogStreamName:u}},logicalId:d}}static createMetricFilter(n,i){let{slug:s,environment:o,filterName:c,filterPattern:u,metricTransformations:d}=i,p=c||r({slug:s,environment:o,resourceType:"metric-filter"}),y=t(p);return{metricFilter:{Type:"AWS::Logs::MetricFilter",Properties:{LogGroupName:x.Ref(n),FilterPattern:u,MetricTransformations:d.map((b)=>({MetricName:b.metricName,MetricNamespace:b.metricNamespace,MetricValue:b.metricValue,DefaultValue:b.defaultValue,Unit:b.unit}))}},logicalId:y}}static AlarmTypes={highCpu:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-high-cpu`,metricName:"CPUUtilization",namespace:"AWS/EC2",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s},alarmActions:c?[c]:void 0}),highMemory:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-high-memory`,metricName:"MemoryUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s},alarmActions:c?[c]:void 0}),highDisk:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-high-disk`,metricName:"DiskSpaceUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s,Filesystem:"/dev/xvda1",MountPath:"/"},alarmActions:c?[c]:void 0}),lambdaErrors:(n,i,s,o=5,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-lambda-errors`,metricName:"Errors",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:s},alarmActions:c?[c]:void 0}),lambdaThrottles:(n,i,s,o=10,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-lambda-throttles`,metricName:"Throttles",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:s},alarmActions:c?[c]:void 0}),apiGateway5xxErrors:(n,i,s,o=10,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-api-5xx-errors`,metricName:"5XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:s},alarmActions:c?[c]:void 0}),apiGateway4xxErrors:(n,i,s,o=50,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-api-4xx-errors`,metricName:"4XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:s},alarmActions:c?[c]:void 0}),dynamoDBThrottles:(n,i,s,o=5,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-dynamodb-throttles`,metricName:"UserErrors",namespace:"AWS/DynamoDB",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{TableName:s},alarmActions:c?[c]:void 0}),rdsCpu:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-rds-cpu`,metricName:"CPUUtilization",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{DBInstanceIdentifier:s},alarmActions:c?[c]:void 0}),rdsFreeStorage:(n,i,s,o=5368709120,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-rds-storage`,metricName:"FreeStorageSpace",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"LessThanThreshold",dimensions:{DBInstanceIdentifier:s},alarmActions:c?[c]:void 0,unit:"Bytes"}),sqsQueueDepth:(n,i,s,o=100,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-sqs-depth`,metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{QueueName:s},alarmActions:c?[c]:void 0}),albUnhealthyTargets:(n,i,s,o,c=1,u)=>({slug:n,environment:i,alarmName:`${n}-${i}-alb-unhealthy`,metricName:"UnHealthyHostCount",namespace:"AWS/ApplicationELB",statistic:"Average",period:300,evaluationPeriods:2,threshold:c,comparisonOperator:"GreaterThanThreshold",dimensions:{LoadBalancer:s,TargetGroup:o},alarmActions:u?[u]:void 0}),sesBounceRate:(n,i,s=5,o)=>({slug:n,environment:i,alarmName:`${n}-${i}-ses-bounce-rate`,metricName:"Reputation.BounceRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:s/100,comparisonOperator:"GreaterThanThreshold",alarmActions:o?[o]:void 0}),sesComplaintRate:(n,i,s=0.1,o)=>({slug:n,environment:i,alarmName:`${n}-${i}-ses-complaint-rate`,metricName:"Reputation.ComplaintRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:s/100,comparisonOperator:"GreaterThanThreshold",alarmActions:o?[o]:void 0}),smsDeliveryFailure:(n,i,s,o=10,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-sms-delivery-failure`,metricName:"DirectSendMessagePermanentFailure",namespace:"AWS/Pinpoint",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{ApplicationId:s},alarmActions:c?[c]:void 0}),smsSpendLimit:(n,i,s=100,o)=>({slug:n,environment:i,alarmName:`${n}-${i}-sms-spend-limit`,metricName:"DirectSendMessageSpend",namespace:"AWS/Pinpoint",statistic:"Sum",period:86400,evaluationPeriods:1,threshold:s,comparisonOperator:"GreaterThanThreshold",alarmActions:o?[o]:void 0}),connectMissedCalls:(n,i,s,o=5,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-connect-missed-calls`,metricName:"MissedCalls",namespace:"AWS/Connect",statistic:"Sum",period:3600,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s},alarmActions:c?[c]:void 0})};static DashboardWidgets={metric:(n,i,s,o,c,u)=>({type:"metric",x:n,y:i,width:s,height:o,properties:{metrics:c,title:u||"Metrics",region:"us-east-1",period:300}}),text:(n,i,s,o,c)=>({type:"text",x:n,y:i,width:s,height:o,properties:{markdown:c}}),log:(n,i,s,o,c,u)=>({type:"log",x:n,y:i,width:s,height:o,properties:{query:`SOURCE '${c.join("' | SOURCE '")}'
2274
+ `;class X{static LambdaCode={send:Ct,receive:on,deliveryStatus:sn};static createPinpointApp(n){return{[`${n.slug}PinpointApp`]:{Type:"AWS::Pinpoint::App",Properties:{Name:n.name||`${n.slug}-sms`}}}}static createSmsChannel(n){let i={ApplicationId:n.applicationId,Enabled:n.enabled!==!1};if(n.senderId)i.SenderId=n.senderId;if(n.shortCode)i.ShortCode=n.shortCode;return{[`${n.slug}SmsChannel`]:{Type:"AWS::Pinpoint::SMSChannel",Properties:i}}}static createSmsLambdaRole(n){return{[`${n.slug}SmsLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${n.slug}-sms-lambda-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"SmsLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["mobiletargeting:SendMessages","mobiletargeting:GetSmsChannel"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem","dynamodb:DeleteItem"],Resource:"*"}]}}]}}}}static createSendLambda(n){return{[`${n.slug}SmsSendLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-sms-send`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:X.LambdaCode.send},Environment:{Variables:{PINPOINT_APP_ID:n.pinpointAppId,MESSAGE_LOG_TABLE:n.messageLogTable||"",SMS_SENDER_ID:n.senderId||"",SMS_ORIGINATION_NUMBER:n.originationNumber||""}}}}}}static createReceiveLambda(n){return{[`${n.slug}SmsReceiveLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-sms-receive`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:X.LambdaCode.receive},Environment:{Variables:{OPT_OUT_TABLE:n.optOutTable||"",MESSAGE_LOG_TABLE:n.messageLogTable||"",NOTIFICATION_TOPIC_ARN:n.notificationTopicArn||"",WEBHOOK_URL:n.webhookUrl||""}}}}}}static createDeliveryStatusLambda(n){return{[`${n.slug}SmsDeliveryStatusLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-sms-delivery-status`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:X.LambdaCode.deliveryStatus},Environment:{Variables:{MESSAGE_LOG_TABLE:n.messageLogTable||"",NOTIFICATION_TOPIC_ARN:n.notificationTopicArn||"",WEBHOOK_URL:n.webhookUrl||""}}}}}}static createMessageLogTable(n){return{[`${n.slug}SmsMessageLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${n.slug}-sms-messages`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"messageId",AttributeType:"S"}],KeySchema:[{AttributeName:"messageId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createOptOutTable(n){return{[`${n.slug}SmsOptOutTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${n.slug}-sms-optouts`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"phoneNumber",AttributeType:"S"}],KeySchema:[{AttributeName:"phoneNumber",KeyType:"HASH"}]}}}}static createNotificationTopic(n){return{[`${n.slug}SmsNotificationTopic`]:{Type:"AWS::SNS::Topic",Properties:{TopicName:`${n.slug}-sms-notifications`}}}}static createCompleteSetup(n){let i={},s={};Object.assign(i,X.createPinpointApp({slug:n.slug})),Object.assign(i,X.createSmsChannel({slug:n.slug,applicationId:{Ref:`${n.slug}PinpointApp`},senderId:n.senderId})),Object.assign(i,X.createSmsLambdaRole({slug:n.slug})),Object.assign(i,X.createMessageLogTable({slug:n.slug})),Object.assign(i,X.createOptOutTable({slug:n.slug})),Object.assign(i,X.createNotificationTopic({slug:n.slug}));let o={"Fn::GetAtt":[`${n.slug}SmsLambdaRole`,"Arn"]},c={Ref:`${n.slug}PinpointApp`},u={Ref:`${n.slug}SmsMessageLogTable`},d={Ref:`${n.slug}SmsOptOutTable`},p={Ref:`${n.slug}SmsNotificationTopic`};if(Object.assign(i,X.createSendLambda({slug:n.slug,roleArn:o,pinpointAppId:c,messageLogTable:u,senderId:n.senderId,originationNumber:n.originationNumber})),n.twoWayEnabled)Object.assign(i,X.createReceiveLambda({slug:n.slug,roleArn:o,optOutTable:d,messageLogTable:u,notificationTopicArn:p,webhookUrl:n.webhookUrl}));return Object.assign(i,X.createDeliveryStatusLambda({slug:n.slug,roleArn:o,messageLogTable:u,notificationTopicArn:p,webhookUrl:n.webhookUrl})),s[`${n.slug}PinpointAppId`]={Description:"Pinpoint application ID",Value:{Ref:`${n.slug}PinpointApp`}},s[`${n.slug}SmsSendLambdaArn`]={Description:"SMS send Lambda ARN",Value:{"Fn::GetAtt":[`${n.slug}SmsSendLambda`,"Arn"]}},s[`${n.slug}SmsNotificationTopicArn`]={Description:"SMS notification topic ARN",Value:{Ref:`${n.slug}SmsNotificationTopic`}},s[`${n.slug}SmsMessageLogTableName`]={Description:"SMS message log table name",Value:{Ref:`${n.slug}SmsMessageLogTable`}},{resources:i,outputs:s}}}function vt(n){return n.replace(/[^a-zA-Z0-9]/g," ").trim().split(/\s+/).map((o)=>o.charAt(0).toUpperCase()+o.slice(1)).join("")||"User"}function Er(n,i){let s=(n||i).replace(/^\/+|\/+$/g,"");if(!s||s.split("/").includes(".."))throw Error(`sftp: invalid homeDirectory for user ${i}`);return s}function wr(n){let i=n.storage;if(i?.type==="efs"){let o="fileSystemId"in i?i.fileSystemId:void 0;if(!o||typeof o==="string"&&!o.trim())throw Error("sftp: EFS storage requires fileSystemId, or a fileSystem name defined in infrastructure.fileSystem");return{type:"efs",fileSystemId:o,posixProfile:i.posixProfile}}let s=(i?.type==="s3"?i.bucket??n.bucket:n.bucket)?.trim();if(!s)throw Error("sftp: S3 storage requires bucket, or a storageBucket name defined in infrastructure.storage");return{type:"s3",bucket:s}}function Ir(n,i,s){let o=i.posixProfile??s;if(!o)throw Error(`sftp: user ${n} requires a posixProfile (uid/gid) on an EFS-backed server`);for(let c of[o.uid,o.gid,...o.secondaryGids??[]])if(!Number.isInteger(c)||c<0||c>4294967295)throw Error(`sftp: user ${n} has an invalid posixProfile id ${c}`);return{Uid:o.uid,Gid:o.gid,...o.secondaryGids?.length?{SecondaryGids:o.secondaryGids}:{}}}function Dr(n,i){return typeof n==="string"?`/${n}/${i}`:{"Fn::Sub":[`/\${FileSystemId}/${i}`,{FileSystemId:n}]}}function Nr(n){return typeof n==="string"?{"Fn::Sub":"arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/${FileSystemId}".replace("${FileSystemId}",n)}:{"Fn::Sub":["arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/${FileSystemId}",{FileSystemId:n}]}}class pl{static create(n){let i=wr(n),s=i.type==="efs"?"EFS":"S3",o=n.endpointType??"PUBLIC";if(o==="VPC"&&(!n.endpointDetails?.vpcId||!n.endpointDetails.subnetIds.length))throw Error("sftp: VPC endpoints require endpointDetails.vpcId and at least one subnet");let c=`${vt(n.slug)}${vt(n.environment)}Sftp`,u=`${c}Server`,d={},p;if(n.logging!==!1){let y=`${c}LoggingRole`;d[y]={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"transfer.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"TransferLogging",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogGroup","logs:CreateLogStream","logs:DescribeLogStreams","logs:PutLogEvents"],Resource:"arn:aws:logs:*:*:log-group:/aws/transfer/*"}]}}]}},p={"Fn::GetAtt":[y,"Arn"]}}d[u]={Type:"AWS::Transfer::Server",Properties:{Domain:s,EndpointType:o,IdentityProviderType:"SERVICE_MANAGED",Protocols:["SFTP"],...o==="VPC"?{EndpointDetails:{VpcId:n.endpointDetails.vpcId,SubnetIds:n.endpointDetails.subnetIds,...n.endpointDetails.securityGroupIds?.length?{SecurityGroupIds:n.endpointDetails.securityGroupIds}:{},...n.endpointDetails.addressAllocationIds?.length?{AddressAllocationIds:n.endpointDetails.addressAllocationIds}:{}}}:{},...n.securityPolicyName?{SecurityPolicyName:n.securityPolicyName}:{},...p?{LoggingRole:p}:{},Tags:[{Key:"Project",Value:n.slug},{Key:"Environment",Value:n.environment},{Key:"ManagedBy",Value:"ts-cloud"}]}};for(let[y,h]of Object.entries(n.users)){if(!/^[a-zA-Z0-9_.@-]{3,100}$/.test(y))throw Error(`sftp: invalid username ${y}`);if(!h.sshPublicKeys.length)throw Error(`sftp: user ${y} requires at least one SSH public key`);let b=vt(y),v=Er(h.homeDirectory,y),A=`${c}${b}User`,T=h.roleArn;if(!T){let R=`${c}${b}Role`,P;if(i.type==="efs")P=[{Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:DescribeMountTargets"],Resource:Nr(i.fileSystemId)}];else{let I=`arn:aws:s3:::${i.bucket}`;P=[{Effect:"Allow",Action:["s3:ListBucket","s3:GetBucketLocation"],Resource:I,Condition:{StringLike:{"s3:prefix":[v,`${v}/*`]}}},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:GetObjectVersion"],Resource:`${I}/${v}/*`}]}d[R]={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"transfer.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"SftpHomeDirectory",PolicyDocument:{Version:"2012-10-17",Statement:P}}]}},T={"Fn::GetAtt":[R,"Arn"]}}d[A]={Type:"AWS::Transfer::User",DependsOn:[u],Properties:{ServerId:{Ref:u},UserName:y,Role:T,HomeDirectoryType:"PATH",HomeDirectory:i.type==="efs"?Dr(i.fileSystemId,v):`/${i.bucket}/${v}`,...i.type==="efs"?{PosixProfile:Ir(y,h,i.posixProfile)}:{},SshPublicKeys:h.sshPublicKeys}}}return{resources:d,serverLogicalId:u,domain:s}}}class Oe{static createBedrockRole(n,i){let{slug:s,environment:o,name:c,models:u=["*"],allowStreaming:d=!0}=i,p=c||r({slug:s,environment:o,resourceType:"bedrock-role"}),y=t(p),h=["bedrock:InvokeModel"];if(d)h.push("bedrock:InvokeModelWithResponseStream");let b=u.map((A)=>A==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${A}`);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:p,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:n},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:`${p}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:h,Resource:b}]}}],Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:o}]}},logicalId:y}}static createBedrockPolicy(n){let{slug:i,environment:s,name:o,models:c=["*"],allowInvoke:u=!0,allowStreaming:d=!0,allowAsync:p=!1}=n,y=o||r({slug:i,environment:s,resourceType:"bedrock-policy"}),h=t(y),b=[];if(u)b.push("bedrock:InvokeModel");if(d)b.push("bedrock:InvokeModelWithResponseStream");if(p)b.push("bedrock:InvokeModelAsync");let v=c.map((T)=>T==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${T}`);return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:y,PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"BedrockModelInvocation",Effect:"Allow",Action:b,Resource:v}]}}},logicalId:h}}static enableBedrockForLambda(n){return Oe.createBedrockRole("lambda.amazonaws.com",n)}static enableBedrockForEcs(n){return Oe.createBedrockRole("ecs-tasks.amazonaws.com",n)}static enableBedrockForEc2(n){return Oe.createBedrockRole("ec2.amazonaws.com",n)}static addBedrockPermissions(n,i=["*"],s=!0){let o=["bedrock:InvokeModel"];if(s)o.push("bedrock:InvokeModelWithResponseStream");let c=i.map((u)=>u==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${u}`);if(!n.Properties.Policies)n.Properties.Policies=[];return n.Properties.Policies.push({PolicyName:"bedrock-permissions",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:o,Resource:c}]}}),n}static Models={Claude3_5_Sonnet:"anthropic.claude-3-5-sonnet-20241022-v2:0",Claude3_5_Haiku:"anthropic.claude-3-5-haiku-20241022-v1:0",Claude3_Opus:"anthropic.claude-3-opus-20240229-v1:0",Claude3_Sonnet:"anthropic.claude-3-sonnet-20240229-v1:0",Claude3_Haiku:"anthropic.claude-3-haiku-20240307-v1:0",TitanTextG1Express:"amazon.titan-text-express-v1",TitanTextG1Lite:"amazon.titan-text-lite-v1",TitanEmbedG1Text:"amazon.titan-embed-text-v1",TitanImageG1:"amazon.titan-image-generator-v1",JurassicUltra:"ai21.j2-ultra-v1",JurassicMid:"ai21.j2-mid-v1",CommandText:"cohere.command-text-v14",CommandLight:"cohere.command-light-text-v14",EmbedEnglish:"cohere.embed-english-v3",EmbedMultilingual:"cohere.embed-multilingual-v3",Llama3_2_1B:"meta.llama3-2-1b-instruct-v1:0",Llama3_2_3B:"meta.llama3-2-3b-instruct-v1:0",Llama3_2_11B:"meta.llama3-2-11b-instruct-v1:0",Llama3_2_90B:"meta.llama3-2-90b-instruct-v1:0",Llama3_1_8B:"meta.llama3-1-8b-instruct-v1:0",Llama3_1_70B:"meta.llama3-1-70b-instruct-v1:0",Llama3_1_405B:"meta.llama3-1-405b-instruct-v1:0",Mistral7B:"mistral.mistral-7b-instruct-v0:2",Mixtral8x7B:"mistral.mixtral-8x7b-instruct-v0:1",MistralLarge:"mistral.mistral-large-2402-v1:0",StableDiffusionXL:"stability.stable-diffusion-xl-v1"};static ModelGroups={AllClaude:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","anthropic.claude-3-opus-20240229-v1:0","anthropic.claude-3-sonnet-20240229-v1:0","anthropic.claude-3-haiku-20240307-v1:0"],AllTitan:["amazon.titan-text-express-v1","amazon.titan-text-lite-v1","amazon.titan-embed-text-v1","amazon.titan-image-generator-v1"],AllLlama:["meta.llama3-2-1b-instruct-v1:0","meta.llama3-2-3b-instruct-v1:0","meta.llama3-2-11b-instruct-v1:0","meta.llama3-2-90b-instruct-v1:0","meta.llama3-1-8b-instruct-v1:0","meta.llama3-1-70b-instruct-v1:0","meta.llama3-1-405b-instruct-v1:0"],TextModels:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","amazon.titan-text-express-v1","meta.llama3-2-11b-instruct-v1:0","mistral.mistral-7b-instruct-v0:2"],EmbeddingModels:["amazon.titan-embed-text-v1","cohere.embed-english-v3","cohere.embed-multilingual-v3"],ImageModels:["amazon.titan-image-generator-v1","stability.stable-diffusion-xl-v1"]}}class lr{static createPostgres(n){return lr.createRDSInstance("postgres","16.2",n)}static createMysql(n){return lr.createRDSInstance("mysql","8.0.35",n)}static createRDSInstance(n,i,s){let{slug:o,environment:c,instanceClass:u="db.t3.micro",allocatedStorage:d=20,storageType:p="gp3",masterUsername:y="admin",masterPassword:h,databaseName:b,subnetIds:v,securityGroupIds:A,encrypted:T=!0,kmsKeyId:R,multiAz:P=!1,backupRetentionDays:I=7,publiclyAccessible:M=!1,enableCloudwatchLogs:L=!0,deletionProtection:N=!0}=s,O=r({slug:o,environment:c,resourceType:`${n}-db`}),B=t(O),F,U;if(v&&v.length>0){let H=r({slug:o,environment:c,resourceType:"db-subnet-group"});U=t(H),F={Type:"AWS::RDS::DBSubnetGroup",Properties:{DBSubnetGroupName:H,DBSubnetGroupDescription:`Subnet group for ${O}`,SubnetIds:v,Tags:[{Key:"Name",Value:H},{Key:"Environment",Value:c}]}}}let j={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:O,DBInstanceClass:u,Engine:n,EngineVersion:i,MasterUsername:y,MasterUserPassword:h,AllocatedStorage:d,StorageType:p,StorageEncrypted:T,MultiAZ:P,BackupRetentionPeriod:I,PubliclyAccessible:M,DeletionProtection:N,Tags:[{Key:"Name",Value:O},{Key:"Environment",Value:c}]}};if(b)j.Properties.DBName=b;if(R)j.Properties.KmsKeyId=R;if(U)j.Properties.DBSubnetGroupName=x.Ref(U);if(A&&A.length>0)j.Properties.VPCSecurityGroups=A;if(L)j.Properties.EnableCloudwatchLogsExports=n==="postgres"?["postgresql"]:["error","general","slowquery"];return{dbInstance:j,subnetGroup:F,logicalId:B,subnetGroupId:U}}static createReadReplica(n,i){let{slug:s,environment:o,instanceClass:c="db.t3.micro",securityGroupIds:u,publiclyAccessible:d=!1}=i,p=r({slug:s,environment:o,resourceType:"db-replica"}),y=t(p),h={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:p,DBInstanceClass:c,SourceDBInstanceIdentifier:x.Ref(n),PubliclyAccessible:d,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:o},{Key:"Type",Value:"ReadReplica"}]}};if(u&&u.length>0)h.Properties.VPCSecurityGroups=u;return{replica:h,logicalId:y}}static createParameterGroup(n,i,s){let{slug:o,environment:c,parameters:u={}}=s,d=r({slug:o,environment:c,resourceType:"db-params"}),p=t(d),y=n==="postgres"?`postgres${i.split(".")[0]}`:`mysql${i.split(".")[0]}.${i.split(".")[1]}`;return{parameterGroup:{Type:"AWS::RDS::DBParameterGroup",Properties:{DBParameterGroupName:d,Description:`Parameter group for ${d}`,Family:y,Parameters:u,Tags:[{Key:"Name",Value:d},{Key:"Environment",Value:c}]}},logicalId:p}}static enableBackup(n,i=7){return n.Properties.BackupRetentionPeriod=i,n}static createTable(n){let{slug:i,environment:s,tableName:o,partitionKey:c,sortKey:u,billingMode:d="PAY_PER_REQUEST",readCapacity:p=5,writeCapacity:y=5,streamEnabled:h=!1,streamViewType:b="NEW_AND_OLD_IMAGES",encrypted:v=!0,kmsKeyId:A,pointInTimeRecovery:T=!0,ttlAttribute:R}=n,P=o||r({slug:i,environment:s,resourceType:"table"}),I=t(P),M=[{AttributeName:c.name,AttributeType:c.type}];if(u)M.push({AttributeName:u.name,AttributeType:u.type});let L=[{AttributeName:c.name,KeyType:"HASH"}];if(u)L.push({AttributeName:u.name,KeyType:"RANGE"});let N={Type:"AWS::DynamoDB::Table",Properties:{TableName:P,BillingMode:d,AttributeDefinitions:M,KeySchema:L,Tags:[{Key:"Name",Value:P},{Key:"Environment",Value:s}]}};if(d==="PROVISIONED")N.Properties.ProvisionedThroughput={ReadCapacityUnits:p,WriteCapacityUnits:y};if(h)N.Properties.StreamSpecification={StreamViewType:b};if(v)N.Properties.SSESpecification={SSEEnabled:!0,SSEType:A?"KMS":"AES256",KMSMasterKeyId:A};if(T)N.Properties.PointInTimeRecoverySpecification={PointInTimeRecoveryEnabled:!0};if(R)N.Properties.TimeToLiveSpecification={AttributeName:R,Enabled:!0};return{table:N,logicalId:I}}static addGlobalSecondaryIndex(n,i){let{indexName:s,partitionKey:o,sortKey:c,projectionType:u="ALL",nonKeyAttributes:d,readCapacity:p=5,writeCapacity:y=5}=i;if(!n.Properties.AttributeDefinitions.some((v)=>v.AttributeName===o.name))n.Properties.AttributeDefinitions.push({AttributeName:o.name,AttributeType:o.type});if(c&&!n.Properties.AttributeDefinitions.some((v)=>v.AttributeName===c.name))n.Properties.AttributeDefinitions.push({AttributeName:c.name,AttributeType:c.type});let h=[{AttributeName:o.name,KeyType:"HASH"}];if(c)h.push({AttributeName:c.name,KeyType:"RANGE"});let b={IndexName:s,KeySchema:h,Projection:{ProjectionType:u,NonKeyAttributes:u==="INCLUDE"?d:void 0},ProvisionedThroughput:void 0};if(n.Properties.BillingMode==="PROVISIONED")b.ProvisionedThroughput={ReadCapacityUnits:p,WriteCapacityUnits:y};if(!n.Properties.GlobalSecondaryIndexes)n.Properties.GlobalSecondaryIndexes=[];return n.Properties.GlobalSecondaryIndexes.push(b),n}static enableStreams(n,i="NEW_AND_OLD_IMAGES"){return n.Properties.StreamSpecification={StreamViewType:i},n}static InstanceClasses={T3_Micro:"db.t3.micro",T3_Small:"db.t3.small",T3_Medium:"db.t3.medium",T3_Large:"db.t3.large",T4g_Micro:"db.t4g.micro",T4g_Small:"db.t4g.small",T4g_Medium:"db.t4g.medium",M5_Large:"db.m5.large",M5_XLarge:"db.m5.xlarge",M5_2XLarge:"db.m5.2xlarge",R5_Large:"db.r5.large",R5_XLarge:"db.r5.xlarge",R5_2XLarge:"db.r5.2xlarge"}}class Vo{static createRedis(n){let{slug:i,environment:s,nodeType:o="cache.t3.micro",engineVersion:c="7.1",port:u=6379,subnetIds:d,securityGroupIds:p,numCacheClusters:y=2,automaticFailover:h=!0,multiAz:b=!0,clusterMode:v=!1,numNodeGroups:A=1,replicasPerNodeGroup:T=1,atRestEncryption:R=!0,transitEncryption:P=!0,authToken:I,kmsKeyId:M,snapshotRetentionDays:L=7,snapshotWindow:N,maintenanceWindow:O}=n,B=r({slug:i,environment:s,resourceType:"redis"}),F=t(B),U,j;if(d&&d.length>0){let z=r({slug:i,environment:s,resourceType:"cache-subnet-group"});j=t(z),U={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:z,Description:`Subnet group for ${B}`,SubnetIds:d,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:s}]}}}let H={Type:"AWS::ElastiCache::ReplicationGroup",Properties:{ReplicationGroupId:B,ReplicationGroupDescription:`Redis cluster for ${i} ${s}`,Engine:"redis",EngineVersion:c,CacheNodeType:o,Port:u,AutomaticFailoverEnabled:h,MultiAZEnabled:b,AtRestEncryptionEnabled:R,TransitEncryptionEnabled:P,SnapshotRetentionLimit:L,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:s}]}};if(v)H.Properties.NumNodeGroups=A,H.Properties.ReplicasPerNodeGroup=T;else H.Properties.NumCacheClusters=y;if(I)H.Properties.AuthToken=I;if(M)H.Properties.KmsKeyId=M;if(j)H.Properties.CacheSubnetGroupName=x.Ref(j);if(p&&p.length>0)H.Properties.SecurityGroupIds=p;if(N)H.Properties.SnapshotWindow=N;if(O)H.Properties.PreferredMaintenanceWindow=O;return{replicationGroup:H,subnetGroup:U,logicalId:F,subnetGroupId:j}}static createMemcached(n){let{slug:i,environment:s,nodeType:o="cache.t3.micro",engineVersion:c="1.6.22",port:u=11211,numCacheNodes:d=2,subnetIds:p,securityGroupIds:y,azMode:h="cross-az",preferredAzs:b,maintenanceWindow:v}=n,A=r({slug:i,environment:s,resourceType:"memcached"}),T=t(A),R,P;if(p&&p.length>0){let M=r({slug:i,environment:s,resourceType:"cache-subnet-group"});P=t(M),R={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:M,Description:`Subnet group for ${A}`,SubnetIds:p,Tags:[{Key:"Name",Value:M},{Key:"Environment",Value:s}]}}}let I={Type:"AWS::ElastiCache::CacheCluster",Properties:{ClusterName:A,CacheNodeType:o,Engine:"memcached",EngineVersion:c,NumCacheNodes:d,Port:u,AZMode:h,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:s}]}};if(P)I.Properties.CacheSubnetGroupName=x.Ref(P);if(y&&y.length>0)I.Properties.VpcSecurityGroupIds=y;if(b&&b.length>0)I.Properties.PreferredAvailabilityZones=b;if(v)I.Properties.PreferredMaintenanceWindow=v;return{cluster:I,subnetGroup:R,logicalId:T,subnetGroupId:P}}static enableClusterMode(n,i=3,s=2){return delete n.Properties.NumCacheClusters,n.Properties.NumNodeGroups=i,n.Properties.ReplicasPerNodeGroup=s,n}static createRedisParameterGroup(n,i){let{slug:s,environment:o,parameters:c={}}=i,u=r({slug:s,environment:o,resourceType:"redis-params"}),d=t(u);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`redis${n.split(".")[0]}.x`,Description:`Parameter group for ${u}`,Properties:c,Tags:[{Key:"Name",Value:u},{Key:"Environment",Value:o}]}},logicalId:d}}static createMemcachedParameterGroup(n,i){let{slug:s,environment:o,parameters:c={}}=i,u=r({slug:s,environment:o,resourceType:"memcached-params"}),d=t(u);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`memcached${n.split(".")[0]}.${n.split(".")[1]}`,Description:`Parameter group for ${u}`,Properties:c,Tags:[{Key:"Name",Value:u},{Key:"Environment",Value:o}]}},logicalId:d}}static NodeTypes={T3_Micro:"cache.t3.micro",T3_Small:"cache.t3.small",T3_Medium:"cache.t3.medium",T4g_Micro:"cache.t4g.micro",T4g_Small:"cache.t4g.small",T4g_Medium:"cache.t4g.medium",M5_Large:"cache.m5.large",M5_XLarge:"cache.m5.xlarge",M5_2XLarge:"cache.m5.2xlarge",R5_Large:"cache.r5.large",R5_XLarge:"cache.r5.xlarge",R5_2XLarge:"cache.r5.2xlarge",R5_4XLarge:"cache.r5.4xlarge",R6g_Large:"cache.r6g.large",R6g_XLarge:"cache.r6g.xlarge",R6g_2XLarge:"cache.r6g.2xlarge"}}class de{static createUser(n){let{slug:i,environment:s,userName:o,groups:c,managedPolicyArns:u}=n,d=o||r({slug:i,environment:s,resourceType:"user"}),p=t(d),y={Type:"AWS::IAM::User",Properties:{UserName:d,Tags:[{Key:"Name",Value:d},{Key:"Environment",Value:s}]}};if(c&&c.length>0)y.Properties.Groups=c;if(u&&u.length>0)y.Properties.ManagedPolicyArns=u;return{user:y,logicalId:p}}static createRole(n){let{slug:i,environment:s,roleName:o,servicePrincipal:c,awsPrincipal:u,managedPolicyArns:d}=n,p=o||r({slug:i,environment:s,resourceType:"role"}),y=t(p),h={};if(c)h.Service=c;if(u)h.AWS=u;let b={Type:"AWS::IAM::Role",Properties:{RoleName:p,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:h,Action:"sts:AssumeRole"}]},Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(d&&d.length>0)b.Properties.ManagedPolicyArns=d;return{role:b,logicalId:y}}static createGroup(n){let{slug:i,environment:s,groupName:o,managedPolicyArns:c}=n,u=o||r({slug:i,environment:s,resourceType:"group"}),d=t(u),p={Type:"AWS::IAM::Group",Properties:{GroupName:u}};if(c&&c.length>0)p.Properties.ManagedPolicyArns=c;return{group:p,logicalId:d}}static createPolicy(n){let{slug:i,environment:s,policyName:o,description:c,statements:u}=n,d=o||r({slug:i,environment:s,resourceType:"policy"}),p=t(d),y=u.map((b)=>({Sid:b.sid,Effect:b.effect||"Allow",Action:b.actions,Resource:b.resources,Condition:b.conditions}));return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:d,Description:c||`Managed policy for ${d}`,PolicyDocument:{Version:"2012-10-17",Statement:y}}},logicalId:p}}static attachPolicyToRole(n,i){if(!n.Properties.ManagedPolicyArns)n.Properties.ManagedPolicyArns=[];if(!n.Properties.ManagedPolicyArns.includes(i))n.Properties.ManagedPolicyArns.push(i);return n}static attachPolicyToUser(n,i){if(!n.Properties.ManagedPolicyArns)n.Properties.ManagedPolicyArns=[];if(!n.Properties.ManagedPolicyArns.includes(i))n.Properties.ManagedPolicyArns.push(i);return n}static attachPolicyToGroup(n,i){if(!n.Properties.ManagedPolicyArns)n.Properties.ManagedPolicyArns=[];if(!n.Properties.ManagedPolicyArns.includes(i))n.Properties.ManagedPolicyArns.push(i);return n}static addInlinePolicyToRole(n,i,s){if(!n.Properties.Policies)n.Properties.Policies=[];let o=s.map((c)=>({Effect:c.effect||"Allow",Action:c.actions,Resource:c.resources}));return n.Properties.Policies.push({PolicyName:i,PolicyDocument:{Version:"2012-10-17",Statement:o}}),n}static addInlinePolicyToUser(n,i,s){if(!n.Properties.Policies)n.Properties.Policies=[];let o=s.map((c)=>({Effect:c.effect||"Allow",Action:c.actions,Resource:c.resources}));return n.Properties.Policies.push({PolicyName:i,PolicyDocument:{Version:"2012-10-17",Statement:o}}),n}static createAccessKey(n,i){let{slug:s,environment:o,status:c="Active"}=i,u=r({slug:s,environment:o,resourceType:"access-key"}),d=t(u);return{accessKey:{Type:"AWS::IAM::AccessKey",Properties:{UserName:x.Ref(n),Status:c}},logicalId:d}}static createInstanceProfile(n,i){let{slug:s,environment:o,profileName:c}=i,u=c||r({slug:s,environment:o,resourceType:"instance-profile"}),d=t(u);return{instanceProfile:{Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:u,Roles:[x.Ref(n)]}},logicalId:d}}static ManagedPolicies={AdministratorAccess:"arn:aws:iam::aws:policy/AdministratorAccess",PowerUserAccess:"arn:aws:iam::aws:policy/PowerUserAccess",ReadOnlyAccess:"arn:aws:iam::aws:policy/ReadOnlyAccess",S3FullAccess:"arn:aws:iam::aws:policy/AmazonS3FullAccess",S3ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess",DynamoDBFullAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess",DynamoDBReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess",RDSFullAccess:"arn:aws:iam::aws:policy/AmazonRDSFullAccess",RDSReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess",LambdaFullAccess:"arn:aws:iam::aws:policy/AWSLambda_FullAccess",LambdaReadOnlyAccess:"arn:aws:iam::aws:policy/AWSLambda_ReadOnlyAccess",LambdaBasicExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",LambdaVPCAccessExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole",EC2FullAccess:"arn:aws:iam::aws:policy/AmazonEC2FullAccess",EC2ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess",EC2ContainerRegistryReadOnly:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",EC2ContainerRegistryPowerUser:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser",ECSTaskExecutionRole:"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",ECSFullAccess:"arn:aws:iam::aws:policy/AmazonECS_FullAccess",CloudWatchFullAccess:"arn:aws:iam::aws:policy/CloudWatchFullAccess",CloudWatchLogsFullAccess:"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess",SESFullAccess:"arn:aws:iam::aws:policy/AmazonSESFullAccess",SNSFullAccess:"arn:aws:iam::aws:policy/AmazonSNSFullAccess",SQSFullAccess:"arn:aws:iam::aws:policy/AmazonSQSFullAccess",SecretsManagerReadWrite:"arn:aws:iam::aws:policy/SecretsManagerReadWrite"};static ServicePrincipals={Lambda:"lambda.amazonaws.com",EC2:"ec2.amazonaws.com",ECS:"ecs.amazonaws.com",ECSTaskExecution:"ecs-tasks.amazonaws.com",APIGateway:"apigateway.amazonaws.com",Events:"events.amazonaws.com",States:"states.amazonaws.com",CodeBuild:"codebuild.amazonaws.com",CodeDeploy:"codedeploy.amazonaws.com",CloudFormation:"cloudformation.amazonaws.com"};static createCiCdUser(n){let{slug:i,environment:s,permissions:o,createAccessKey:c=!0}=n,u={},d=[];if(o.s3Buckets&&o.s3Buckets.length>0)d.push({sid:"S3Access",actions:["s3:GetBucketLocation","s3:ListBucket","s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucketMultipartUploads","s3:AbortMultipartUpload"],resources:[...o.s3Buckets,...o.s3Buckets.map((T)=>`${T}/*`)]});if(o.cloudFrontDistributions&&o.cloudFrontDistributions.length>0)d.push({sid:"CloudFrontAccess",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations","cloudfront:GetDistribution"],resources:o.cloudFrontDistributions});if(o.ecrRepositories&&o.ecrRepositories.length>0)d.push({sid:"ECRAccess",actions:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:DescribeRepositories","ecr:ListImages","ecr:DescribeImages","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:o.ecrRepositories}),d.push({sid:"ECRLogin",actions:["ecr:GetAuthorizationToken"],resources:"*"});if(o.ecsServices&&o.ecsServices.length>0)d.push({sid:"ECSAccess",actions:["ecs:DescribeServices","ecs:DescribeTaskDefinition","ecs:DescribeTasks","ecs:ListTasks","ecs:RegisterTaskDefinition","ecs:UpdateService","ecs:RunTask","ecs:StopTask"],resources:o.ecsServices}),d.push({sid:"ECSTaskDefinitions",actions:["ecs:RegisterTaskDefinition","ecs:DeregisterTaskDefinition"],resources:"*"}),d.push({sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}});if(o.cloudFormationStacks&&o.cloudFormationStacks.length>0)d.push({sid:"CloudFormationAccess",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:DescribeStackResources","cloudformation:GetTemplate","cloudformation:ListStackResources","cloudformation:ValidateTemplate"],resources:o.cloudFormationStacks});if(o.lambdaFunctions&&o.lambdaFunctions.length>0)d.push({sid:"LambdaAccess",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion","lambda:UpdateAlias","lambda:CreateAlias"],resources:o.lambdaFunctions});if(o.secretsManagerSecrets&&o.secretsManagerSecrets.length>0)d.push({sid:"SecretsManagerAccess",actions:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],resources:o.secretsManagerSecrets});let{policy:p,logicalId:y}=de.createPolicy({slug:i,environment:s,policyName:r({slug:i,environment:s,resourceType:"cicd-policy"}),description:`CI/CD deployment policy for ${i} (${s})`,statements:d});u[y]=p;let{user:h,logicalId:b}=de.createUser({slug:i,environment:s,userName:r({slug:i,environment:s,resourceType:"cicd-user"}),managedPolicyArns:[x.Ref(y)]});u[b]=h;let v,A;if(c){let T=de.createAccessKey(b,{slug:i,environment:s});v=T.accessKey,A=T.logicalId,u[A]=v}return{user:h,accessKey:v,policy:p,userLogicalId:b,accessKeyLogicalId:A,policyLogicalId:y,resources:u}}static createCrossAccountRole(n){let{slug:i,environment:s,trustedAccountIds:o,externalId:c,permissions:u,maxSessionDuration:d=3600}=n,p={},{policy:y,logicalId:h}=de.createPolicy({slug:i,environment:s,policyName:r({slug:i,environment:s,resourceType:"cross-account-policy"}),description:`Cross-account access policy for ${i} (${s})`,statements:u});p[h]=y;let b=r({slug:i,environment:s,resourceType:"cross-account-role"}),v=t(b),A={};if(c)A.StringEquals={"sts:ExternalId":c};let T={Type:"AWS::IAM::Role",Properties:{RoleName:b,MaxSessionDuration:d,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:o.map((R)=>`arn:aws:iam::${R}:root`)},Action:"sts:AssumeRole",...Object.keys(A).length>0?{Condition:A}:{}}]},ManagedPolicyArns:[x.Ref(h)],Tags:[{Key:"Name",Value:b},{Key:"Environment",Value:s},{Key:"Purpose",Value:"Cross-Account Access"}]}};return p[v]=T,{role:T,policy:y,roleLogicalId:v,policyLogicalId:h,resources:p}}static createCliUser(n){let{slug:i,environment:s,permissions:o="readonly"}=n,c={},u=[],d=[];switch(o){case"readonly":d=[de.ManagedPolicies.ReadOnlyAccess];break;case"deploy":u=[{sid:"S3Deploy",actions:["s3:*"],resources:"*"},{sid:"CloudFrontDeploy",actions:["cloudfront:*"],resources:"*"},{sid:"ECSDeploy",actions:["ecs:*"],resources:"*"},{sid:"ECRDeploy",actions:["ecr:*"],resources:"*"},{sid:"LambdaDeploy",actions:["lambda:*"],resources:"*"},{sid:"CloudFormationDeploy",actions:["cloudformation:*"],resources:"*"},{sid:"IAMPassRole",actions:["iam:PassRole"],resources:"*"}];break;case"admin":d=[de.ManagedPolicies.AdministratorAccess];break}let p,y;if(u.length>0){let T=de.createPolicy({slug:i,environment:s,policyName:r({slug:i,environment:s,resourceType:"cli-policy"}),description:`CLI access policy for ${i} (${s})`,statements:u});p=T.policy,y=T.logicalId,c[y]=p,d=[x.Ref(y)]}let{user:h,logicalId:b}=de.createUser({slug:i,environment:s,userName:r({slug:i,environment:s,resourceType:"cli-user"}),managedPolicyArns:d});c[b]=h;let{accessKey:v,logicalId:A}=de.createAccessKey(b,{slug:i,environment:s});return c[A]=v,{user:h,accessKey:v,policy:p,userLogicalId:b,accessKeyLogicalId:A,policyLogicalId:y,resources:c}}static CiCdPolicies={s3Deployment:(n)=>[{sid:"S3ListBuckets",actions:["s3:ListBucket","s3:GetBucketLocation"],resources:n},{sid:"S3Objects",actions:["s3:GetObject","s3:PutObject","s3:DeleteObject"],resources:n.map((i)=>`${i}/*`)}],cloudFrontInvalidation:(n)=>[{sid:"CloudFrontInvalidation",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations"],resources:n}],ecsDeployment:()=>[{sid:"ECSServices",actions:["ecs:DescribeServices","ecs:UpdateService","ecs:DescribeTaskDefinition","ecs:RegisterTaskDefinition"],resources:"*"},{sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}}],ecrPush:(n)=>[{sid:"ECRAuth",actions:["ecr:GetAuthorizationToken"],resources:"*"},{sid:"ECRPush",actions:["ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:n}],lambdaDeployment:(n)=>[{sid:"LambdaDeploy",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion"],resources:n}],cloudFormationDeployment:(n)=>[{sid:"CloudFormationDeploy",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:GetTemplate"],resources:n}]}}class ml{static createRestApi(n){let{slug:i,environment:s,name:o,description:c,endpointType:u="REGIONAL",binaryMediaTypes:d,compressionSize:p}=n,y=o||r({slug:i,environment:s,resourceType:"rest-api"}),h=t(y),b={Type:"AWS::ApiGateway::RestApi",Properties:{Name:y,Description:c||`REST API for ${i} ${s}`,EndpointConfiguration:{Types:[u]},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:s}]}};if(d&&d.length>0)b.Properties.BinaryMediaTypes=d;if(p!==void 0)b.Properties.MinimumCompressionSize=p;return{restApi:b,logicalId:h}}static createHttpApi(n){let{slug:i,environment:s,name:o,description:c,corsEnabled:u=!0,corsOrigins:d=["*"],corsMethods:p=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],corsHeaders:y=["*"],corsMaxAge:h=86400,corsAllowCredentials:b=!1}=n,v=o||r({slug:i,environment:s,resourceType:"http-api"}),A=t(v),T={Type:"AWS::ApiGatewayV2::Api",Properties:{Name:v,Description:c||`HTTP API for ${i} ${s}`,ProtocolType:"HTTP",Tags:{Name:v,Environment:s}}};if(u)T.Properties.CorsConfiguration={AllowOrigins:d,AllowMethods:p,AllowHeaders:y,MaxAge:h,AllowCredentials:b};return{httpApi:T,logicalId:A}}static createWebSocketApi(n){let{slug:i,environment:s,name:o,description:c}=n,u=o||r({slug:i,environment:s,resourceType:"ws-api"}),d=t(u);return{webSocketApi:{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:u,Description:c||`WebSocket API for ${i} ${s}`,ProtocolType:"WEBSOCKET",Tags:{Name:u,Environment:s}}},logicalId:d}}static createDeployment(n,i){let{slug:s,environment:o,description:c}=i,u=r({slug:s,environment:o,resourceType:"api-deployment"}),d=t(u);return{deployment:{Type:"AWS::ApiGateway::Deployment",Properties:{RestApiId:x.Ref(n),Description:c||`Deployment for ${u}`}},logicalId:d}}static createStage(n,i,s){let{slug:o,environment:c,stageName:u,description:d,cacheEnabled:p=!1,cacheSize:y="0.5",variables:h,throttling:b}=s,v=r({slug:o,environment:c,resourceType:"api-stage"}),A=t(v),T={Type:"AWS::ApiGateway::Stage",Properties:{StageName:u||c,RestApiId:x.Ref(n),DeploymentId:x.Ref(i),Description:d,CacheClusterEnabled:p,Tags:[{Key:"Name",Value:v},{Key:"Environment",Value:c}]}};if(p)T.Properties.CacheClusterSize=y;if(h)T.Properties.Variables=h;if(b)T.Properties.MethodSettings=[{HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:b.burstLimit,ThrottlingRateLimit:b.rateLimit}];return{stage:T,logicalId:A}}static createAuthorizer(n,i){let{slug:s,environment:o,name:c,type:u,functionArn:d,identitySource:p,userPoolArns:y,ttl:h=300}=i,b=c||r({slug:s,environment:o,resourceType:"api-authorizer"}),v=t(b),A={Type:"AWS::ApiGateway::Authorizer",Properties:{Name:b,Type:u,RestApiId:x.Ref(n),AuthorizerResultTtlInSeconds:h}};if(u==="TOKEN"||u==="REQUEST"){if(!d)throw Error("Lambda authorizer requires functionArn");A.Properties.AuthorizerUri=d,A.Properties.IdentitySource=p||"method.request.header.Authorization"}if(u==="COGNITO_USER_POOLS"){if(!y||y.length===0)throw Error("Cognito authorizer requires userPoolArns");A.Properties.ProviderARNs=y,A.Properties.IdentitySource=p||"method.request.header.Authorization"}return{authorizer:A,logicalId:v}}static setCors(n,i={}){let{origins:s=["*"],methods:o=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],headers:c=["*"],maxAge:u=86400,allowCredentials:d=!1}=i;return n.Properties.CorsConfiguration={AllowOrigins:s,AllowMethods:o,AllowHeaders:c,MaxAge:u,AllowCredentials:d},n}static addThrottling(n,i=5000,s=1e4){if(!n.Properties.MethodSettings)n.Properties.MethodSettings=[];return n.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:i,ThrottlingRateLimit:s}),n}static enableCaching(n,i="0.5",s=300){if(n.Properties.CacheClusterEnabled=!0,n.Properties.CacheClusterSize=i,!n.Properties.MethodSettings)n.Properties.MethodSettings=[];return n.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",CachingEnabled:!0,CacheTtlInSeconds:s}),n}static CacheSizes={Small:"0.5",Medium:"1.6",Large:"6.1",XLarge:"13.5",XXLarge:"28.4",XXXLarge:"58.2",Huge:"118",Massive:"237"};static ThrottlingPresets={Light:{burstLimit:100,rateLimit:50},Medium:{burstLimit:500,rateLimit:250},Heavy:{burstLimit:2000,rateLimit:1000},Default:{burstLimit:5000,rateLimit:1e4}}}class le{static createTopic(n){let{slug:i,environment:s,topicName:o,displayName:c,encrypted:u=!1,kmsKeyId:d}=n,p=o||r({slug:i,environment:s,resourceType:"topic"}),y=t(p),h={Type:"AWS::SNS::Topic",Properties:{TopicName:p,DisplayName:c||p,Tags:[{Key:"Name",Value:p},{Key:"Environment",Value:s}]}};if(u&&d)h.Properties.KmsMasterKeyId=d;return{topic:h,logicalId:y}}static subscribe(n,i){let{slug:s,environment:o,protocol:c,endpoint:u,filterPolicy:d,rawMessageDelivery:p=!1}=i,y=r({slug:s,environment:o,resourceType:"subscription"}),h=u.replace(/[^a-zA-Z0-9]/g,""),b=h.length>12?h.slice(-12):h,v=t(`${y}-${c}-${b}`),A={Type:"AWS::SNS::Subscription",Properties:{TopicArn:x.Ref(n),Protocol:c,Endpoint:u,RawMessageDelivery:p}};if(d)A.Properties.FilterPolicy=d;return{subscription:A,logicalId:v}}static subscribeEmail(n,i,s){return le.subscribe(n,{...s,protocol:"email",endpoint:i})}static subscribeLambda(n,i,s){return le.subscribe(n,{...s,protocol:"lambda",endpoint:i,rawMessageDelivery:!0})}static subscribeSqs(n,i,s){return le.subscribe(n,{...s,protocol:"sqs",endpoint:i})}static subscribeHttp(n,i,s){let o=i.startsWith("https://")?"https":"http";return le.subscribe(n,{...s,protocol:o,endpoint:i})}static subscribeSms(n,i,s){return le.subscribe(n,{...s,protocol:"sms",endpoint:i})}static setTopicPolicy(n,i){let{slug:s,environment:o,allowedPrincipals:c,allowedServices:u,actions:d="SNS:Publish"}=i,p=r({slug:s,environment:o,resourceType:"topic-policy"}),y=t(p),h={};if(c)h.AWS=c;if(u)h.Service=u;return{policy:{Type:"AWS::SNS::TopicPolicy",Properties:{Topics:[x.Ref(n)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:h,Action:d,Resource:x.Ref(n)}]}}},logicalId:y}}static allowCloudWatchAlarms(n,i){return le.setTopicPolicy(n,{...i,allowedServices:"cloudwatch.amazonaws.com",actions:"SNS:Publish"})}static allowEventBridge(n,i){return le.setTopicPolicy(n,{...i,allowedServices:"events.amazonaws.com",actions:"SNS:Publish"})}static allowS3(n,i){return le.setTopicPolicy(n,{...i,allowedServices:"s3.amazonaws.com",actions:"SNS:Publish"})}static enableEncryption(n,i){if(!n.Properties)n.Properties={};return n.Properties.KmsMasterKeyId=i,n}static addInlineSubscription(n,i,s){if(!n.Properties)n.Properties={};if(!n.Properties.Subscription)n.Properties.Subscription=[];return n.Properties.Subscription.push({Protocol:i,Endpoint:s}),n}static FilterPolicies={eventType:(n)=>({eventType:n}),status:(n)=>({status:n}),numericRange:(n,i,s)=>({[n]:[{numeric:[">=",i,"<=",s]}]}),prefix:(n,i)=>({[n]:[{prefix:i}]}),and:(...n)=>Object.assign({},...n),exists:(n,i)=>({[n]:[{exists:i}]})};static UseCases={createAlertTopic:(n)=>le.createTopic({...n,topicName:n.topicName||`${n.slug}-${n.environment}-alerts`,displayName:n.displayName||"Alert Notifications"}),createEventFanout:(n)=>le.createTopic({...n,topicName:n.topicName||`${n.slug}-${n.environment}-events`,displayName:n.displayName||"Event Fanout"}),createNotificationTopic:(n)=>le.createTopic({...n,topicName:n.topicName||`${n.slug}-${n.environment}-notifications`,displayName:n.displayName||"User Notifications"})}}class ay{static createStateMachine(n){let{slug:i,environment:s,stateMachineName:o,type:c="STANDARD",definition:u,roleArn:d,loggingConfiguration:p,tracingConfiguration:y}=n,h=o||r({slug:i,environment:s,resourceType:"state-machine"}),b=t(h),v,A,T;if(d)T=d;else{let P=r({slug:i,environment:s,resourceType:"state-machine-role"});A=t(P),v={Type:"AWS::IAM::Role",Properties:{RoleName:P,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"states.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"],Tags:[{Key:"Name",Value:P},{Key:"Environment",Value:s}]}},T=x.GetAtt(A,"Arn")}let R={Type:"AWS::StepFunctions::StateMachine",Properties:{StateMachineName:h,StateMachineType:c,DefinitionString:JSON.stringify(u),RoleArn:T,Tags:[{Key:"Name",Value:h},{Key:"Environment",Value:s}]}};if(p)R.Properties.LoggingConfiguration={Level:p.level,IncludeExecutionData:p.includeExecutionData,Destinations:p.destinations?.map((P)=>({CloudWatchLogsLogGroup:{LogGroupArn:P}}))};if(y)R.Properties.TracingConfiguration={Enabled:y.enabled};return{stateMachine:R,logicalId:b,role:v,roleLogicalId:A}}static createLambdaTask(n,i){return{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Parameters:{FunctionName:n,Payload:i?.parameters||{"Input.$":"$"}},ResultPath:i?.resultPath,Retry:i?.retry,Catch:i?.catch,Next:i?.next,End:i?.end}}static createDynamoDBTask(n,i,s,o){return{Type:"Task",Resource:{GetItem:"arn:aws:states:::dynamodb:getItem",PutItem:"arn:aws:states:::dynamodb:putItem",UpdateItem:"arn:aws:states:::dynamodb:updateItem",DeleteItem:"arn:aws:states:::dynamodb:deleteItem"}[n],Parameters:{TableName:i,...s},ResultPath:o?.resultPath,Retry:o?.retry,Catch:o?.catch,Next:o?.next,End:o?.end}}static createSNSPublishTask(n,i,s){return{Type:"Task",Resource:"arn:aws:states:::sns:publish",Parameters:{TopicArn:n,Message:i},ResultPath:s?.resultPath,Retry:s?.retry,Catch:s?.catch,Next:s?.next,End:s?.end}}static createSQSSendMessageTask(n,i,s){return{Type:"Task",Resource:"arn:aws:states:::sqs:sendMessage",Parameters:{QueueUrl:n,MessageBody:i},ResultPath:s?.resultPath,Retry:s?.retry,Catch:s?.catch,Next:s?.next,End:s?.end}}static createPassState(n){return{Type:"Pass",Result:n?.result,ResultPath:n?.resultPath,Parameters:n?.parameters,Next:n?.next,End:n?.end}}static createWaitState(n){return{Type:"Wait",Seconds:n.seconds,Timestamp:n.timestamp,SecondsPath:n.secondsPath,TimestampPath:n.timestampPath,Next:n.next,End:n.end}}static createChoiceState(n,i){return{Type:"Choice",Choices:n,Default:i}}static createParallelState(n,i){return{Type:"Parallel",Branches:n,ResultPath:i?.resultPath,Retry:i?.retry,Catch:i?.catch,Next:i?.next,End:i?.end}}static createMapState(n,i){return{Type:"Map",ItemsPath:i?.itemsPath||"$.items",Iterator:n,MaxConcurrency:i?.maxConcurrency,ResultPath:i?.resultPath,Retry:i?.retry,Catch:i?.catch,Next:i?.next,End:i?.end}}static createSucceedState(){return{Type:"Succeed"}}static createFailState(n,i){return{Type:"Fail",Error:n,Cause:i}}static RetryPolicies={standard:()=>({ErrorEquals:["States.ALL"],IntervalSeconds:2,MaxAttempts:3,BackoffRate:2}),aggressive:()=>({ErrorEquals:["States.TaskFailed","States.Timeout"],IntervalSeconds:1,MaxAttempts:5,BackoffRate:1.5}),custom:(n,i,s,o)=>({ErrorEquals:n,IntervalSeconds:i,MaxAttempts:s,BackoffRate:o})};static CatchPolicies={all:(n,i)=>({ErrorEquals:["States.ALL"],Next:n,ResultPath:i||"$.error"}),specific:(n,i,s)=>({ErrorEquals:n,Next:i,ResultPath:s||"$.error"})};static Patterns={sequential:(n,i,s)=>{let o={};return s.forEach((c,u)=>{let d=u===s.length-1;o[c.name]={...c.state,Next:d?void 0:s[u+1].name,End:d}}),{Comment:"Sequential workflow",StartAt:s[0].name,States:o}},fanout:(n,i,s)=>({Comment:"Fan-out workflow",StartAt:"Parallel",States:{Parallel:{Type:"Parallel",Branches:s.map((o)=>o.definition),End:!0}}}),map:(n,i,s,o)=>({Comment:"Map workflow",StartAt:"Map",States:{Map:{Type:"Map",ItemsPath:"$.items",Iterator:s,MaxConcurrency:o,End:!0}}}),withErrorHandling:(n,i,s,o)=>({Comment:"Workflow with error handling",StartAt:"Main",States:{Main:{...s,Catch:[{ErrorEquals:["States.ALL"],Next:"ErrorHandler"}],Next:"Success"},ErrorHandler:o,Success:{Type:"Succeed"}}})}}class qo{static createAlarm(n){let{slug:i,environment:s,alarmName:o,metricName:c,namespace:u,statistic:d="Average",period:p=300,evaluationPeriods:y=1,threshold:h,comparisonOperator:b,treatMissingData:v="notBreaching",actionsEnabled:A=!0,alarmActions:T,okActions:R,insufficientDataActions:P,dimensions:I,unit:M,datapointsToAlarm:L}=n,N=o||r({slug:i,environment:s,resourceType:"alarm"}),O=t(N),B={Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:N,MetricName:c,Namespace:u,Statistic:d,Period:p,EvaluationPeriods:y,Threshold:h,ComparisonOperator:b,TreatMissingData:v,ActionsEnabled:A}};if(T&&T.length>0)B.Properties.AlarmActions=T;if(R&&R.length>0)B.Properties.OKActions=R;if(P&&P.length>0)B.Properties.InsufficientDataActions=P;if(I)B.Properties.Dimensions=Object.entries(I).map(([F,U])=>({Name:F,Value:U}));if(M)B.Properties.Unit=M;if(L!==void 0)B.Properties.DatapointsToAlarm=L;return{alarm:B,logicalId:O}}static createCompositeAlarm(n){let{slug:i,environment:s,alarmName:o,alarmRule:c,actionsEnabled:u=!0,alarmActions:d,okActions:p,insufficientDataActions:y}=n,h=o||r({slug:i,environment:s,resourceType:"composite-alarm"}),b=t(h),v={Type:"AWS::CloudWatch::CompositeAlarm",Properties:{AlarmName:h,AlarmRule:c,ActionsEnabled:u}};if(d&&d.length>0)v.Properties.AlarmActions=d;if(p&&p.length>0)v.Properties.OKActions=p;if(y&&y.length>0)v.Properties.InsufficientDataActions=y;return{alarm:v,logicalId:b}}static createDashboard(n){let{slug:i,environment:s,dashboardName:o,widgets:c}=n,u=o||r({slug:i,environment:s,resourceType:"dashboard"}),d=t(u),p={widgets:c.map((h)=>({type:h.type,x:h.x,y:h.y,width:h.width,height:h.height,properties:h.properties}))};return{dashboard:{Type:"AWS::CloudWatch::Dashboard",Properties:{DashboardName:u,DashboardBody:JSON.stringify(p)}},logicalId:d}}static createLogGroup(n){let{slug:i,environment:s,logGroupName:o,retentionInDays:c,kmsKeyId:u}=n,d=o||r({slug:i,environment:s,resourceType:"log-group"}),p=t(d),y={Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:d}};if(c!==void 0)y.Properties.RetentionInDays=c;if(u)y.Properties.KmsKeyId=u;return{logGroup:y,logicalId:p}}static createLogStream(n,i){let{slug:s,environment:o,logStreamName:c}=i,u=c||r({slug:s,environment:o,resourceType:"log-stream"}),d=t(u);return{logStream:{Type:"AWS::Logs::LogStream",Properties:{LogGroupName:x.Ref(n),LogStreamName:u}},logicalId:d}}static createMetricFilter(n,i){let{slug:s,environment:o,filterName:c,filterPattern:u,metricTransformations:d}=i,p=c||r({slug:s,environment:o,resourceType:"metric-filter"}),y=t(p);return{metricFilter:{Type:"AWS::Logs::MetricFilter",Properties:{LogGroupName:x.Ref(n),FilterPattern:u,MetricTransformations:d.map((b)=>({MetricName:b.metricName,MetricNamespace:b.metricNamespace,MetricValue:b.metricValue,DefaultValue:b.defaultValue,Unit:b.unit}))}},logicalId:y}}static AlarmTypes={highCpu:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-high-cpu`,metricName:"CPUUtilization",namespace:"AWS/EC2",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s},alarmActions:c?[c]:void 0}),highMemory:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-high-memory`,metricName:"MemoryUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s},alarmActions:c?[c]:void 0}),highDisk:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-high-disk`,metricName:"DiskSpaceUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s,Filesystem:"/dev/xvda1",MountPath:"/"},alarmActions:c?[c]:void 0}),lambdaErrors:(n,i,s,o=5,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-lambda-errors`,metricName:"Errors",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:s},alarmActions:c?[c]:void 0}),lambdaThrottles:(n,i,s,o=10,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-lambda-throttles`,metricName:"Throttles",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:s},alarmActions:c?[c]:void 0}),apiGateway5xxErrors:(n,i,s,o=10,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-api-5xx-errors`,metricName:"5XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:s},alarmActions:c?[c]:void 0}),apiGateway4xxErrors:(n,i,s,o=50,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-api-4xx-errors`,metricName:"4XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:s},alarmActions:c?[c]:void 0}),dynamoDBThrottles:(n,i,s,o=5,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-dynamodb-throttles`,metricName:"UserErrors",namespace:"AWS/DynamoDB",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{TableName:s},alarmActions:c?[c]:void 0}),rdsCpu:(n,i,s,o=80,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-rds-cpu`,metricName:"CPUUtilization",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{DBInstanceIdentifier:s},alarmActions:c?[c]:void 0}),rdsFreeStorage:(n,i,s,o=5368709120,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-rds-storage`,metricName:"FreeStorageSpace",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"LessThanThreshold",dimensions:{DBInstanceIdentifier:s},alarmActions:c?[c]:void 0,unit:"Bytes"}),sqsQueueDepth:(n,i,s,o=100,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-sqs-depth`,metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS",statistic:"Average",period:300,evaluationPeriods:2,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{QueueName:s},alarmActions:c?[c]:void 0}),albUnhealthyTargets:(n,i,s,o,c=1,u)=>({slug:n,environment:i,alarmName:`${n}-${i}-alb-unhealthy`,metricName:"UnHealthyHostCount",namespace:"AWS/ApplicationELB",statistic:"Average",period:300,evaluationPeriods:2,threshold:c,comparisonOperator:"GreaterThanThreshold",dimensions:{LoadBalancer:s,TargetGroup:o},alarmActions:u?[u]:void 0}),sesBounceRate:(n,i,s=5,o)=>({slug:n,environment:i,alarmName:`${n}-${i}-ses-bounce-rate`,metricName:"Reputation.BounceRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:s/100,comparisonOperator:"GreaterThanThreshold",alarmActions:o?[o]:void 0}),sesComplaintRate:(n,i,s=0.1,o)=>({slug:n,environment:i,alarmName:`${n}-${i}-ses-complaint-rate`,metricName:"Reputation.ComplaintRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:s/100,comparisonOperator:"GreaterThanThreshold",alarmActions:o?[o]:void 0}),smsDeliveryFailure:(n,i,s,o=10,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-sms-delivery-failure`,metricName:"DirectSendMessagePermanentFailure",namespace:"AWS/Pinpoint",statistic:"Sum",period:300,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{ApplicationId:s},alarmActions:c?[c]:void 0}),smsSpendLimit:(n,i,s=100,o)=>({slug:n,environment:i,alarmName:`${n}-${i}-sms-spend-limit`,metricName:"DirectSendMessageSpend",namespace:"AWS/Pinpoint",statistic:"Sum",period:86400,evaluationPeriods:1,threshold:s,comparisonOperator:"GreaterThanThreshold",alarmActions:o?[o]:void 0}),connectMissedCalls:(n,i,s,o=5,c)=>({slug:n,environment:i,alarmName:`${n}-${i}-connect-missed-calls`,metricName:"MissedCalls",namespace:"AWS/Connect",statistic:"Sum",period:3600,evaluationPeriods:1,threshold:o,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:s},alarmActions:c?[c]:void 0})};static DashboardWidgets={metric:(n,i,s,o,c,u)=>({type:"metric",x:n,y:i,width:s,height:o,properties:{metrics:c,title:u||"Metrics",region:"us-east-1",period:300}}),text:(n,i,s,o,c)=>({type:"text",x:n,y:i,width:s,height:o,properties:{markdown:c}}),log:(n,i,s,o,c,u)=>({type:"log",x:n,y:i,width:s,height:o,properties:{query:`SOURCE '${c.join("' | SOURCE '")}'
2275
2275
  | fields @timestamp, @message
2276
2276
  | sort @timestamp desc
2277
2277
  | limit 20`,region:"us-east-1",title:u||"Logs"}})};static RetentionPeriods={ONE_DAY:1,THREE_DAYS:3,FIVE_DAYS:5,ONE_WEEK:7,TWO_WEEKS:14,ONE_MONTH:30,TWO_MONTHS:60,THREE_MONTHS:90,FOUR_MONTHS:120,FIVE_MONTHS:150,SIX_MONTHS:180,ONE_YEAR:365,THIRTEEN_MONTHS:400,EIGHTEEN_MONTHS:545,TWO_YEARS:731,FIVE_YEARS:1827,TEN_YEARS:3653,NEVER_EXPIRE:void 0};static FilterPatterns={errors:"[time, request_id, event_type = ERROR*, ...]",all:"",jsonField:(n,i)=>`{ $.${n} = "${i}" }`,httpStatus:(n)=>`[..., status_code = ${n}, ...]`,http4xx:"[..., status_code = 4*, ...]",http5xx:"[..., status_code = 5*, ...]"};static createApplicationDashboard(n){let{slug:i,environment:s,region:o="us-east-1",components:c={}}=n,u=[],d=0;if(u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:`# ${i.toUpperCase()} Dashboard (${s})`}}),d+=1,c.ec2InstanceIds&&c.ec2InstanceIds.length>0)u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:"## EC2 Instances"}}),d+=1,u.push({type:"metric",x:0,y:d,width:8,height:6,properties:{title:"CPU Utilization",region:o,metrics:c.ec2InstanceIds.map((p)=>["AWS/EC2","CPUUtilization","InstanceId",p]),period:300,stat:"Average"}}),u.push({type:"metric",x:8,y:d,width:8,height:6,properties:{title:"Network Traffic",region:o,metrics:[...c.ec2InstanceIds.flatMap((p)=>[["AWS/EC2","NetworkIn","InstanceId",p,{label:`${p} In`}],["AWS/EC2","NetworkOut","InstanceId",p,{label:`${p} Out`}]])],period:300,stat:"Sum"}}),u.push({type:"metric",x:16,y:d,width:8,height:6,properties:{title:"Status Checks",region:o,metrics:c.ec2InstanceIds.map((p)=>["AWS/EC2","StatusCheckFailed","InstanceId",p]),period:60,stat:"Maximum"}}),d+=6;if(c.lambdaFunctionNames&&c.lambdaFunctionNames.length>0)u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:"## Lambda Functions"}}),d+=1,u.push({type:"metric",x:0,y:d,width:8,height:6,properties:{title:"Invocations",region:o,metrics:c.lambdaFunctionNames.map((p)=>["AWS/Lambda","Invocations","FunctionName",p]),period:300,stat:"Sum"}}),u.push({type:"metric",x:8,y:d,width:8,height:6,properties:{title:"Duration",region:o,metrics:c.lambdaFunctionNames.map((p)=>["AWS/Lambda","Duration","FunctionName",p]),period:300,stat:"Average"}}),u.push({type:"metric",x:16,y:d,width:8,height:6,properties:{title:"Errors",region:o,metrics:c.lambdaFunctionNames.map((p)=>["AWS/Lambda","Errors","FunctionName",p]),period:300,stat:"Sum"}}),d+=6;if(c.ecsClusterName&&c.ecsServiceName)u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:"## ECS Service"}}),d+=1,u.push({type:"metric",x:0,y:d,width:8,height:6,properties:{title:"CPU Utilization",region:o,metrics:[["AWS/ECS","CPUUtilization","ClusterName",c.ecsClusterName,"ServiceName",c.ecsServiceName]],period:300,stat:"Average"}}),u.push({type:"metric",x:8,y:d,width:8,height:6,properties:{title:"Memory Utilization",region:o,metrics:[["AWS/ECS","MemoryUtilization","ClusterName",c.ecsClusterName,"ServiceName",c.ecsServiceName]],period:300,stat:"Average"}}),u.push({type:"metric",x:16,y:d,width:8,height:6,properties:{title:"Running Tasks",region:o,metrics:[["ECS/ContainerInsights","RunningTaskCount","ClusterName",c.ecsClusterName,"ServiceName",c.ecsServiceName]],period:60,stat:"Average"}}),d+=6;if(c.albName)u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:"## Application Load Balancer"}}),d+=1,u.push({type:"metric",x:0,y:d,width:8,height:6,properties:{title:"Request Count",region:o,metrics:[["AWS/ApplicationELB","RequestCount","LoadBalancer",c.albName]],period:60,stat:"Sum"}}),u.push({type:"metric",x:8,y:d,width:8,height:6,properties:{title:"Response Time",region:o,metrics:[["AWS/ApplicationELB","TargetResponseTime","LoadBalancer",c.albName]],period:60,stat:"Average"}}),u.push({type:"metric",x:16,y:d,width:8,height:6,properties:{title:"HTTP Errors",region:o,metrics:[["AWS/ApplicationELB","HTTPCode_Target_4XX_Count","LoadBalancer",c.albName,{label:"4XX"}],["AWS/ApplicationELB","HTTPCode_Target_5XX_Count","LoadBalancer",c.albName,{label:"5XX"}]],period:60,stat:"Sum"}}),d+=6;if(c.rdsInstanceId)u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:"## RDS Database"}}),d+=1,u.push({type:"metric",x:0,y:d,width:8,height:6,properties:{title:"CPU Utilization",region:o,metrics:[["AWS/RDS","CPUUtilization","DBInstanceIdentifier",c.rdsInstanceId]],period:300,stat:"Average"}}),u.push({type:"metric",x:8,y:d,width:8,height:6,properties:{title:"Database Connections",region:o,metrics:[["AWS/RDS","DatabaseConnections","DBInstanceIdentifier",c.rdsInstanceId]],period:60,stat:"Sum"}}),u.push({type:"metric",x:16,y:d,width:8,height:6,properties:{title:"Free Storage Space",region:o,metrics:[["AWS/RDS","FreeStorageSpace","DBInstanceIdentifier",c.rdsInstanceId]],period:300,stat:"Average"}}),d+=6;if(c.sqsQueueNames&&c.sqsQueueNames.length>0)u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:"## SQS Queues"}}),d+=1,u.push({type:"metric",x:0,y:d,width:12,height:6,properties:{title:"Messages Visible",region:o,metrics:c.sqsQueueNames.map((p)=>["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName",p]),period:60,stat:"Sum"}}),u.push({type:"metric",x:12,y:d,width:12,height:6,properties:{title:"Message Age",region:o,metrics:c.sqsQueueNames.map((p)=>["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName",p]),period:60,stat:"Maximum"}}),d+=6;if(c.logGroupNames&&c.logGroupNames.length>0)u.push({type:"text",x:0,y:d,width:24,height:1,properties:{markdown:"## Application Logs"}}),d+=1,u.push({type:"log",x:0,y:d,width:24,height:6,properties:{query:`SOURCE '${c.logGroupNames.join("' | SOURCE '")}'
@@ -2430,7 +2430,7 @@ exports.handler = async (event) => {
2430
2430
  console.log('Receive SMS:', JSON.stringify(event, null, 2));
2431
2431
  // Process inbound SMS, handle opt-out keywords
2432
2432
  return { statusCode: 200 };
2433
- };`}var e={ref:(n)=>({Ref:n}),getAtt:(n,i)=>({"Fn::GetAtt":[n,i]}),join:(n,i)=>({"Fn::Join":[n,i]}),sub:(n,i)=>i?{"Fn::Sub":[n,i]}:{"Fn::Sub":n},select:(n,i)=>({"Fn::Select":[n,i]}),split:(n,i)=>({"Fn::Split":[n,i]}),getAZs:(n="")=>({"Fn::GetAZs":n}),importValue:(n)=>({"Fn::ImportValue":n}),findInMap:(n,i,s)=>({"Fn::FindInMap":[n,i,s]}),base64:(n)=>({"Fn::Base64":n}),cidr:(n,i,s)=>({"Fn::Cidr":[n,i,s]}),equals:(n,i)=>({"Fn::Equals":[n,i]}),if:(n,i,s)=>({"Fn::If":[n,i,s]}),not:(n)=>({"Fn::Not":[n]}),and:(...n)=>({"Fn::And":n}),or:(...n)=>({"Fn::Or":n})},un={s3Bucket:(n)=>e.sub(`arn:aws:s3:::${n}`),s3Object:(n,i="*")=>e.sub(`arn:aws:s3:::${n}/${i}`),lambda:(n,i,s)=>e.sub(`arn:aws:lambda:\${AWS::Region}:\${AWS::AccountId}:function:${n}`,i&&s?{"AWS::Region":i,"AWS::AccountId":s}:void 0),dynamodb:(n)=>e.sub(`arn:aws:dynamodb:\${AWS::Region}:\${AWS::AccountId}:table/${n}`),sqs:(n)=>e.sub(`arn:aws:sqs:\${AWS::Region}:\${AWS::AccountId}:${n}`),sns:(n)=>e.sub(`arn:aws:sns:\${AWS::Region}:\${AWS::AccountId}:${n}`),kinesis:(n)=>e.sub(`arn:aws:kinesis:\${AWS::Region}:\${AWS::AccountId}:stream/${n}`),iam:(n,i)=>e.sub(`arn:aws:iam::\${AWS::AccountId}:${n}/${i}`),secretsManager:(n)=>e.sub(`arn:aws:secretsmanager:\${AWS::Region}:\${AWS::AccountId}:secret:${n}`),cloudwatch:(n)=>e.sub(`arn:aws:logs:\${AWS::Region}:\${AWS::AccountId}:log-group:${n}`)},WI={ACCOUNT_ID:{Ref:"AWS::AccountId"},NOTIFICATION_ARNS:{Ref:"AWS::NotificationARNs"},NO_VALUE:{Ref:"AWS::NoValue"},PARTITION:{Ref:"AWS::Partition"},REGION:{Ref:"AWS::Region"},STACK_ID:{Ref:"AWS::StackId"},STACK_NAME:{Ref:"AWS::StackName"},URL_SUFFIX:{Ref:"AWS::URLSuffix"}};function Sn(n,i){if(i.type==="http")$r(n,i);else if(i.type==="rest")Br(n,i);else if(i.type==="websocket")Fr(n,i)}function $r(n,i){let s={Name:e.sub("${AWS::StackName}-http-api"),ProtocolType:"HTTP"};if(i.cors)s.CorsConfiguration={AllowOrigins:i.cors.allowOrigins,AllowMethods:i.cors.allowMethods,AllowHeaders:i.cors.allowHeaders||["*"],MaxAge:i.cors.maxAge||300};if(n.addResource("HttpApi","AWS::ApiGatewayV2::Api",s),n.addResource("HttpApiStage","AWS::ApiGatewayV2::Stage",{ApiId:e.ref("HttpApi"),StageName:"$default",AutoDeploy:!0,DefaultRouteSettings:i.throttling?{ThrottlingBurstLimit:i.throttling.burstLimit,ThrottlingRateLimit:i.throttling.rateLimit}:void 0,AccessLogSettings:{DestinationArn:e.getAtt("ApiLogGroup","Arn"),Format:"$context.requestId $context.error.message $context.error.messageString"}},{dependsOn:["HttpApi","ApiLogGroup"]}),n.addResource("ApiLogGroup","AWS::Logs::LogGroup",{LogGroupName:e.sub("/aws/apigateway/${AWS::StackName}-http-api"),RetentionInDays:14}),i.authorizer)Gr(n,"HttpApi",i.authorizer);if(i.customDomain)Rt(n,"HttpApi",i.customDomain,"HTTP");n.addOutputs({HttpApiId:{Description:"HTTP API ID",Value:e.ref("HttpApi"),Export:{Name:e.sub("${AWS::StackName}-http-api-id")}},HttpApiEndpoint:{Description:"HTTP API endpoint",Value:e.getAtt("HttpApi","ApiEndpoint"),Export:{Name:e.sub("${AWS::StackName}-http-api-endpoint")}}})}function Br(n,i){n.addResource("RestApi","AWS::ApiGateway::RestApi",{Name:e.sub("${AWS::StackName}-rest-api"),Description:e.sub("REST API for ${AWS::StackName}"),EndpointConfiguration:{Types:["REGIONAL"]}}),n.addResource("ApiGatewayAccount","AWS::ApiGateway::Account",{CloudWatchRoleArn:e.getAtt("ApiGatewayCloudWatchRole","Arn")},{dependsOn:"ApiGatewayCloudWatchRole"}),n.addResource("ApiGatewayCloudWatchRole","AWS::IAM::Role",{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"apigateway.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"]}),n.addResource("RestApiDeployment","AWS::ApiGateway::Deployment",{RestApiId:e.ref("RestApi"),Description:"Initial deployment"},{dependsOn:"RestApi"});let s={RestApiId:e.ref("RestApi"),DeploymentId:e.ref("RestApiDeployment"),StageName:"prod",Description:"Production stage",MethodSettings:[{ResourcePath:"/*",HttpMethod:"*",LoggingLevel:"INFO",DataTraceEnabled:!0,MetricsEnabled:!0}]};if(i.throttling)s.MethodSettings[0].ThrottlingBurstLimit=i.throttling.burstLimit,s.MethodSettings[0].ThrottlingRateLimit=i.throttling.rateLimit;if(n.addResource("RestApiStage","AWS::ApiGateway::Stage",s,{dependsOn:["RestApi","RestApiDeployment"]}),i.customDomain)Rt(n,"RestApi",i.customDomain,"REST");n.addOutputs({RestApiId:{Description:"REST API ID",Value:e.ref("RestApi"),Export:{Name:e.sub("${AWS::StackName}-rest-api-id")}},RestApiEndpoint:{Description:"REST API endpoint",Value:e.sub("https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/prod"),Export:{Name:e.sub("${AWS::StackName}-rest-api-endpoint")}}})}function Fr(n,i){if(n.addResource("WebSocketApi","AWS::ApiGatewayV2::Api",{Name:e.sub("${AWS::StackName}-websocket-api"),ProtocolType:"WEBSOCKET",RouteSelectionExpression:"$request.body.action"}),i.routes){if(i.routes.connect)lt(n,"$connect",i.routes.connect.functionName);if(i.routes.disconnect)lt(n,"$disconnect",i.routes.disconnect.functionName);if(i.routes.default)lt(n,"$default",i.routes.default.functionName);if(i.routes.custom)i.routes.custom.forEach((s)=>{lt(n,s.routeKey,s.functionName)})}if(n.addResource("WebSocketApiStage","AWS::ApiGatewayV2::Stage",{ApiId:e.ref("WebSocketApi"),StageName:"prod",AutoDeploy:!0,DefaultRouteSettings:i.throttling?{ThrottlingBurstLimit:i.throttling.burstLimit,ThrottlingRateLimit:i.throttling.rateLimit}:void 0},{dependsOn:"WebSocketApi"}),i.customDomain)Rt(n,"WebSocketApi",i.customDomain,"WEBSOCKET");n.addOutputs({WebSocketApiId:{Description:"WebSocket API ID",Value:e.ref("WebSocketApi"),Export:{Name:e.sub("${AWS::StackName}-websocket-api-id")}},WebSocketApiEndpoint:{Description:"WebSocket API endpoint",Value:e.getAtt("WebSocketApi","ApiEndpoint"),Export:{Name:e.sub("${AWS::StackName}-websocket-api-endpoint")}}})}function lt(n,i,s){let o=n.toLogicalId(`websocket-route-${i}`),c=n.toLogicalId(`websocket-integration-${i}`),u=n.toLogicalId(`${s}-function`);n.addResource(c,"AWS::ApiGatewayV2::Integration",{ApiId:e.ref("WebSocketApi"),IntegrationType:"AWS_PROXY",IntegrationUri:e.sub(`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${u}.Arn}/invocations`)},{dependsOn:["WebSocketApi",u]}),n.addResource(o,"AWS::ApiGatewayV2::Route",{ApiId:e.ref("WebSocketApi"),RouteKey:i,Target:e.join("/",["integrations",e.ref(c)])},{dependsOn:["WebSocketApi",c]}),n.addResource(`${o}Permission`,"AWS::Lambda::Permission",{FunctionName:e.ref(u),Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:e.sub("arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${WebSocketApi}/*")},{dependsOn:[u,"WebSocketApi"]})}function Rt(n,i,s,o){let c={DomainName:s.domain};if(o==="REST")c.CertificateArn=s.certificateArn,c.EndpointConfiguration={Types:["REGIONAL"]},n.addResource("ApiCustomDomain","AWS::ApiGateway::DomainName",c),n.addResource("ApiBasePathMapping","AWS::ApiGateway::BasePathMapping",{DomainName:e.ref("ApiCustomDomain"),RestApiId:e.ref(i),Stage:e.ref("RestApiStage")},{dependsOn:["ApiCustomDomain",i,"RestApiStage"]});else c.DomainNameConfigurations=[{CertificateArn:s.certificateArn,EndpointType:"REGIONAL"}],n.addResource("ApiCustomDomain","AWS::ApiGatewayV2::DomainName",c),n.addResource("ApiMapping","AWS::ApiGatewayV2::ApiMapping",{ApiId:e.ref(i),DomainName:e.ref("ApiCustomDomain"),Stage:o==="HTTP"?e.ref("HttpApiStage"):e.ref("WebSocketApiStage")},{dependsOn:["ApiCustomDomain",i]});if(s.dnsProvider!=="external")n.addResource("ApiDNSRecord","AWS::Route53::RecordSet",{HostedZoneName:e.sub(`${_r(s.domain)}.`),Name:s.domain,Type:"A",AliasTarget:{HostedZoneId:e.getAtt("ApiCustomDomain","RegionalHostedZoneId"),DNSName:e.getAtt("ApiCustomDomain","RegionalDomainName"),EvaluateTargetHealth:!1}},{dependsOn:"ApiCustomDomain"});n.addOutputs({ApiCustomDomainName:{Description:"Configured API custom domain",Value:s.domain},ApiCustomDomainTarget:{Description:"DNS target for Route53 or an external DNS provider",Value:e.getAtt("ApiCustomDomain","RegionalDomainName")},ApiCustomDomainHostedZoneId:{Description:"Regional API Gateway hosted zone ID",Value:e.getAtt("ApiCustomDomain","RegionalHostedZoneId")}})}function Gr(n,i,s){if(!s)return;if(s.type==="jwt")n.addResource("ApiAuthorizer","AWS::ApiGatewayV2::Authorizer",{ApiId:e.ref(i),AuthorizerType:"JWT",IdentitySource:[s.identitySource||"$request.header.Authorization"],JwtConfiguration:{Issuer:s.issuer,Audience:s.audience},Name:"JWTAuthorizer"},{dependsOn:i});else if(s.type==="lambda")n.addResource("ApiAuthorizer","AWS::ApiGatewayV2::Authorizer",{ApiId:e.ref(i),AuthorizerType:"REQUEST",AuthorizerUri:s.authorizerUri,IdentitySource:[s.identitySource||"$request.header.Authorization"],Name:"LambdaAuthorizer"},{dependsOn:i})}function _r(n){let i=n.split(".");if(i.length>=2)return i.slice(-2).join(".");return n}function An(n,i){if(i.redis)Wr(n,i.redis);if(i.memcached)Vr(n,i.memcached);if(i.elasticache)Ur(n,i.elasticache)}function Wr(n,i){if(!i)return;if(n.addResource("CacheSubnetGroup","AWS::ElastiCache::SubnetGroup",{Description:"Subnet group for ElastiCache Redis cluster",SubnetIds:[e.ref("PrivateSubnet1"),e.ref("PrivateSubnet2")],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-subnet-group")}]},{dependsOn:["PrivateSubnet1","PrivateSubnet2"]}),n.addResource("CacheSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for ElastiCache Redis",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:i.port||6379,ToPort:i.port||6379,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-sg")}]},{dependsOn:["VPC","AppSecurityGroup"]}),i.parameterGroup&&Object.keys(i.parameterGroup).length>0)n.addResource("CacheParameterGroup","AWS::ElastiCache::ParameterGroup",{Description:"Parameter group for Redis",CacheParameterGroupFamily:`redis${i.engineVersion.split(".")[0]}`,Properties:i.parameterGroup});if(i.numCacheNodes>1||i.automaticFailoverEnabled)n.addResource("RedisReplicationGroup","AWS::ElastiCache::ReplicationGroup",{ReplicationGroupDescription:"Redis replication group",ReplicationGroupId:e.sub("${AWS::StackName}-redis"),Engine:"redis",EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheClusters:i.numCacheNodes,AutomaticFailoverEnabled:i.automaticFailoverEnabled||!1,MultiAZEnabled:i.automaticFailoverEnabled||!1,Port:i.port||6379,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),SecurityGroupIds:[e.ref("CacheSecurityGroup")],CacheParameterGroupName:i.parameterGroup?e.ref("CacheParameterGroup"):void 0,SnapshotRetentionLimit:i.snapshotRetentionLimit||5,SnapshotWindow:i.snapshotWindow||"03:00-05:00",PreferredMaintenanceWindow:"sun:05:00-sun:06:00",AtRestEncryptionEnabled:!0,TransitEncryptionEnabled:!0,Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-redis")}]},{dependsOn:i.parameterGroup?["CacheSubnetGroup","CacheSecurityGroup","CacheParameterGroup"]:["CacheSubnetGroup","CacheSecurityGroup"],deletionPolicy:"Snapshot",updateReplacePolicy:"Snapshot"}),n.addOutputs({RedisEndpoint:{Description:"Redis primary endpoint",Value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Address"),Export:{Name:e.sub("${AWS::StackName}-redis-endpoint")}},RedisPort:{Description:"Redis port",Value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Port"),Export:{Name:e.sub("${AWS::StackName}-redis-port")}}});else n.addResource("RedisCacheCluster","AWS::ElastiCache::CacheCluster",{ClusterName:e.sub("${AWS::StackName}-redis"),Engine:"redis",EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheNodes:1,Port:i.port||6379,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),VpcSecurityGroupIds:[e.ref("CacheSecurityGroup")],CacheParameterGroupName:i.parameterGroup?e.ref("CacheParameterGroup"):void 0,SnapshotRetentionLimit:i.snapshotRetentionLimit||5,SnapshotWindow:i.snapshotWindow||"03:00-05:00",PreferredMaintenanceWindow:"sun:05:00-sun:06:00",Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-redis")}]},{dependsOn:i.parameterGroup?["CacheSubnetGroup","CacheSecurityGroup","CacheParameterGroup"]:["CacheSubnetGroup","CacheSecurityGroup"],deletionPolicy:"Snapshot",updateReplacePolicy:"Snapshot"}),n.addOutputs({RedisEndpoint:{Description:"Redis endpoint",Value:e.getAtt("RedisCacheCluster","RedisEndpoint.Address"),Export:{Name:e.sub("${AWS::StackName}-redis-endpoint")}},RedisPort:{Description:"Redis port",Value:e.getAtt("RedisCacheCluster","RedisEndpoint.Port"),Export:{Name:e.sub("${AWS::StackName}-redis-port")}}})}function Vr(n,i){if(!i)return;if(!n.hasResource("CacheSubnetGroup"))n.addResource("CacheSubnetGroup","AWS::ElastiCache::SubnetGroup",{Description:"Subnet group for ElastiCache",SubnetIds:[e.ref("PrivateSubnet1"),e.ref("PrivateSubnet2")]},{dependsOn:["PrivateSubnet1","PrivateSubnet2"]});if(!n.hasResource("CacheSecurityGroup"))n.addResource("CacheSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for ElastiCache Memcached",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:i.port||11211,ToPort:i.port||11211,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-sg")}]},{dependsOn:["VPC","AppSecurityGroup"]});n.addResource("MemcachedCacheCluster","AWS::ElastiCache::CacheCluster",{ClusterName:e.sub("${AWS::StackName}-memcached"),Engine:"memcached",EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheNodes:i.numCacheNodes,Port:i.port||11211,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),VpcSecurityGroupIds:[e.ref("CacheSecurityGroup")],PreferredMaintenanceWindow:"sun:05:00-sun:06:00",Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-memcached")}]},{dependsOn:["CacheSubnetGroup","CacheSecurityGroup"]}),n.addOutputs({MemcachedEndpoint:{Description:"Memcached configuration endpoint",Value:e.getAtt("MemcachedCacheCluster","ConfigurationEndpoint.Address"),Export:{Name:e.sub("${AWS::StackName}-memcached-endpoint")}},MemcachedPort:{Description:"Memcached port",Value:e.getAtt("MemcachedCacheCluster","ConfigurationEndpoint.Port"),Export:{Name:e.sub("${AWS::StackName}-memcached-port")}}})}function Ur(n,i){if(!i)return;let s=i.engine==="redis";if(!n.hasResource("CacheSubnetGroup"))n.addResource("CacheSubnetGroup","AWS::ElastiCache::SubnetGroup",{Description:"Subnet group for ElastiCache",SubnetIds:[e.ref("PrivateSubnet1"),e.ref("PrivateSubnet2")]},{dependsOn:["PrivateSubnet1","PrivateSubnet2"]});if(!n.hasResource("CacheSecurityGroup"))n.addResource("CacheSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for ElastiCache",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:s?6379:11211,ToPort:s?6379:11211,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-sg")}]},{dependsOn:["VPC","AppSecurityGroup"]});n.addResource("CacheCluster","AWS::ElastiCache::CacheCluster",{ClusterName:e.sub(`\${AWS::StackName}-${i.engine}`),Engine:i.engine,EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheNodes:i.numCacheNodes,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),VpcSecurityGroupIds:[e.ref("CacheSecurityGroup")],Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i.engine}`)}]},{dependsOn:["CacheSubnetGroup","CacheSecurityGroup"]})}function Cn(n,i){if(!i.enabled)return;n.addResource("CloudFrontOriginAccessIdentity","AWS::CloudFront::CloudFrontOriginAccessIdentity",{CloudFrontOriginAccessIdentityConfig:{Comment:e.sub("${AWS::StackName} CloudFront OAI")}});let s=[],o=[];if(!i.origins||i.origins.length===0)s.push({Id:"S3Origin",DomainName:e.getAtt("StaticBucket","DomainName"),S3OriginConfig:{OriginAccessIdentity:e.sub("origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}")}});else i.origins.forEach((d,p)=>{let y={Id:d.id,DomainName:d.domainName};if(d.originPath)y.OriginPath=d.originPath;if(d.domainName.includes("s3"))y.S3OriginConfig={OriginAccessIdentity:e.sub("origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}")};else y.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"]};if(s.push(y),p>0||d.pathPattern)o.push({PathPattern:d.pathPattern||`/${d.id}/*`,TargetOriginId:d.id,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD"],Compress:i.compress!==!1,ForwardedValues:{QueryString:!0,Cookies:{Forward:"none"}},MinTTL:i.cachePolicy?.minTTL||0,DefaultTTL:i.cachePolicy?.defaultTTL||86400,MaxTTL:i.cachePolicy?.maxTTL||31536000})});let c={TargetOriginId:s[0].Id,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD"],Compress:i.compress!==!1,ForwardedValues:{QueryString:!0,Cookies:{Forward:"none"}},MinTTL:i.cachePolicy?.minTTL||0,DefaultTTL:i.cachePolicy?.defaultTTL||86400,MaxTTL:i.cachePolicy?.maxTTL||31536000};if(i.edgeFunctions&&i.edgeFunctions.length>0)c.LambdaFunctionAssociations=i.edgeFunctions.map((d)=>({EventType:d.eventType,LambdaFunctionARN:d.functionArn}));let u={Enabled:!0,HttpVersion:i.http3?"http3":"http2",IPV6Enabled:!0,Origins:s,DefaultCacheBehavior:c,PriceClass:i.priceClass||"PriceClass_100",ViewerCertificate:{}};if(o.length>0)u.CacheBehaviors=o;if(i.customDomain)u.Aliases=[i.customDomain.domain],u.ViewerCertificate={AcmCertificateArn:i.customDomain.certificateArn,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else u.ViewerCertificate={CloudFrontDefaultCertificate:!0};if(i.errorPages)u.CustomErrorResponses=Object.entries(i.errorPages).map(([d,p])=>({ErrorCode:Number.parseInt(d),ResponseCode:200,ResponsePagePath:p,ErrorCachingMinTTL:300}));if(u.DefaultRootObject="index.html",u.Comment=e.sub("${AWS::StackName} CloudFront Distribution"),n.addResource("CloudFrontDistribution","AWS::CloudFront::Distribution",{DistributionConfig:u},{dependsOn:"CloudFrontOriginAccessIdentity"}),!i.origins||i.origins.length===0)n.addResource("StaticBucketPolicyForCloudFront","AWS::S3::BucketPolicy",{Bucket:e.ref("StaticBucket"),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontAccess",Effect:"Allow",Principal:{CanonicalUser:e.getAtt("CloudFrontOriginAccessIdentity","S3CanonicalUserId")},Action:"s3:GetObject",Resource:e.join("",[e.getAtt("StaticBucket","Arn"),"/*"])}]}},{dependsOn:["StaticBucket","CloudFrontOriginAccessIdentity"]});if(i.customDomain)n.addResource("CloudFrontDNSRecord","AWS::Route53::RecordSet",{HostedZoneName:e.sub(`${Hr(i.customDomain.domain)}.`),Name:i.customDomain.domain,Type:"A",AliasTarget:{HostedZoneId:"Z2FDTNDATAQYW2",DNSName:e.getAtt("CloudFrontDistribution","DomainName"),EvaluateTargetHealth:!1}},{dependsOn:"CloudFrontDistribution"});if(n.addOutputs({CloudFrontDistributionId:{Description:"CloudFront distribution ID",Value:e.ref("CloudFrontDistribution"),Export:{Name:e.sub("${AWS::StackName}-cloudfront-id")}},CloudFrontDomainName:{Description:"CloudFront distribution domain name",Value:e.getAtt("CloudFrontDistribution","DomainName"),Export:{Name:e.sub("${AWS::StackName}-cloudfront-domain")}}}),i.customDomain)n.addOutputs({CloudFrontURL:{Description:"CloudFront custom domain URL",Value:e.sub(`https://${i.customDomain.domain}`)}})}function Hr(n){let i=n.split(".");if(i.length>=2)return i.slice(-2).join(".");return n}function Tn(n,i){if(i.server)jr(n,i.server);if(i.fargate)vn(n,"app",i.fargate);if(i.services)i.services.forEach((s)=>{if(s.type==="fargate")vn(n,s.name,{taskDefinition:s.taskDefinition,service:s.service})})}function jr(n,i){if(!i)return;n.addResource("AppSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for application instances",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:3000,ToPort:3000,SourceSecurityGroupId:e.ref("ALBSecurityGroup")},{IpProtocol:"tcp",FromPort:22,ToPort:22,CidrIp:"0.0.0.0/0"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0"}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-app-sg")}]},{dependsOn:"VPC"}),n.addResource("EC2InstanceRole","AWS::IAM::Role",{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore","arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-ec2-role")}]}),n.addResource("EC2InstanceProfile","AWS::IAM::InstanceProfile",{Roles:[e.ref("EC2InstanceRole")]},{dependsOn:"EC2InstanceRole"});let s=i.userData||`#!/bin/bash
2433
+ };`}var e={ref:(n)=>({Ref:n}),getAtt:(n,i)=>({"Fn::GetAtt":[n,i]}),join:(n,i)=>({"Fn::Join":[n,i]}),sub:(n,i)=>i?{"Fn::Sub":[n,i]}:{"Fn::Sub":n},select:(n,i)=>({"Fn::Select":[n,i]}),split:(n,i)=>({"Fn::Split":[n,i]}),getAZs:(n="")=>({"Fn::GetAZs":n}),importValue:(n)=>({"Fn::ImportValue":n}),findInMap:(n,i,s)=>({"Fn::FindInMap":[n,i,s]}),base64:(n)=>({"Fn::Base64":n}),cidr:(n,i,s)=>({"Fn::Cidr":[n,i,s]}),equals:(n,i)=>({"Fn::Equals":[n,i]}),if:(n,i,s)=>({"Fn::If":[n,i,s]}),not:(n)=>({"Fn::Not":[n]}),and:(...n)=>({"Fn::And":n}),or:(...n)=>({"Fn::Or":n})},un={s3Bucket:(n)=>e.sub(`arn:aws:s3:::${n}`),s3Object:(n,i="*")=>e.sub(`arn:aws:s3:::${n}/${i}`),lambda:(n,i,s)=>e.sub(`arn:aws:lambda:\${AWS::Region}:\${AWS::AccountId}:function:${n}`,i&&s?{"AWS::Region":i,"AWS::AccountId":s}:void 0),dynamodb:(n)=>e.sub(`arn:aws:dynamodb:\${AWS::Region}:\${AWS::AccountId}:table/${n}`),sqs:(n)=>e.sub(`arn:aws:sqs:\${AWS::Region}:\${AWS::AccountId}:${n}`),sns:(n)=>e.sub(`arn:aws:sns:\${AWS::Region}:\${AWS::AccountId}:${n}`),kinesis:(n)=>e.sub(`arn:aws:kinesis:\${AWS::Region}:\${AWS::AccountId}:stream/${n}`),iam:(n,i)=>e.sub(`arn:aws:iam::\${AWS::AccountId}:${n}/${i}`),secretsManager:(n)=>e.sub(`arn:aws:secretsmanager:\${AWS::Region}:\${AWS::AccountId}:secret:${n}`),cloudwatch:(n)=>e.sub(`arn:aws:logs:\${AWS::Region}:\${AWS::AccountId}:log-group:${n}`)},JI={ACCOUNT_ID:{Ref:"AWS::AccountId"},NOTIFICATION_ARNS:{Ref:"AWS::NotificationARNs"},NO_VALUE:{Ref:"AWS::NoValue"},PARTITION:{Ref:"AWS::Partition"},REGION:{Ref:"AWS::Region"},STACK_ID:{Ref:"AWS::StackId"},STACK_NAME:{Ref:"AWS::StackName"},URL_SUFFIX:{Ref:"AWS::URLSuffix"}};function Sn(n,i){if(i.type==="http")$r(n,i);else if(i.type==="rest")Br(n,i);else if(i.type==="websocket")Fr(n,i)}function $r(n,i){let s={Name:e.sub("${AWS::StackName}-http-api"),ProtocolType:"HTTP"};if(i.cors)s.CorsConfiguration={AllowOrigins:i.cors.allowOrigins,AllowMethods:i.cors.allowMethods,AllowHeaders:i.cors.allowHeaders||["*"],MaxAge:i.cors.maxAge||300};if(n.addResource("HttpApi","AWS::ApiGatewayV2::Api",s),n.addResource("HttpApiStage","AWS::ApiGatewayV2::Stage",{ApiId:e.ref("HttpApi"),StageName:"$default",AutoDeploy:!0,DefaultRouteSettings:i.throttling?{ThrottlingBurstLimit:i.throttling.burstLimit,ThrottlingRateLimit:i.throttling.rateLimit}:void 0,AccessLogSettings:{DestinationArn:e.getAtt("ApiLogGroup","Arn"),Format:"$context.requestId $context.error.message $context.error.messageString"}},{dependsOn:["HttpApi","ApiLogGroup"]}),n.addResource("ApiLogGroup","AWS::Logs::LogGroup",{LogGroupName:e.sub("/aws/apigateway/${AWS::StackName}-http-api"),RetentionInDays:14}),i.authorizer)Gr(n,"HttpApi",i.authorizer);if(i.customDomain)Rt(n,"HttpApi",i.customDomain,"HTTP");n.addOutputs({HttpApiId:{Description:"HTTP API ID",Value:e.ref("HttpApi"),Export:{Name:e.sub("${AWS::StackName}-http-api-id")}},HttpApiEndpoint:{Description:"HTTP API endpoint",Value:e.getAtt("HttpApi","ApiEndpoint"),Export:{Name:e.sub("${AWS::StackName}-http-api-endpoint")}}})}function Br(n,i){n.addResource("RestApi","AWS::ApiGateway::RestApi",{Name:e.sub("${AWS::StackName}-rest-api"),Description:e.sub("REST API for ${AWS::StackName}"),EndpointConfiguration:{Types:["REGIONAL"]}}),n.addResource("ApiGatewayAccount","AWS::ApiGateway::Account",{CloudWatchRoleArn:e.getAtt("ApiGatewayCloudWatchRole","Arn")},{dependsOn:"ApiGatewayCloudWatchRole"}),n.addResource("ApiGatewayCloudWatchRole","AWS::IAM::Role",{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"apigateway.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"]}),n.addResource("RestApiDeployment","AWS::ApiGateway::Deployment",{RestApiId:e.ref("RestApi"),Description:"Initial deployment"},{dependsOn:"RestApi"});let s={RestApiId:e.ref("RestApi"),DeploymentId:e.ref("RestApiDeployment"),StageName:"prod",Description:"Production stage",MethodSettings:[{ResourcePath:"/*",HttpMethod:"*",LoggingLevel:"INFO",DataTraceEnabled:!0,MetricsEnabled:!0}]};if(i.throttling)s.MethodSettings[0].ThrottlingBurstLimit=i.throttling.burstLimit,s.MethodSettings[0].ThrottlingRateLimit=i.throttling.rateLimit;if(n.addResource("RestApiStage","AWS::ApiGateway::Stage",s,{dependsOn:["RestApi","RestApiDeployment"]}),i.customDomain)Rt(n,"RestApi",i.customDomain,"REST");n.addOutputs({RestApiId:{Description:"REST API ID",Value:e.ref("RestApi"),Export:{Name:e.sub("${AWS::StackName}-rest-api-id")}},RestApiEndpoint:{Description:"REST API endpoint",Value:e.sub("https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/prod"),Export:{Name:e.sub("${AWS::StackName}-rest-api-endpoint")}}})}function Fr(n,i){if(n.addResource("WebSocketApi","AWS::ApiGatewayV2::Api",{Name:e.sub("${AWS::StackName}-websocket-api"),ProtocolType:"WEBSOCKET",RouteSelectionExpression:"$request.body.action"}),i.routes){if(i.routes.connect)lt(n,"$connect",i.routes.connect.functionName);if(i.routes.disconnect)lt(n,"$disconnect",i.routes.disconnect.functionName);if(i.routes.default)lt(n,"$default",i.routes.default.functionName);if(i.routes.custom)i.routes.custom.forEach((s)=>{lt(n,s.routeKey,s.functionName)})}if(n.addResource("WebSocketApiStage","AWS::ApiGatewayV2::Stage",{ApiId:e.ref("WebSocketApi"),StageName:"prod",AutoDeploy:!0,DefaultRouteSettings:i.throttling?{ThrottlingBurstLimit:i.throttling.burstLimit,ThrottlingRateLimit:i.throttling.rateLimit}:void 0},{dependsOn:"WebSocketApi"}),i.customDomain)Rt(n,"WebSocketApi",i.customDomain,"WEBSOCKET");n.addOutputs({WebSocketApiId:{Description:"WebSocket API ID",Value:e.ref("WebSocketApi"),Export:{Name:e.sub("${AWS::StackName}-websocket-api-id")}},WebSocketApiEndpoint:{Description:"WebSocket API endpoint",Value:e.getAtt("WebSocketApi","ApiEndpoint"),Export:{Name:e.sub("${AWS::StackName}-websocket-api-endpoint")}}})}function lt(n,i,s){let o=n.toLogicalId(`websocket-route-${i}`),c=n.toLogicalId(`websocket-integration-${i}`),u=n.toLogicalId(`${s}-function`);n.addResource(c,"AWS::ApiGatewayV2::Integration",{ApiId:e.ref("WebSocketApi"),IntegrationType:"AWS_PROXY",IntegrationUri:e.sub(`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${u}.Arn}/invocations`)},{dependsOn:["WebSocketApi",u]}),n.addResource(o,"AWS::ApiGatewayV2::Route",{ApiId:e.ref("WebSocketApi"),RouteKey:i,Target:e.join("/",["integrations",e.ref(c)])},{dependsOn:["WebSocketApi",c]}),n.addResource(`${o}Permission`,"AWS::Lambda::Permission",{FunctionName:e.ref(u),Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:e.sub("arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${WebSocketApi}/*")},{dependsOn:[u,"WebSocketApi"]})}function Rt(n,i,s,o){let c={DomainName:s.domain};if(o==="REST")c.CertificateArn=s.certificateArn,c.EndpointConfiguration={Types:["REGIONAL"]},n.addResource("ApiCustomDomain","AWS::ApiGateway::DomainName",c),n.addResource("ApiBasePathMapping","AWS::ApiGateway::BasePathMapping",{DomainName:e.ref("ApiCustomDomain"),RestApiId:e.ref(i),Stage:e.ref("RestApiStage")},{dependsOn:["ApiCustomDomain",i,"RestApiStage"]});else c.DomainNameConfigurations=[{CertificateArn:s.certificateArn,EndpointType:"REGIONAL"}],n.addResource("ApiCustomDomain","AWS::ApiGatewayV2::DomainName",c),n.addResource("ApiMapping","AWS::ApiGatewayV2::ApiMapping",{ApiId:e.ref(i),DomainName:e.ref("ApiCustomDomain"),Stage:o==="HTTP"?e.ref("HttpApiStage"):e.ref("WebSocketApiStage")},{dependsOn:["ApiCustomDomain",i]});if(s.dnsProvider!=="external")n.addResource("ApiDNSRecord","AWS::Route53::RecordSet",{HostedZoneName:e.sub(`${_r(s.domain)}.`),Name:s.domain,Type:"A",AliasTarget:{HostedZoneId:e.getAtt("ApiCustomDomain","RegionalHostedZoneId"),DNSName:e.getAtt("ApiCustomDomain","RegionalDomainName"),EvaluateTargetHealth:!1}},{dependsOn:"ApiCustomDomain"});n.addOutputs({ApiCustomDomainName:{Description:"Configured API custom domain",Value:s.domain},ApiCustomDomainTarget:{Description:"DNS target for Route53 or an external DNS provider",Value:e.getAtt("ApiCustomDomain","RegionalDomainName")},ApiCustomDomainHostedZoneId:{Description:"Regional API Gateway hosted zone ID",Value:e.getAtt("ApiCustomDomain","RegionalHostedZoneId")}})}function Gr(n,i,s){if(!s)return;if(s.type==="jwt")n.addResource("ApiAuthorizer","AWS::ApiGatewayV2::Authorizer",{ApiId:e.ref(i),AuthorizerType:"JWT",IdentitySource:[s.identitySource||"$request.header.Authorization"],JwtConfiguration:{Issuer:s.issuer,Audience:s.audience},Name:"JWTAuthorizer"},{dependsOn:i});else if(s.type==="lambda")n.addResource("ApiAuthorizer","AWS::ApiGatewayV2::Authorizer",{ApiId:e.ref(i),AuthorizerType:"REQUEST",AuthorizerUri:s.authorizerUri,IdentitySource:[s.identitySource||"$request.header.Authorization"],Name:"LambdaAuthorizer"},{dependsOn:i})}function _r(n){let i=n.split(".");if(i.length>=2)return i.slice(-2).join(".");return n}function An(n,i){if(i.redis)Wr(n,i.redis);if(i.memcached)Vr(n,i.memcached);if(i.elasticache)Ur(n,i.elasticache)}function Wr(n,i){if(!i)return;if(n.addResource("CacheSubnetGroup","AWS::ElastiCache::SubnetGroup",{Description:"Subnet group for ElastiCache Redis cluster",SubnetIds:[e.ref("PrivateSubnet1"),e.ref("PrivateSubnet2")],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-subnet-group")}]},{dependsOn:["PrivateSubnet1","PrivateSubnet2"]}),n.addResource("CacheSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for ElastiCache Redis",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:i.port||6379,ToPort:i.port||6379,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-sg")}]},{dependsOn:["VPC","AppSecurityGroup"]}),i.parameterGroup&&Object.keys(i.parameterGroup).length>0)n.addResource("CacheParameterGroup","AWS::ElastiCache::ParameterGroup",{Description:"Parameter group for Redis",CacheParameterGroupFamily:`redis${i.engineVersion.split(".")[0]}`,Properties:i.parameterGroup});if(i.numCacheNodes>1||i.automaticFailoverEnabled)n.addResource("RedisReplicationGroup","AWS::ElastiCache::ReplicationGroup",{ReplicationGroupDescription:"Redis replication group",ReplicationGroupId:e.sub("${AWS::StackName}-redis"),Engine:"redis",EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheClusters:i.numCacheNodes,AutomaticFailoverEnabled:i.automaticFailoverEnabled||!1,MultiAZEnabled:i.automaticFailoverEnabled||!1,Port:i.port||6379,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),SecurityGroupIds:[e.ref("CacheSecurityGroup")],CacheParameterGroupName:i.parameterGroup?e.ref("CacheParameterGroup"):void 0,SnapshotRetentionLimit:i.snapshotRetentionLimit||5,SnapshotWindow:i.snapshotWindow||"03:00-05:00",PreferredMaintenanceWindow:"sun:05:00-sun:06:00",AtRestEncryptionEnabled:!0,TransitEncryptionEnabled:!0,Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-redis")}]},{dependsOn:i.parameterGroup?["CacheSubnetGroup","CacheSecurityGroup","CacheParameterGroup"]:["CacheSubnetGroup","CacheSecurityGroup"],deletionPolicy:"Snapshot",updateReplacePolicy:"Snapshot"}),n.addOutputs({RedisEndpoint:{Description:"Redis primary endpoint",Value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Address"),Export:{Name:e.sub("${AWS::StackName}-redis-endpoint")}},RedisPort:{Description:"Redis port",Value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Port"),Export:{Name:e.sub("${AWS::StackName}-redis-port")}}});else n.addResource("RedisCacheCluster","AWS::ElastiCache::CacheCluster",{ClusterName:e.sub("${AWS::StackName}-redis"),Engine:"redis",EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheNodes:1,Port:i.port||6379,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),VpcSecurityGroupIds:[e.ref("CacheSecurityGroup")],CacheParameterGroupName:i.parameterGroup?e.ref("CacheParameterGroup"):void 0,SnapshotRetentionLimit:i.snapshotRetentionLimit||5,SnapshotWindow:i.snapshotWindow||"03:00-05:00",PreferredMaintenanceWindow:"sun:05:00-sun:06:00",Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-redis")}]},{dependsOn:i.parameterGroup?["CacheSubnetGroup","CacheSecurityGroup","CacheParameterGroup"]:["CacheSubnetGroup","CacheSecurityGroup"],deletionPolicy:"Snapshot",updateReplacePolicy:"Snapshot"}),n.addOutputs({RedisEndpoint:{Description:"Redis endpoint",Value:e.getAtt("RedisCacheCluster","RedisEndpoint.Address"),Export:{Name:e.sub("${AWS::StackName}-redis-endpoint")}},RedisPort:{Description:"Redis port",Value:e.getAtt("RedisCacheCluster","RedisEndpoint.Port"),Export:{Name:e.sub("${AWS::StackName}-redis-port")}}})}function Vr(n,i){if(!i)return;if(!n.hasResource("CacheSubnetGroup"))n.addResource("CacheSubnetGroup","AWS::ElastiCache::SubnetGroup",{Description:"Subnet group for ElastiCache",SubnetIds:[e.ref("PrivateSubnet1"),e.ref("PrivateSubnet2")]},{dependsOn:["PrivateSubnet1","PrivateSubnet2"]});if(!n.hasResource("CacheSecurityGroup"))n.addResource("CacheSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for ElastiCache Memcached",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:i.port||11211,ToPort:i.port||11211,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-sg")}]},{dependsOn:["VPC","AppSecurityGroup"]});n.addResource("MemcachedCacheCluster","AWS::ElastiCache::CacheCluster",{ClusterName:e.sub("${AWS::StackName}-memcached"),Engine:"memcached",EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheNodes:i.numCacheNodes,Port:i.port||11211,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),VpcSecurityGroupIds:[e.ref("CacheSecurityGroup")],PreferredMaintenanceWindow:"sun:05:00-sun:06:00",Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-memcached")}]},{dependsOn:["CacheSubnetGroup","CacheSecurityGroup"]}),n.addOutputs({MemcachedEndpoint:{Description:"Memcached configuration endpoint",Value:e.getAtt("MemcachedCacheCluster","ConfigurationEndpoint.Address"),Export:{Name:e.sub("${AWS::StackName}-memcached-endpoint")}},MemcachedPort:{Description:"Memcached port",Value:e.getAtt("MemcachedCacheCluster","ConfigurationEndpoint.Port"),Export:{Name:e.sub("${AWS::StackName}-memcached-port")}}})}function Ur(n,i){if(!i)return;let s=i.engine==="redis";if(!n.hasResource("CacheSubnetGroup"))n.addResource("CacheSubnetGroup","AWS::ElastiCache::SubnetGroup",{Description:"Subnet group for ElastiCache",SubnetIds:[e.ref("PrivateSubnet1"),e.ref("PrivateSubnet2")]},{dependsOn:["PrivateSubnet1","PrivateSubnet2"]});if(!n.hasResource("CacheSecurityGroup"))n.addResource("CacheSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for ElastiCache",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:s?6379:11211,ToPort:s?6379:11211,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-cache-sg")}]},{dependsOn:["VPC","AppSecurityGroup"]});n.addResource("CacheCluster","AWS::ElastiCache::CacheCluster",{ClusterName:e.sub(`\${AWS::StackName}-${i.engine}`),Engine:i.engine,EngineVersion:i.engineVersion,CacheNodeType:i.nodeType,NumCacheNodes:i.numCacheNodes,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),VpcSecurityGroupIds:[e.ref("CacheSecurityGroup")],Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i.engine}`)}]},{dependsOn:["CacheSubnetGroup","CacheSecurityGroup"]})}function Cn(n,i){if(!i.enabled)return;n.addResource("CloudFrontOriginAccessIdentity","AWS::CloudFront::CloudFrontOriginAccessIdentity",{CloudFrontOriginAccessIdentityConfig:{Comment:e.sub("${AWS::StackName} CloudFront OAI")}});let s=[],o=[];if(!i.origins||i.origins.length===0)s.push({Id:"S3Origin",DomainName:e.getAtt("StaticBucket","DomainName"),S3OriginConfig:{OriginAccessIdentity:e.sub("origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}")}});else i.origins.forEach((d,p)=>{let y={Id:d.id,DomainName:d.domainName};if(d.originPath)y.OriginPath=d.originPath;if(d.domainName.includes("s3"))y.S3OriginConfig={OriginAccessIdentity:e.sub("origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}")};else y.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"]};if(s.push(y),p>0||d.pathPattern)o.push({PathPattern:d.pathPattern||`/${d.id}/*`,TargetOriginId:d.id,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD"],Compress:i.compress!==!1,ForwardedValues:{QueryString:!0,Cookies:{Forward:"none"}},MinTTL:i.cachePolicy?.minTTL||0,DefaultTTL:i.cachePolicy?.defaultTTL||86400,MaxTTL:i.cachePolicy?.maxTTL||31536000})});let c={TargetOriginId:s[0].Id,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD"],Compress:i.compress!==!1,ForwardedValues:{QueryString:!0,Cookies:{Forward:"none"}},MinTTL:i.cachePolicy?.minTTL||0,DefaultTTL:i.cachePolicy?.defaultTTL||86400,MaxTTL:i.cachePolicy?.maxTTL||31536000};if(i.edgeFunctions&&i.edgeFunctions.length>0)c.LambdaFunctionAssociations=i.edgeFunctions.map((d)=>({EventType:d.eventType,LambdaFunctionARN:d.functionArn}));let u={Enabled:!0,HttpVersion:i.http3?"http3":"http2",IPV6Enabled:!0,Origins:s,DefaultCacheBehavior:c,PriceClass:i.priceClass||"PriceClass_100",ViewerCertificate:{}};if(o.length>0)u.CacheBehaviors=o;if(i.customDomain)u.Aliases=[i.customDomain.domain],u.ViewerCertificate={AcmCertificateArn:i.customDomain.certificateArn,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else u.ViewerCertificate={CloudFrontDefaultCertificate:!0};if(i.errorPages)u.CustomErrorResponses=Object.entries(i.errorPages).map(([d,p])=>({ErrorCode:Number.parseInt(d),ResponseCode:200,ResponsePagePath:p,ErrorCachingMinTTL:300}));if(u.DefaultRootObject="index.html",u.Comment=e.sub("${AWS::StackName} CloudFront Distribution"),n.addResource("CloudFrontDistribution","AWS::CloudFront::Distribution",{DistributionConfig:u},{dependsOn:"CloudFrontOriginAccessIdentity"}),!i.origins||i.origins.length===0)n.addResource("StaticBucketPolicyForCloudFront","AWS::S3::BucketPolicy",{Bucket:e.ref("StaticBucket"),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontAccess",Effect:"Allow",Principal:{CanonicalUser:e.getAtt("CloudFrontOriginAccessIdentity","S3CanonicalUserId")},Action:"s3:GetObject",Resource:e.join("",[e.getAtt("StaticBucket","Arn"),"/*"])}]}},{dependsOn:["StaticBucket","CloudFrontOriginAccessIdentity"]});if(i.customDomain)n.addResource("CloudFrontDNSRecord","AWS::Route53::RecordSet",{HostedZoneName:e.sub(`${Hr(i.customDomain.domain)}.`),Name:i.customDomain.domain,Type:"A",AliasTarget:{HostedZoneId:"Z2FDTNDATAQYW2",DNSName:e.getAtt("CloudFrontDistribution","DomainName"),EvaluateTargetHealth:!1}},{dependsOn:"CloudFrontDistribution"});if(n.addOutputs({CloudFrontDistributionId:{Description:"CloudFront distribution ID",Value:e.ref("CloudFrontDistribution"),Export:{Name:e.sub("${AWS::StackName}-cloudfront-id")}},CloudFrontDomainName:{Description:"CloudFront distribution domain name",Value:e.getAtt("CloudFrontDistribution","DomainName"),Export:{Name:e.sub("${AWS::StackName}-cloudfront-domain")}}}),i.customDomain)n.addOutputs({CloudFrontURL:{Description:"CloudFront custom domain URL",Value:e.sub(`https://${i.customDomain.domain}`)}})}function Hr(n){let i=n.split(".");if(i.length>=2)return i.slice(-2).join(".");return n}function Tn(n,i){if(i.server)jr(n,i.server);if(i.fargate)vn(n,"app",i.fargate);if(i.services)i.services.forEach((s)=>{if(s.type==="fargate")vn(n,s.name,{taskDefinition:s.taskDefinition,service:s.service})})}function jr(n,i){if(!i)return;n.addResource("AppSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for application instances",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:3000,ToPort:3000,SourceSecurityGroupId:e.ref("ALBSecurityGroup")},{IpProtocol:"tcp",FromPort:22,ToPort:22,CidrIp:"0.0.0.0/0"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0"}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-app-sg")}]},{dependsOn:"VPC"}),n.addResource("EC2InstanceRole","AWS::IAM::Role",{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore","arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-ec2-role")}]}),n.addResource("EC2InstanceProfile","AWS::IAM::InstanceProfile",{Roles:[e.ref("EC2InstanceRole")]},{dependsOn:"EC2InstanceRole"});let s=i.userData||`#!/bin/bash
2434
2434
  set -e
2435
2435
  # Update system
2436
2436
  yum update -y || apt-get update -y
@@ -2451,30 +2451,30 @@ rpm -U ./amazon-cloudwatch-agent.rpm || true
2451
2451
  };`},Environment:i.environment?{Variables:i.environment}:void 0,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i.name}`)}]};if(s!=="edge")u.VpcConfig={SubnetIds:[e.ref("PrivateSubnet1"),e.ref("PrivateSubnet2")],SecurityGroupIds:[e.ref("AppSecurityGroup")]};if(n.addResource(o,"AWS::Lambda::Function",u,{dependsOn:c}),n.addResource(`${o}LogGroup`,"AWS::Logs::LogGroup",{LogGroupName:e.sub(`/aws/lambda/\${AWS::StackName}-${i.name}`),RetentionInDays:14}),i.events)i.events.forEach((d,p)=>{Qr(n,o,d,p)});n.addOutputs({[`${o}Arn`]:{Description:`${i.name} function ARN`,Value:e.getAtt(o,"Arn"),Export:{Name:e.sub(`\${AWS::StackName}-${i.name}-function-arn`)}}})}function Qr(n,i,s,o){let c=`${i}EventSource${o}`;switch(s.type){case"http":break;case"s3":if(s.bucket){let u=n.toLogicalId(`${s.bucket}-bucket`);n.addResource(`${c}Permission`,"AWS::Lambda::Permission",{FunctionName:e.ref(i),Action:"lambda:InvokeFunction",Principal:"s3.amazonaws.com",SourceArn:un.s3Bucket(e.ref(u))},{dependsOn:[i,u]})}break;case"sqs":if(s.queueName){let u=n.toLogicalId(`${s.queueName}-queue`);n.addResource(c,"AWS::Lambda::EventSourceMapping",{EventSourceArn:e.getAtt(u,"Arn"),FunctionName:e.ref(i),BatchSize:s.batchSize||10},{dependsOn:[i,u]})}break;case"kinesis":if(s.streamName){let u=n.toLogicalId(`${s.streamName}-stream`);n.addResource(c,"AWS::Lambda::EventSourceMapping",{EventSourceArn:e.getAtt(u,"Arn"),FunctionName:e.ref(i),BatchSize:s.batchSize||100,StartingPosition:s.startingPosition||"LATEST",ParallelizationFactor:s.parallelizationFactor||1},{dependsOn:[i,u]})}break;case"dynamodb-stream":if(s.tableName){let u=n.toLogicalId(`${s.tableName}-table`);n.addResource(c,"AWS::Lambda::EventSourceMapping",{EventSourceArn:e.getAtt(u,"StreamArn"),FunctionName:e.ref(i),BatchSize:s.batchSize||100,StartingPosition:s.startingPosition||"LATEST"},{dependsOn:[i,u]})}break;case"schedule":if(s.expression)n.addResource(`${c}Rule`,"AWS::Events::Rule",{ScheduleExpression:s.expression,State:"ENABLED",Targets:[{Arn:e.getAtt(i,"Arn"),Id:`${i}Target`}]},{dependsOn:i}),n.addResource(`${c}Permission`,"AWS::Lambda::Permission",{FunctionName:e.ref(i),Action:"lambda:InvokeFunction",Principal:"events.amazonaws.com",SourceArn:e.getAtt(`${c}Rule`,"Arn")},{dependsOn:[i,`${c}Rule`]});break}}function Jr(n){let i=[];if(!n)return i;if(n.forEach((s)=>{switch(s.type){case"s3":i.push({Effect:"Allow",Action:["s3:GetObject","s3:GetObjectVersion"],Resource:s.bucket?`arn:aws:s3:::${s.bucket}/*`:"arn:aws:s3:::*/*"});break;case"sqs":i.push({Effect:"Allow",Action:["sqs:ReceiveMessage","sqs:DeleteMessage","sqs:GetQueueAttributes"],Resource:s.queueName?un.sqs(s.queueName):"arn:aws:sqs:*:*:*"});break;case"kinesis":i.push({Effect:"Allow",Action:["kinesis:GetRecords","kinesis:GetShardIterator","kinesis:DescribeStream","kinesis:ListStreams"],Resource:s.streamName?un.kinesis(s.streamName):"arn:aws:kinesis:*:*:stream/*"});break;case"dynamodb-stream":i.push({Effect:"Allow",Action:["dynamodb:GetRecords","dynamodb:GetShardIterator","dynamodb:DescribeStream","dynamodb:ListStreams"],Resource:s.tableName?e.sub(`arn:aws:dynamodb:\${AWS::Region}:\${AWS::AccountId}:table/${s.tableName}/stream/*`):"arn:aws:dynamodb:*:*:table/*/stream/*"});break}}),i.length===0)i.push({Effect:"Allow",Action:["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],Resource:"arn:aws:logs:*:*:*"});return i}function wn(n,i){if(i.topics)i.topics.forEach((s)=>{Yr(n,s)})}function Yr(n,i){let s=n.toLogicalId(`${i.name}-topic`);if(n.addResource(s,"AWS::SNS::Topic",{TopicName:e.sub(`\${AWS::StackName}-${i.name}`),DisplayName:i.displayName||i.name,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i.name}`)}]}),n.addResource(`${s}Policy`,"AWS::SNS::TopicPolicy",{Topics:[e.ref(s)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["events.amazonaws.com","cloudwatch.amazonaws.com","s3.amazonaws.com"]},Action:"sns:Publish",Resource:e.ref(s)},{Effect:"Allow",Principal:{AWS:e.sub("arn:aws:iam::${AWS::AccountId}:root")},Action:["sns:Subscribe","sns:Publish","sns:Receive"],Resource:e.ref(s)}]}},{dependsOn:s}),i.subscriptions)i.subscriptions.forEach((o,c)=>{let u=`${s}Subscription${c+1}`,d={Protocol:o.protocol,TopicArn:e.ref(s),Endpoint:o.endpoint};if(o.filterPolicy)d.FilterPolicy=o.filterPolicy;if(o.protocol==="sqs"){let p=n.toLogicalId(`${o.endpoint}-queue`);d.Endpoint=e.getAtt(p,"Arn")}if(o.protocol==="lambda"){let p=n.toLogicalId(o.endpoint);d.Endpoint=e.getAtt(p,"Arn"),n.addResource(`${u}Permission`,"AWS::Lambda::Permission",{FunctionName:e.ref(p),Action:"lambda:InvokeFunction",Principal:"sns.amazonaws.com",SourceArn:e.ref(s)},{dependsOn:[p,s]})}n.addResource(u,"AWS::SNS::Subscription",d,{dependsOn:s})});n.addOutputs({[`${s}Arn`]:{Description:`${i.name} topic ARN`,Value:e.ref(s),Export:{Name:e.sub(`\${AWS::StackName}-${i.name}-topic-arn`)}}})}function In(n,i){if(i.alarms&&i.alarms.length>0)n.addResource("AlarmTopic","AWS::SNS::Topic",{TopicName:e.sub("${AWS::StackName}-alarms"),DisplayName:"CloudWatch Alarms",Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-alarms")}]}),i.alarms.forEach((s,o)=>{Zr(n,s,o)});if(i.dashboard)Xr(n,i.dashboard);if(i.logs?.groups)i.logs.groups.forEach((s)=>{ei(n,s,i.logs?.retention)})}function Zr(n,i,s){let o=n.toLogicalId(`alarm-${i.name||i.metric}-${s}`),c={AlarmName:i.name||e.sub(`\${AWS::StackName}-${i.metric}`),AlarmDescription:`Alarm for ${i.metric}`,MetricName:i.metric,Namespace:i.namespace||Et(i.metric,i.service),Statistic:i.statistic||"Average",Period:i.period||300,EvaluationPeriods:i.evaluationPeriods||1,Threshold:i.threshold,ComparisonOperator:i.comparisonOperator||"GreaterThanThreshold",TreatMissingData:i.treatMissingData||"notBreaching",AlarmActions:[e.ref("AlarmTopic")],OKActions:[e.ref("AlarmTopic")]};if(i.dimensions)c.Dimensions=Object.entries(i.dimensions).map(([u,d])=>({Name:u,Value:d}));else if(i.service)c.Dimensions=ti(i.service);n.addResource(o,"AWS::CloudWatch::Alarm",c,{dependsOn:"AlarmTopic"})}function Xr(n,i){if(!i)return;let s=[],o=0,c=0;i.widgets?.forEach((u)=>{let d=u.width||12,p=u.height||6;if(u.type==="metric"&&u.metrics){let y=u.metrics.map((h)=>{if(typeof h==="string")return[Et(h),h];else return[Et(h.metric,h.service),h.metric]});s.push({type:"metric",x:o,y:c,width:d,height:p,properties:{metrics:y,period:300,stat:"Average",region:e.ref("AWS::Region"),title:u.metrics.length>1?"Multiple Metrics":typeof u.metrics[0]==="string"?u.metrics[0]:u.metrics[0].metric}})}else if(u.type==="log"&&u.logGroup)s.push({type:"log",x:o,y:c,width:d,height:p,properties:{query:`SOURCE '${u.logGroup}'
2452
2452
  | fields @timestamp, @message
2453
2453
  | sort @timestamp desc
2454
- | limit 20`,region:e.ref("AWS::Region"),title:`Logs: ${u.logGroup}`}});else if(u.type==="text"&&u.text)s.push({type:"text",x:o,y:c,width:d,height:p,properties:{markdown:u.text}});if(o+=d,o>=24)o=0,c+=p}),n.addResource("CloudWatchDashboard","AWS::CloudWatch::Dashboard",{DashboardName:e.sub(`\${AWS::StackName}-${i.name}`),DashboardBody:JSON.stringify({widgets:s})}),n.addOutputs({DashboardURL:{Description:"CloudWatch Dashboard URL",Value:e.sub("https://console.aws.amazon.com/cloudwatch/home?region=${AWS::Region}#dashboards:name=${CloudWatchDashboard}")}})}function ei(n,i,s){let o=n.toLogicalId(`${i}-log-group`);n.addResource(o,"AWS::Logs::LogGroup",{LogGroupName:e.sub(`/aws/\${AWS::StackName}/${i}`),RetentionInDays:s||14,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]})}function Et(n,i){if(i)return{ec2:"AWS/EC2",ecs:"AWS/ECS",lambda:"AWS/Lambda",rds:"AWS/RDS",dynamodb:"AWS/DynamoDB",s3:"AWS/S3",cloudfront:"AWS/CloudFront",alb:"AWS/ApplicationELB",nlb:"AWS/NetworkELB",apigateway:"AWS/ApiGateway",sqs:"AWS/SQS",sns:"AWS/SNS",kinesis:"AWS/Kinesis",elasticache:"AWS/ElastiCache"}[i.toLowerCase()]||"AWS/CloudWatch";let s=n.toLowerCase();if(s.includes("cpu")||s.includes("memory")||s.includes("network"))return"AWS/EC2";if(s.includes("lambda")||s.includes("invocation")||s.includes("duration"))return"AWS/Lambda";if(s.includes("request")||s.includes("latency")||s.includes("target"))return"AWS/ApplicationELB";if(s.includes("database")||s.includes("connection"))return"AWS/RDS";if(s.includes("read")||s.includes("write")||s.includes("consumed"))return"AWS/DynamoDB";return"AWS/CloudWatch"}function ti(n){return{ec2:[{Name:"InstanceId",Value:e.ref("EC2Instance")}],ecs:[{Name:"ClusterName",Value:e.ref("ECSCluster")},{Name:"ServiceName",Value:e.getAtt("ECSService","Name")}],lambda:[{Name:"FunctionName",Value:e.ref("LambdaFunction")}],rds:[{Name:"DBInstanceIdentifier",Value:e.ref("Database")}],dynamodb:[{Name:"TableName",Value:e.ref("DynamoDBTable")}],alb:[{Name:"LoadBalancer",Value:e.getAtt("LoadBalancer","LoadBalancerFullName")}],apigateway:[{Name:"ApiName",Value:e.ref("HttpApi")}]}[n.toLowerCase()]||[]}function Dn(n,i){if(!i.vpc)return;let{cidr:s="10.0.0.0/16",availabilityZones:o=2,natGateways:c=1,enableDnsHostnames:u=!0,enableDnsSupport:d=!0}=i.vpc;n.addResource("VPC","AWS::EC2::VPC",{CidrBlock:s,EnableDnsHostnames:u,EnableDnsSupport:d,Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-vpc")}]}),n.addResource("InternetGateway","AWS::EC2::InternetGateway",{Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-igw")}]}),n.addResource("VPCGatewayAttachment","AWS::EC2::VPCGatewayAttachment",{VpcId:e.ref("VPC"),InternetGatewayId:e.ref("InternetGateway")},{dependsOn:["VPC","InternetGateway"]});let p=[];for(let v=0;v<o;v++){let A=`PublicSubnet${v+1}`;p.push(A),n.addResource(A,"AWS::EC2::Subnet",{VpcId:e.ref("VPC"),CidrBlock:e.select(v,e.cidr(e.getAtt("VPC","CidrBlock"),o*2,8)),AvailabilityZone:e.select(v,e.getAZs()),MapPublicIpOnLaunch:!0,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-public-${v+1}`)},{Key:"Type",Value:"public"}]},{dependsOn:"VPC"})}let y=[];for(let v=0;v<o;v++){let A=`PrivateSubnet${v+1}`;y.push(A),n.addResource(A,"AWS::EC2::Subnet",{VpcId:e.ref("VPC"),CidrBlock:e.select(v+o,e.cidr(e.getAtt("VPC","CidrBlock"),o*2,8)),AvailabilityZone:e.select(v,e.getAZs()),MapPublicIpOnLaunch:!1,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-private-${v+1}`)},{Key:"Type",Value:"private"}]},{dependsOn:"VPC"})}let h=[];for(let v=0;v<c;v++){let A=`NatEIP${v+1}`;h.push(A),n.addResource(A,"AWS::EC2::EIP",{Domain:"vpc",Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-nat-eip-${v+1}`)}]},{dependsOn:"VPCGatewayAttachment"})}let b=[];for(let v=0;v<c;v++){let A=`NatGateway${v+1}`;b.push(A);let T=v%o;n.addResource(A,"AWS::EC2::NatGateway",{AllocationId:e.getAtt(h[v],"AllocationId"),SubnetId:e.ref(p[T]),Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-nat-${v+1}`)}]},{dependsOn:[h[v],p[T]]})}n.addResource("PublicRouteTable","AWS::EC2::RouteTable",{VpcId:e.ref("VPC"),Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-public-rt")}]},{dependsOn:"VPC"}),n.addResource("PublicRoute","AWS::EC2::Route",{RouteTableId:e.ref("PublicRouteTable"),DestinationCidrBlock:"0.0.0.0/0",GatewayId:e.ref("InternetGateway")},{dependsOn:["PublicRouteTable","VPCGatewayAttachment"]}),p.forEach((v,A)=>{n.addResource(`PublicSubnetRouteTableAssociation${A+1}`,"AWS::EC2::SubnetRouteTableAssociation",{SubnetId:e.ref(v),RouteTableId:e.ref("PublicRouteTable")},{dependsOn:[v,"PublicRouteTable"]})}),y.forEach((v,A)=>{let T=`PrivateRouteTable${A+1}`,R=A%c;n.addResource(T,"AWS::EC2::RouteTable",{VpcId:e.ref("VPC"),Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-private-rt-${A+1}`)}]},{dependsOn:"VPC"}),n.addResource(`PrivateRoute${A+1}`,"AWS::EC2::Route",{RouteTableId:e.ref(T),DestinationCidrBlock:"0.0.0.0/0",NatGatewayId:e.ref(b[R])},{dependsOn:[T,b[R]]}),n.addResource(`PrivateSubnetRouteTableAssociation${A+1}`,"AWS::EC2::SubnetRouteTableAssociation",{SubnetId:e.ref(v),RouteTableId:e.ref(T)},{dependsOn:[v,T]})}),n.addResource("S3VPCEndpoint","AWS::EC2::VPCEndpoint",{VpcId:e.ref("VPC"),ServiceName:e.sub("com.amazonaws.${AWS::Region}.s3"),VpcEndpointType:"Gateway",RouteTableIds:[e.ref("PublicRouteTable"),...Array.from({length:o},(v,A)=>e.ref(`PrivateRouteTable${A+1}`))]},{dependsOn:"VPC"}),n.addResource("NetworkAcl","AWS::EC2::NetworkAcl",{VpcId:e.ref("VPC"),Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-nacl")}]},{dependsOn:"VPC"}),n.addResource("NetworkAclEntryInbound","AWS::EC2::NetworkAclEntry",{NetworkAclId:e.ref("NetworkAcl"),RuleNumber:100,Protocol:-1,RuleAction:"allow",CidrBlock:"0.0.0.0/0"},{dependsOn:"NetworkAcl"}),n.addResource("NetworkAclEntryOutbound","AWS::EC2::NetworkAclEntry",{NetworkAclId:e.ref("NetworkAcl"),RuleNumber:100,Protocol:-1,Egress:!0,RuleAction:"allow",CidrBlock:"0.0.0.0/0"},{dependsOn:"NetworkAcl"}),n.addOutputs({VPCId:{Description:"VPC ID",Value:e.ref("VPC"),Export:{Name:e.sub("${AWS::StackName}-VPC")}},PublicSubnets:{Description:"Public subnet IDs",Value:e.join(",",p.map((v)=>e.ref(v))),Export:{Name:e.sub("${AWS::StackName}-PublicSubnets")}},PrivateSubnets:{Description:"Private subnet IDs",Value:e.join(",",y.map((v)=>e.ref(v))),Export:{Name:e.sub("${AWS::StackName}-PrivateSubnets")}}})}function Nn(n,i){for(let[s,o]of Object.entries(i))ni(n,s,o)}function ni(n,i,s){let o=n.toLogicalId(`${i}-queue`),c=s.fifo||!1,u;if(s.deadLetterQueue){let p=`${o}DLQ`;n.addResource(p,"AWS::SQS::Queue",{QueueName:c?e.sub(`\${AWS::StackName}-${i}-dlq.fifo`):e.sub(`\${AWS::StackName}-${i}-dlq`),FifoQueue:c,MessageRetentionPeriod:1209600,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}-dlq`)}]},{deletionPolicy:"Retain",updateReplacePolicy:"Retain"}),u=e.getAtt(p,"Arn")}let d={QueueName:c?e.sub(`\${AWS::StackName}-${i}.fifo`):e.sub(`\${AWS::StackName}-${i}`),FifoQueue:c,VisibilityTimeout:s.visibilityTimeout||30,MessageRetentionPeriod:s.messageRetentionPeriod||345600,ReceiveMessageWaitTimeSeconds:s.receiveMessageWaitTime||0,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]};if(c&&s.contentBasedDeduplication)d.ContentBasedDeduplication=!0;if(s.deadLetterQueue&&u)d.RedrivePolicy={deadLetterTargetArn:u,maxReceiveCount:s.maxReceiveCount||3};if(n.addResource(o,"AWS::SQS::Queue",d,{dependsOn:s.deadLetterQueue?`${o}DLQ`:void 0,deletionPolicy:"Retain",updateReplacePolicy:"Retain"}),n.addResource(`${o}Policy`,"AWS::SQS::QueuePolicy",{Queues:[e.ref(o)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["lambda.amazonaws.com","events.amazonaws.com","sns.amazonaws.com"]},Action:"sqs:SendMessage",Resource:e.getAtt(o,"Arn"),Condition:{ArnEquals:{"aws:SourceArn":e.sub("arn:aws:*:${AWS::Region}:${AWS::AccountId}:*")}}}]}},{dependsOn:o}),n.addOutputs({[`${o}Url`]:{Description:`${i} queue URL`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-queue-url`)}},[`${o}Arn`]:{Description:`${i} queue ARN`,Value:e.getAtt(o,"Arn"),Export:{Name:e.sub(`\${AWS::StackName}-${i}-queue-arn`)}}}),s.deadLetterQueue)n.addOutputs({[`${o}DLQUrl`]:{Description:`${i} dead letter queue URL`,Value:e.ref(`${o}DLQ`),Export:{Name:e.sub(`\${AWS::StackName}-${i}-dlq-url`)}}})}function xn(n,i){if(i.certificate)ri(n,i.certificate);if(i.waf?.enabled)ii(n,i.waf);if(i.securityGroups)for(let[s,o]of Object.entries(i.securityGroups))ai(n,s,o)}function ri(n,i){if(!i)return;let s=[i.domain];if(i.subdomains)s.push(...i.subdomains);n.addResource("Certificate","AWS::CertificateManager::Certificate",{DomainName:i.domain,SubjectAlternativeNames:i.subdomains,ValidationMethod:i.validationMethod||"DNS",DomainValidationOptions:s.map((o)=>({DomainName:o,HostedZoneId:e.ref("HostedZone")})),Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-certificate")}]}),n.addOutputs({CertificateArn:{Description:"ACM Certificate ARN",Value:e.ref("Certificate"),Export:{Name:e.sub("${AWS::StackName}-certificate-arn")}}})}function ii(n,i){if(!i)return;let s=[],o=i.rules||["rateLimit","sqlInjection","xss"];if(o.includes("rateLimit"))s.push({Name:"RateLimitRule",Priority:1,Statement:{RateBasedStatement:{Limit:i.rateLimit||2000,AggregateKeyType:"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"RateLimitRule"}});let c=s.length+1;if(o.includes("sqlInjection"))s.push({Name:"AWSManagedRulesSQLi",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesSQLiRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesSQLi"}});if(o.includes("xss"))s.push({Name:"AWSManagedRulesXSS",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesKnownBadInputsRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesXSS"}});if(o.includes("knownBadInputs"))s.push({Name:"AWSManagedRulesKnownBadInputs",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesKnownBadInputsRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesKnownBadInputs"}});if(o.includes("coreRuleSet"))s.push({Name:"AWSManagedRulesCoreRuleSet",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesCommonRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesCoreRuleSet"}});if(o.includes("linuxRuleSet"))s.push({Name:"AWSManagedRulesLinuxRuleSet",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesLinuxRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesLinuxRuleSet"}});if(o.includes("apiProtection"))s.push({Name:"AWSManagedRulesAPIProtection",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesAmazonIpReputationList"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesAPIProtection"}});if(o.includes("geoBlock"))s.push({Name:"GeoBlockRule",Priority:c++,Statement:{GeoMatchStatement:{CountryCodes:["CN","RU"]}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"GeoBlockRule"}});if(o.includes("connectionLimit"))s.push({Name:"ConnectionLimitRule",Priority:c++,Statement:{RateBasedStatement:{Limit:100,AggregateKeyType:"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"ConnectionLimitRule"}});if(n.addResource("WebACL","AWS::WAFv2::WebACL",{Name:e.sub("${AWS::StackName}-waf"),Scope:i.scope||"REGIONAL",DefaultAction:{Allow:{}},Rules:s,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:e.sub("${AWS::StackName}-waf")},Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-waf")}]}),n.hasResource("LoadBalancer"))n.addResource("WebACLAssociation","AWS::WAFv2::WebACLAssociation",{ResourceArn:e.ref("LoadBalancer"),WebACLArn:e.getAtt("WebACL","Arn")},{dependsOn:["WebACL","LoadBalancer"]});n.addOutputs({WebACLId:{Description:"WAF Web ACL ID",Value:e.ref("WebACL"),Export:{Name:e.sub("${AWS::StackName}-waf-id")}},WebACLArn:{Description:"WAF Web ACL ARN",Value:e.getAtt("WebACL","Arn"),Export:{Name:e.sub("${AWS::StackName}-waf-arn")}}})}function ai(n,i,s){if(!s)return;let o=n.toLogicalId(`${i}-security-group`),c=s.ingress?.map((d)=>({IpProtocol:d.protocol,FromPort:d.port,ToPort:d.port,CidrIp:d.cidr,SourceSecurityGroupId:d.source?e.ref(d.source):void 0}))||[],u=s.egress?.map((d)=>({IpProtocol:d.protocol,FromPort:d.port,ToPort:d.port,CidrIp:d.cidr||"0.0.0.0/0"}))||[{IpProtocol:"-1",CidrIp:"0.0.0.0/0"}];n.addResource(o,"AWS::EC2::SecurityGroup",{GroupDescription:`Security group for ${i}`,VpcId:e.ref("VPC"),SecurityGroupIngress:c,SecurityGroupEgress:u,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}-sg`)}]},{dependsOn:"VPC"}),n.addOutputs({[`${o}Id`]:{Description:`${i} security group ID`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-sg-id`)}}})}function kn(n,i){for(let[s,o]of Object.entries(i)){if(o.type==="efs"){oi(n,s,o);continue}si(n,s,o)}}function si(n,i,s){let o=n.toLogicalId(`${i}-bucket`),c={BucketName:e.sub(`\${AWS::StackName}-${i}`),Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]};if(s.versioning)c.VersioningConfiguration={Status:"Enabled"};if(s.encryption)c.BucketEncryption={ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]};if(!s.public)c.PublicAccessBlockConfiguration={BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0};if(s.website)c.WebsiteConfiguration={IndexDocument:"index.html",ErrorDocument:"index.html"};if(s.cors&&s.cors.length>0)c.CorsConfiguration={CorsRules:s.cors.map((u)=>({AllowedOrigins:u.allowedOrigins,AllowedMethods:u.allowedMethods,AllowedHeaders:u.allowedHeaders||["*"],MaxAge:u.maxAge||3600}))};if(s.lifecycleRules&&s.lifecycleRules.length>0)c.LifecycleConfiguration={Rules:s.lifecycleRules.map((u)=>({Id:u.id,Status:u.enabled?"Enabled":"Disabled",ExpirationInDays:u.expirationDays,Transitions:u.transitions?.map((d)=>({TransitionInDays:d.days,StorageClass:d.storageClass}))}))};if(s.intelligentTiering)c.IntelligentTieringConfigurations=[{Id:"EntireBucket",Status:"Enabled",Tierings:[{AccessTier:"ARCHIVE_ACCESS",Days:90},{AccessTier:"DEEP_ARCHIVE_ACCESS",Days:180}]}];if(n.addResource(o,"AWS::S3::Bucket",c,{deletionPolicy:s.versioning?"Retain":"Delete"}),s.public)n.addResource(`${o}Policy`,"AWS::S3::BucketPolicy",{Bucket:e.ref(o),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadGetObject",Effect:"Allow",Principal:"*",Action:"s3:GetObject",Resource:e.join("",[un.s3Bucket(e.ref(o)),"/*"])}]}},{dependsOn:o});if(n.addOutputs({[`${o}Name`]:{Description:`${i} bucket name`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-bucket`)}},[`${o}Arn`]:{Description:`${i} bucket ARN`,Value:e.getAtt(o,"Arn"),Export:{Name:e.sub(`\${AWS::StackName}-${i}-bucket-arn`)}}}),s.website)n.addOutputs({[`${o}WebsiteURL`]:{Description:`${i} website URL`,Value:e.getAtt(o,"WebsiteURL")}})}function oi(n,i,s){let o=n.toLogicalId(`${i}-efs`),c={Encrypted:s.encryption!==!1,PerformanceMode:s.performanceMode||"generalPurpose",ThroughputMode:s.throughputMode||"bursting",FileSystemTags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]};if(s.lifecyclePolicy){if(c.LifecyclePolicies=[],s.lifecyclePolicy.transitionToIA)c.LifecyclePolicies.push({TransitionToIA:`AFTER_${s.lifecyclePolicy.transitionToIA}_DAYS`});if(s.lifecyclePolicy.transitionToPrimaryStorageClass)c.LifecyclePolicies.push({TransitionToPrimaryStorageClass:"AFTER_1_ACCESS"})}n.addResource(o,"AWS::EFS::FileSystem",c,{deletionPolicy:"Retain"});let u=2;for(let d=0;d<u;d++)n.addResource(`${o}MountTarget${d+1}`,"AWS::EFS::MountTarget",{FileSystemId:e.ref(o),SubnetId:e.ref(`PrivateSubnet${d+1}`),SecurityGroups:[e.ref("EFSSecurityGroup")]},{dependsOn:[o,`PrivateSubnet${d+1}`]});n.addResource("EFSSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for EFS mount targets",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:2049,ToPort:2049,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-efs-sg")}]},{dependsOn:"VPC"}),n.addOutputs({[`${o}Id`]:{Description:`${i} EFS file system ID`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-efs`)}}})}class Nm{template;config;resourceDependencies;constructor(n){this.config=n,this.resourceDependencies=new Map,this.template={AWSTemplateFormatVersion:"2010-09-09",Description:`Infrastructure for ${n.project.name} (${n.project.slug})`,Resources:{}}}build(){return this.addParameters(),this.addMappings(),this.addConditions(),this.addResources(),this.initializeOutputs(),this.resolveDependencies(),this.template}addParameters(){this.template.Parameters={Environment:{Type:"String",Default:"production",AllowedValues:["development","staging","production"],Description:"Environment name"}}}addMappings(){this.template.Mappings={RegionMap:{"us-east-1":{AMI:"ami-0f3caa1cf4417e51b"},"us-west-2":{AMI:"ami-0d1cd67c26f5fca19"},"eu-west-1":{AMI:"ami-0bbc25e23a7640b9b"}}}}addConditions(){this.template.Conditions={IsProduction:e.equals(e.ref("Environment"),"production"),HasDomain:e.not([e.equals(this.config.environments?.production?.domain||"","")])}}addResources(){let{infrastructure:n}=this.config;if(!n)return;if(n.network)this.addNetworkResources(n.network);if(n.storage)this.addStorageResources(n.storage);if(n.compute)this.addComputeResources(n.compute);if(n.databases)this.addDatabaseResources(n.databases);if(n.cache)this.addCacheResources(n.cache);if(n.cdn)this.addCDNResources(n.cdn);if(n.apiGateway)this.addApiGatewayResources(n.apiGateway);if(n.functions)this.addFunctionResources(n.functions);if(n.queues)this.addQueueResources(n.queues);if(n.messaging)this.addMessagingResources(n.messaging);if(n.monitoring)this.addMonitoringResources(n.monitoring);if(n.security)this.addSecurityResources(n.security)}initializeOutputs(){let n=this.template.Outputs||{};if(this.template.Outputs={StackName:{Description:"Stack name",Value:e.ref("AWS::StackName"),Export:{Name:e.sub("${AWS::StackName}-Name")}},Region:{Description:"AWS Region",Value:e.ref("AWS::Region"),Export:{Name:e.sub("${AWS::StackName}-Region")}},...n},this.config.environments?.production?.domain)this.template.Outputs.Domain={Description:"Production domain",Value:this.config.environments.production.domain,Condition:"HasDomain"}}addResource(n,i,s,o){let c={Type:i,Properties:s};if(o?.dependsOn)c.DependsOn=o.dependsOn,this.trackDependency(n,o.dependsOn);if(o?.condition)c.Condition=o.condition;if(o?.deletionPolicy)c.DeletionPolicy=o.deletionPolicy;if(o?.updateReplacePolicy)c.UpdateReplacePolicy=o.updateReplacePolicy;this.template.Resources[n]=c}addOutputs(n){this.template.Outputs={...this.template.Outputs,...n}}getOutputs(){return this.template.Outputs||{}}hasResource(n){return n in this.template.Resources}getResource(n){return this.template.Resources[n]}trackDependency(n,i){if(!this.resourceDependencies.has(n))this.resourceDependencies.set(n,new Set);(Array.isArray(i)?i:[i]).forEach((o)=>this.resourceDependencies.get(n).add(o))}resolveDependencies(){let n=new Set,i=new Set,s=(o)=>{if(i.has(o))throw Error(`Circular dependency detected involving resource: ${o}`);if(n.has(o))return!0;n.add(o),i.add(o);let c=this.resourceDependencies.get(o);if(c)for(let u of c)s(u);return i.delete(o),!0};for(let o of this.resourceDependencies.keys())s(o)}toLogicalId(n){return n.split(/[-_\s]/).map((i)=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join("")}addNetworkResources(n){Dn(this,n)}addStorageResources(n){kn(this,n)}addComputeResources(n){Tn(this,n)}addDatabaseResources(n){Pn(this,n)}addFunctionResources(n){En(this,n)}addCacheResources(n){An(this,n)}addQueueResources(n){Nn(this,n)}addMessagingResources(n){wn(this,n)}addCDNResources(n){Cn(this,n)}addApiGatewayResources(n){Sn(this,n)}addMonitoringResources(n){In(this,n)}addSecurityResources(n){xn(this,n)}}function fl(n){return new Nm(n).build()}function JI(n){let{name:i,slug:s,domain:o,subdomain:c}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:c&&o?`${c}.${o}`:o}},infrastructure:{storage:{assets:{public:!0,versioning:!1,website:!0,encryption:!1,cors:[{allowedOrigins:["*"],allowedMethods:["GET","HEAD"],allowedHeaders:["*"],maxAge:3600}]}},cdn:{enabled:!0,customDomain:o?{domain:c&&o?`${c}.${o}`:o,certificateArn:"TO_BE_GENERATED"}:void 0,cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0,errorPages:{404:"/index.html",403:"/index.html"}}}}}function XI(n){let{name:i,slug:s,domain:o,instanceType:c="t3.small",minInstances:u=2,maxInstances:d=10}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},compute:{server:{instanceType:c,ami:"ubuntu-22.04",keyPair:`${s}-key`,autoScaling:{min:u,max:d,desired:u,targetCPU:70},loadBalancer:{type:"application",healthCheck:{path:"/health",interval:30,timeout:5,healthyThreshold:2,unhealthyThreshold:3}},userData:{packages:["nodejs","npm","nginx"],commands:["curl -fsSL https://bun.sh/install | bash","npm install -g pm2"]}}},databases:{postgres:{engine:"postgres",version:"15",instanceClass:"db.t3.micro",allocatedStorage:20,multiAZ:!0,backupRetentionDays:7,deletionProtection:!0}},cache:{redis:{nodeType:"cache.t3.micro",numCacheNodes:1,engine:"redis",engineVersion:"7.0"}},security:{certificate:o?{domain:o,subdomains:[`*.${o}`],validationMethod:"DNS"}:void 0}}}}function YI(n){let{name:i,slug:s,domain:o,taskCpu:c="256",taskMemory:u="512",desiredCount:d=2}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:0}},compute:{fargate:{taskDefinition:{cpu:c,memory:u,containerDefinitions:[{name:"app",image:`${s}-app:latest`,portMappings:[{containerPort:3000}],environment:[],secrets:[]}]},service:{desiredCount:d,healthCheck:{path:"/health",interval:30,timeout:5,healthyThreshold:2,unhealthyThreshold:3},autoScaling:{min:d,max:d*5,targetCPU:70,targetMemory:80}},loadBalancer:{type:"application"}}},databases:{dynamodb:{tables:{[`${s}-main`]:{partitionKey:{name:"id",type:"S"},sortKey:{name:"createdAt",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0}}}},functions:{"process-queue":{runtime:"nodejs20.x",handler:"dist/workers/queue.handler",memory:512,timeout:60,events:[{type:"sqs",queueName:`${s}-queue`}]}},security:{certificate:o?{domain:o,subdomains:[`*.${o}`],validationMethod:"DNS"}:void 0}}}}function ZI(n){let{name:i,slug:s,entry:o,domain:c,runtime:u="nodejs20.x",memory:d=1024,build:p,deploy:y,assets:h,queues:b=!0,scheduler:v="on",region:A="us-east-1"}=n;return{project:{name:i,slug:s,region:A},mode:"serverless",environments:{production:{type:"production",domain:c,app:{kind:"node",runtime:u,entry:o,memory:d,build:p,deploy:y,assets:h,queues:b,scheduler:v,domain:c}}}}}function hl(n){let i=n.database!==!1,s=n.cache!==!1,o=n.queue!==!1;return{project:{name:n.name,slug:n.slug,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:n.domain}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},compute:{fargate:{taskDefinition:{cpu:"256",memory:"512",containerDefinitions:[{name:"api",image:n.imageUri,portMappings:[{containerPort:3000}],environment:[{name:"NODE_ENV",value:"production"},{name:"PORT",value:"3000"},{name:"AWS_REGION",value:e.ref("AWS::Region")},...i?[{name:"DB_HOST",value:e.getAtt("PostgresDb","Endpoint.Address")},{name:"DB_PORT",value:e.getAtt("PostgresDb","Endpoint.Port")}]:[],...s?[{name:"REDIS_HOST",value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Address")},{name:"REDIS_PORT",value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Port")},{name:"REDIS_TLS",value:"true"}]:[],...o?[{name:"QUEUE_URL",value:e.ref("JobsQueue")}]:[],{name:"MAIL_TRANSPORT",value:"ses"}],secrets:i?[{name:"DB_USERNAME",valueFrom:e.sub("${DBSecret}:username::")},{name:"DB_PASSWORD",valueFrom:e.sub("${DBSecret}:password::")}]:[]}]},service:{desiredCount:n.desiredCount||1,healthCheck:{path:"/api/health",interval:30,timeout:5},autoScaling:{min:n.desiredCount||1,max:6,targetCPU:70}},loadBalancer:{type:"application",...n.certificateArn?{customDomain:{domain:n.domain,certificateArn:n.certificateArn}}:{},...n.originVerifySecret?{originVerifyHeader:{name:"X-Origin-Verify",value:n.originVerifySecret}}:{}}}},...i?{databases:{postgres:{engine:"postgres",version:"16",instanceClass:"db.t4g.micro",allocatedStorage:20,maxAllocatedStorage:100,multiAZ:!1,backupRetentionDays:7,deletionProtection:!0}}}:{},...s?{cache:{redis:{nodeType:"cache.t4g.micro",numCacheNodes:2,engine:"redis",engineVersion:"7.1",automaticFailoverEnabled:!0,snapshotRetentionLimit:5}}}:{},...o?{queues:{jobs:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:345600,deadLetterQueue:!0,maxReceiveCount:3,receiveMessageWaitTime:20}}}:{}}}}function eb(n){let{name:i,slug:s,domain:o,apiSubdomain:c="api"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},storage:{frontend:{public:!0,versioning:!0,website:!0,encryption:!1}},cdn:{enabled:!0,customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0,errorPages:{404:"/index.html"}},compute:{fargate:{taskDefinition:{cpu:"512",memory:"1024",containerDefinitions:[{name:"api",image:`${s}-api:latest`,portMappings:[{containerPort:3000}]}]},service:{desiredCount:2,healthCheck:{path:"/api/health",interval:30},autoScaling:{min:2,max:10,targetCPU:70}},loadBalancer:{type:"application",customDomain:{domain:`${c}.${o}`,certificateArn:"TO_BE_GENERATED"}}}},databases:{postgres:{engine:"postgres",version:"15",instanceClass:"db.t3.small",allocatedStorage:50,multiAZ:!0,backupRetentionDays:14,deletionProtection:!0}},cache:{redis:{nodeType:"cache.t3.small",numCacheNodes:2,engine:"redis",engineVersion:"7.0"}},queues:{jobs:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:345600,deadLetterQueue:!0}},security:{certificate:{domain:o,subdomains:[`*.${o}`],validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","sqlInjection","xss"]}}}}}function tb(n){let{name:i,slug:s,domain:o}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{apiGateway:{type:"HTTP",cors:{allowOrigins:["*"],allowMethods:["GET","POST","PUT","DELETE","PATCH"],allowHeaders:["Content-Type","Authorization"],maxAge:3600},customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,throttling:{rateLimit:1e4,burstLimit:5000},authorizer:{type:"JWT",identitySource:"$request.header.Authorization"}},functions:{users:{runtime:"nodejs20.x",handler:"dist/api/users.handler",memory:512,timeout:30,events:[{type:"http",path:"/users",method:"GET"},{type:"http",path:"/users",method:"POST"}]},products:{runtime:"nodejs20.x",handler:"dist/api/products.handler",memory:512,timeout:30,events:[{type:"http",path:"/products",method:"GET"}]}},databases:{dynamodb:{tables:{[`${s}-users`]:{partitionKey:{name:"userId",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0,globalSecondaryIndexes:[{name:"EmailIndex",partitionKey:{name:"email",type:"S"},projection:"ALL"}]},[`${s}-products`]:{partitionKey:{name:"productId",type:"S"},sortKey:{name:"category",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!1}}}},cache:{elasticache:{nodeType:"cache.t3.micro",numCacheNodes:1,engine:"redis",engineVersion:"7.0"}},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","sqlInjection"]}},monitoring:{alarms:[{metric:"Errors",threshold:10,period:300,evaluationPeriods:1},{metric:"Duration",threshold:3000,period:300,evaluationPeriods:2}]}}}}function rb(n){let{name:i,slug:s,domain:o,instanceType:c="t3.small"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},compute:{server:{instanceType:c,ami:"ubuntu-22.04",keyPair:`${s}-key`,autoScaling:{min:2,max:6,desired:2,targetCPU:75},loadBalancer:{type:"application",healthCheck:{path:"/wp-admin/install.php",interval:30}},userData:{packages:["nginx","php8.1-fpm","php8.1-mysql","php8.1-curl","php8.1-gd","php8.1-mbstring","php8.1-xml","php8.1-zip"],commands:["cd /var/www","wget https://wordpress.org/latest.tar.gz","tar -xzf latest.tar.gz","chown -R www-data:www-data wordpress","rm /etc/nginx/sites-enabled/default","systemctl restart nginx","systemctl restart php8.1-fpm"]}}},fileSystem:{uploads:{performanceMode:"generalPurpose",throughputMode:"bursting",encrypted:!0,lifecyclePolicy:{transitionToIA:30},mountPath:"/var/www/wordpress/wp-content/uploads"}},databases:{mysql:{engine:"mysql",version:"8.0",instanceClass:"db.t3.small",allocatedStorage:50,multiAZ:!0,backupRetentionDays:7,deletionProtection:!0,databaseName:"wordpress"}},cache:{redis:{nodeType:"cache.t3.micro",numCacheNodes:1,engine:"redis",engineVersion:"7.0"}},cdn:{enabled:!0,customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,origins:[{type:"alb",pathPattern:"/wp-content/*"}]},security:{certificate:{domain:o,subdomains:[`www.${o}`],validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","sqlInjection","xss","wordpressRules"]}}}}}function nb(n){let{name:i,slug:s,domain:o,apiDomain:c}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{storage:{static:{public:!0,versioning:!0,website:!0,encryption:!1,cors:[{allowedOrigins:["*"],allowedMethods:["GET","HEAD"]}],lifecycleRules:[{id:"DeleteOldVersions",enabled:!0,expirationDays:90}]}},cdn:{enabled:!0,customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cachePolicy:{minTTL:0,defaultTTL:0,maxTTL:31536000},compress:!0,http3:!0,errorPages:{404:"/404.html",500:"/500.html"},edgeFunctions:[{eventType:"origin-request",functionArn:"TO_BE_CREATED",name:"ssr-handler"}]},functions:{ssr:{runtime:"nodejs20.x",handler:"dist/edge/ssr.handler",memory:512,timeout:5},...c?{api:{runtime:"nodejs20.x",handler:"dist/api/index.handler",memory:1024,timeout:30,events:[{type:"http",path:"/{proxy+}",method:"ANY"}]}}:{}},apiGateway:c?{type:"HTTP",customDomain:{domain:c,certificateArn:"TO_BE_GENERATED"},cors:{allowOrigins:[o],allowMethods:["GET","POST","PUT","DELETE"],allowHeaders:["Content-Type","Authorization"]}}:void 0,databases:{dynamodb:{tables:{content:{partitionKey:{name:"id",type:"S"},sortKey:{name:"type",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!1}}}},security:{certificate:{domain:o,subdomains:c?[c]:[],validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","geoBlock"]}}}}}function ib(n){let{name:i,slug:s,domain:o,services:c}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:3,natGateways:2}},compute:{services:c.map((u)=>({name:u.name,type:"fargate",taskDefinition:{cpu:u.cpu||"256",memory:u.memory||"512",containerDefinitions:[{name:u.name,image:`${s}-${u.name}:latest`,portMappings:[{containerPort:u.port}],healthCheck:{command:["CMD-SHELL",`curl -f http://localhost:${u.port}/health || exit 1`],interval:30,timeout:5,retries:3}}]},service:{desiredCount:u.desiredCount||2,serviceDiscovery:{enabled:!0,namespace:`${s}.local`},autoScaling:{min:2,max:10,targetCPU:70}}}))},apiGateway:{type:"HTTP",customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cors:{allowOrigins:["*"],allowMethods:["GET","POST","PUT","DELETE","PATCH"]},routes:c.map((u)=>({path:`/${u.name}/{proxy+}`,integration:{type:"vpc-link",service:u.name}}))},databases:{dynamodb:{tables:Object.fromEntries(c.map((u)=>[`${s}-${u.name}`,{partitionKey:{name:"id",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0}]))}},queues:{events:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:345600,deadLetterQueue:!0}},messaging:{topics:{events:{name:`${s}-events`,subscriptions:c.map((u)=>({protocol:"sqs",endpoint:`${s}-${u.name}-queue`,filterPolicy:{service:[u.name]}}))}}},monitoring:{dashboard:{name:`${s}-microservices`,widgets:c.map((u)=>({type:"metric",metrics:[{service:u.name,metric:"CPUUtilization"},{service:u.name,metric:"MemoryUtilization"},{service:u.name,metric:"RequestCount"}]}))},alarms:c.flatMap((u)=>[{name:`${u.name}-high-cpu`,metric:"CPUUtilization",threshold:80,service:u.name},{name:`${u.name}-errors`,metric:"Errors",threshold:10,service:u.name}])},security:{certificate:{domain:o,validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","sqlInjection"]}}}}}function sb(n){let{name:i,slug:s,domain:o}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{apiGateway:{type:"websocket",customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,routes:[{path:"$connect",method:"WEBSOCKET",integration:"websocket-connect"},{path:"$disconnect",method:"WEBSOCKET",integration:"websocket-disconnect"},{path:"$default",method:"WEBSOCKET",integration:"websocket-default"},{path:"sendMessage",method:"WEBSOCKET",integration:"websocket-send-message"},{path:"joinRoom",method:"WEBSOCKET",integration:"websocket-join-room"}]},functions:{connect:{runtime:"nodejs20.x",handler:"dist/websocket/connect.handler",memory:512,timeout:30},disconnect:{runtime:"nodejs20.x",handler:"dist/websocket/disconnect.handler",memory:512,timeout:30},default:{runtime:"nodejs20.x",handler:"dist/websocket/default.handler",memory:512,timeout:30},"send-message":{runtime:"nodejs20.x",handler:"dist/websocket/sendMessage.handler",memory:512,timeout:30},"join-room":{runtime:"nodejs20.x",handler:"dist/websocket/joinRoom.handler",memory:512,timeout:30},broadcast:{runtime:"nodejs20.x",handler:"dist/streams/broadcast.handler",memory:1024,timeout:60,events:[{type:"dynamodb-stream",tableName:`${s}-messages`,startingPosition:"LATEST",batchSize:100}]}},databases:{dynamodb:{tables:{[`${s}-connections`]:{partitionKey:{name:"connectionId",type:"S"},billingMode:"PAY_PER_REQUEST",globalSecondaryIndexes:[{name:"RoomIndex",partitionKey:{name:"roomId",type:"S"},sortKey:{name:"connectionId",type:"S"},projection:"ALL"}]},[`${s}-messages`]:{partitionKey:{name:"roomId",type:"S"},sortKey:{name:"timestamp",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0,globalSecondaryIndexes:[{name:"UserIndex",partitionKey:{name:"userId",type:"S"},sortKey:{name:"timestamp",type:"S"},projection:"ALL"}]},[`${s}-rooms`]:{partitionKey:{name:"roomId",type:"S"},billingMode:"PAY_PER_REQUEST"}}}},cache:{elasticache:{nodeType:"cache.t3.small",numCacheNodes:2,engine:"redis",engineVersion:"7.0"}},monitoring:{alarms:[{metric:"WebSocketConnections",threshold:1e4,evaluationPeriods:1},{metric:"IntegrationLatency",threshold:1000,evaluationPeriods:2}],dashboard:{name:`${s}-realtime`,widgets:[{type:"metric",metrics:["WebSocketConnections","MessagesSent","IntegrationLatency"]}]}},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","connectionLimit"]}}}}}function ob(n){let{name:i,slug:s,retentionDays:o=7}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",infrastructure:{streaming:{dataStream:{name:`${s}-stream`,shardCount:2,retentionPeriod:o*24,encryption:!0}},storage:{raw:{public:!1,versioning:!0,encryption:!0,intelligentTiering:!0,lifecycleRules:[{id:"ArchiveOldData",enabled:!0,transitions:[{days:30,storageClass:"GLACIER"},{days:90,storageClass:"DEEP_ARCHIVE"}]}]},processed:{public:!1,versioning:!0,encryption:!0,intelligentTiering:!0}},functions:{"stream-processor":{runtime:"nodejs20.x",handler:"dist/processors/stream.handler",memory:2048,timeout:300,events:[{type:"kinesis",streamName:`${s}-stream`,batchSize:1000,startingPosition:"LATEST",parallelizationFactor:10}]},transformer:{runtime:"nodejs20.x",handler:"dist/processors/transform.handler",memory:3008,timeout:900,events:[{type:"s3",bucket:`${s}-raw`,prefix:"incoming/"}]},aggregator:{runtime:"nodejs20.x",handler:"dist/processors/aggregate.handler",memory:2048,timeout:600,events:[{type:"schedule",expression:"cron(0 * * * ? *)"}]}},analytics:{athena:{database:`${s}_analytics`,workgroup:`${s}-workgroup`,outputBucket:`${s}-query-results`,tables:[{name:"raw_events",location:`s3://${s}-raw/events/`,format:"parquet",partitionKeys:["year","month","day"]},{name:"processed_events",location:`s3://${s}-processed/events/`,format:"parquet",partitionKeys:["year","month","day"]}]},glue:{crawlers:[{name:`${s}-crawler`,databaseName:`${s}_analytics`,s3Targets:[`s3://${s}-raw/`,`s3://${s}-processed/`],schedule:"cron(0 2 * * ? *)"}],jobs:[{name:`${s}-etl-job`,scriptLocation:`s3://${s}-scripts/etl.py`,role:`${s}-glue-role`,maxCapacity:10,timeout:120}]}},databases:{dynamodb:{tables:{[`${s}-metadata`]:{partitionKey:{name:"pipelineId",type:"S"},sortKey:{name:"timestamp",type:"S"},billingMode:"PAY_PER_REQUEST"}}}},queues:{failedJobs:{fifo:!1,visibilityTimeout:900,messageRetentionPeriod:1209600,deadLetterQueue:!0,maxReceiveCount:3}},workflow:{pipelines:[{name:`${s}-daily-pipeline`,type:"stepFunctions",definition:{StartAt:"ExtractData",States:{ExtractData:{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Next:"TransformData"},TransformData:{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Next:"LoadData"},LoadData:{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",End:!0}}},schedule:"cron(0 0 * * ? *)"}]},monitoring:{dashboard:{name:`${s}-pipeline`,widgets:[{type:"metric",metrics:["KinesisIncomingRecords","LambdaInvocations","S3ObjectsCreated","GlueJobsSucceeded"]}]},alarms:[{metric:"LambdaErrors",threshold:10,evaluationPeriods:1},{metric:"KinesisIteratorAge",threshold:60000,evaluationPeriods:2}]}}}}function ab(n){let{name:i,slug:s,domain:o,modelS3Path:c=`s3://${s}-models/`,instanceType:u="ml.t3.medium"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{storage:{models:{public:!1,versioning:!0,encryption:!0,intelligentTiering:!0},datasets:{public:!1,versioning:!0,encryption:!0,lifecycleRules:[{id:"ArchiveOldDatasets",enabled:!0,transitions:[{days:90,storageClass:"GLACIER"}]}]},predictions:{public:!1,versioning:!1,encryption:!0,lifecycleRules:[{id:"DeleteOldPredictions",enabled:!0,expirationDays:30}]}},machineLearning:{sagemaker:{endpoints:[{name:`${s}-inference`,modelS3Path:c,instanceType:u,initialInstanceCount:1,autoScaling:{minInstances:1,maxInstances:5,targetInvocationsPerInstance:1000}}],trainingJobs:[{name:`${s}-training`,algorithmSpecification:{trainingImage:"TO_BE_SPECIFIED",trainingInputMode:"File"},instanceType:"ml.p3.2xlarge",instanceCount:1,volumeSizeInGB:50,maxRuntimeInSeconds:86400}]}},apiGateway:{type:"HTTP",customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,cors:{allowOrigins:["*"],allowMethods:["POST"],allowHeaders:["Content-Type","Authorization"]},throttling:{rateLimit:1000,burstLimit:500}},functions:{predict:{runtime:"python3.11",handler:"handlers/predict.handler",memory:2048,timeout:60,events:[{type:"http",path:"/predict",method:"POST"}],environment:{SAGEMAKER_ENDPOINT:`${s}-inference`,MODEL_BUCKET:`${s}-models`}},"batch-predict":{runtime:"python3.11",handler:"handlers/batchPredict.handler",memory:3008,timeout:900,events:[{type:"s3",bucket:`${s}-datasets`,suffix:".csv"}]},"trigger-training":{runtime:"python3.11",handler:"handlers/training.handler",memory:1024,timeout:300,events:[{type:"schedule",expression:"cron(0 2 * * ? *)"}]}},databases:{dynamodb:{tables:{[`${s}-predictions`]:{partitionKey:{name:"requestId",type:"S"},sortKey:{name:"timestamp",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0},[`${s}-models`]:{partitionKey:{name:"modelId",type:"S"},sortKey:{name:"version",type:"S"},billingMode:"PAY_PER_REQUEST"}}}},queues:{predictions:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:86400,deadLetterQueue:!0}},monitoring:{dashboard:{name:`${s}-ml`,widgets:[{type:"metric",metrics:["SageMakerInvocations","SageMakerModelLatency","APIGatewayRequests","LambdaErrors"]}]},alarms:[{metric:"SageMakerModelLatency",threshold:1000,evaluationPeriods:2},{metric:"SageMakerInvocationErrors",threshold:10,evaluationPeriods:1}]},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","apiProtection"]}}}}}function cb(n){let{name:i,slug:s,domain:o,instanceType:c="t3.medium",minInstances:u=2,maxInstances:d=10,databaseEngine:p="mysql",sessionStore:y="redis"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:2}},compute:{server:{instanceType:c,ami:"ubuntu-22.04",autoScaling:{min:u,max:d,targetCPU:70,scaleUpCooldown:300,scaleDownCooldown:300},loadBalancer:{type:"application",healthCheck:{path:"/health",interval:30,timeout:5,healthyThreshold:2,unhealthyThreshold:3},stickySession:{enabled:!0,duration:86400}},userData:`#!/bin/bash
2454
+ | limit 20`,region:e.ref("AWS::Region"),title:`Logs: ${u.logGroup}`}});else if(u.type==="text"&&u.text)s.push({type:"text",x:o,y:c,width:d,height:p,properties:{markdown:u.text}});if(o+=d,o>=24)o=0,c+=p}),n.addResource("CloudWatchDashboard","AWS::CloudWatch::Dashboard",{DashboardName:e.sub(`\${AWS::StackName}-${i.name}`),DashboardBody:JSON.stringify({widgets:s})}),n.addOutputs({DashboardURL:{Description:"CloudWatch Dashboard URL",Value:e.sub("https://console.aws.amazon.com/cloudwatch/home?region=${AWS::Region}#dashboards:name=${CloudWatchDashboard}")}})}function ei(n,i,s){let o=n.toLogicalId(`${i}-log-group`);n.addResource(o,"AWS::Logs::LogGroup",{LogGroupName:e.sub(`/aws/\${AWS::StackName}/${i}`),RetentionInDays:s||14,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]})}function Et(n,i){if(i)return{ec2:"AWS/EC2",ecs:"AWS/ECS",lambda:"AWS/Lambda",rds:"AWS/RDS",dynamodb:"AWS/DynamoDB",s3:"AWS/S3",cloudfront:"AWS/CloudFront",alb:"AWS/ApplicationELB",nlb:"AWS/NetworkELB",apigateway:"AWS/ApiGateway",sqs:"AWS/SQS",sns:"AWS/SNS",kinesis:"AWS/Kinesis",elasticache:"AWS/ElastiCache"}[i.toLowerCase()]||"AWS/CloudWatch";let s=n.toLowerCase();if(s.includes("cpu")||s.includes("memory")||s.includes("network"))return"AWS/EC2";if(s.includes("lambda")||s.includes("invocation")||s.includes("duration"))return"AWS/Lambda";if(s.includes("request")||s.includes("latency")||s.includes("target"))return"AWS/ApplicationELB";if(s.includes("database")||s.includes("connection"))return"AWS/RDS";if(s.includes("read")||s.includes("write")||s.includes("consumed"))return"AWS/DynamoDB";return"AWS/CloudWatch"}function ti(n){return{ec2:[{Name:"InstanceId",Value:e.ref("EC2Instance")}],ecs:[{Name:"ClusterName",Value:e.ref("ECSCluster")},{Name:"ServiceName",Value:e.getAtt("ECSService","Name")}],lambda:[{Name:"FunctionName",Value:e.ref("LambdaFunction")}],rds:[{Name:"DBInstanceIdentifier",Value:e.ref("Database")}],dynamodb:[{Name:"TableName",Value:e.ref("DynamoDBTable")}],alb:[{Name:"LoadBalancer",Value:e.getAtt("LoadBalancer","LoadBalancerFullName")}],apigateway:[{Name:"ApiName",Value:e.ref("HttpApi")}]}[n.toLowerCase()]||[]}function Dn(n,i){if(!i.vpc)return;let{cidr:s="10.0.0.0/16",availabilityZones:o=2,natGateways:c=1,enableDnsHostnames:u=!0,enableDnsSupport:d=!0}=i.vpc;n.addResource("VPC","AWS::EC2::VPC",{CidrBlock:s,EnableDnsHostnames:u,EnableDnsSupport:d,Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-vpc")}]}),n.addResource("InternetGateway","AWS::EC2::InternetGateway",{Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-igw")}]}),n.addResource("VPCGatewayAttachment","AWS::EC2::VPCGatewayAttachment",{VpcId:e.ref("VPC"),InternetGatewayId:e.ref("InternetGateway")},{dependsOn:["VPC","InternetGateway"]});let p=[];for(let v=0;v<o;v++){let A=`PublicSubnet${v+1}`;p.push(A),n.addResource(A,"AWS::EC2::Subnet",{VpcId:e.ref("VPC"),CidrBlock:e.select(v,e.cidr(e.getAtt("VPC","CidrBlock"),o*2,8)),AvailabilityZone:e.select(v,e.getAZs()),MapPublicIpOnLaunch:!0,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-public-${v+1}`)},{Key:"Type",Value:"public"}]},{dependsOn:"VPC"})}let y=[];for(let v=0;v<o;v++){let A=`PrivateSubnet${v+1}`;y.push(A),n.addResource(A,"AWS::EC2::Subnet",{VpcId:e.ref("VPC"),CidrBlock:e.select(v+o,e.cidr(e.getAtt("VPC","CidrBlock"),o*2,8)),AvailabilityZone:e.select(v,e.getAZs()),MapPublicIpOnLaunch:!1,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-private-${v+1}`)},{Key:"Type",Value:"private"}]},{dependsOn:"VPC"})}let h=[];for(let v=0;v<c;v++){let A=`NatEIP${v+1}`;h.push(A),n.addResource(A,"AWS::EC2::EIP",{Domain:"vpc",Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-nat-eip-${v+1}`)}]},{dependsOn:"VPCGatewayAttachment"})}let b=[];for(let v=0;v<c;v++){let A=`NatGateway${v+1}`;b.push(A);let T=v%o;n.addResource(A,"AWS::EC2::NatGateway",{AllocationId:e.getAtt(h[v],"AllocationId"),SubnetId:e.ref(p[T]),Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-nat-${v+1}`)}]},{dependsOn:[h[v],p[T]]})}n.addResource("PublicRouteTable","AWS::EC2::RouteTable",{VpcId:e.ref("VPC"),Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-public-rt")}]},{dependsOn:"VPC"}),n.addResource("PublicRoute","AWS::EC2::Route",{RouteTableId:e.ref("PublicRouteTable"),DestinationCidrBlock:"0.0.0.0/0",GatewayId:e.ref("InternetGateway")},{dependsOn:["PublicRouteTable","VPCGatewayAttachment"]}),p.forEach((v,A)=>{n.addResource(`PublicSubnetRouteTableAssociation${A+1}`,"AWS::EC2::SubnetRouteTableAssociation",{SubnetId:e.ref(v),RouteTableId:e.ref("PublicRouteTable")},{dependsOn:[v,"PublicRouteTable"]})}),y.forEach((v,A)=>{let T=`PrivateRouteTable${A+1}`,R=A%c;n.addResource(T,"AWS::EC2::RouteTable",{VpcId:e.ref("VPC"),Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-private-rt-${A+1}`)}]},{dependsOn:"VPC"}),n.addResource(`PrivateRoute${A+1}`,"AWS::EC2::Route",{RouteTableId:e.ref(T),DestinationCidrBlock:"0.0.0.0/0",NatGatewayId:e.ref(b[R])},{dependsOn:[T,b[R]]}),n.addResource(`PrivateSubnetRouteTableAssociation${A+1}`,"AWS::EC2::SubnetRouteTableAssociation",{SubnetId:e.ref(v),RouteTableId:e.ref(T)},{dependsOn:[v,T]})}),n.addResource("S3VPCEndpoint","AWS::EC2::VPCEndpoint",{VpcId:e.ref("VPC"),ServiceName:e.sub("com.amazonaws.${AWS::Region}.s3"),VpcEndpointType:"Gateway",RouteTableIds:[e.ref("PublicRouteTable"),...Array.from({length:o},(v,A)=>e.ref(`PrivateRouteTable${A+1}`))]},{dependsOn:"VPC"}),n.addResource("NetworkAcl","AWS::EC2::NetworkAcl",{VpcId:e.ref("VPC"),Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-nacl")}]},{dependsOn:"VPC"}),n.addResource("NetworkAclEntryInbound","AWS::EC2::NetworkAclEntry",{NetworkAclId:e.ref("NetworkAcl"),RuleNumber:100,Protocol:-1,RuleAction:"allow",CidrBlock:"0.0.0.0/0"},{dependsOn:"NetworkAcl"}),n.addResource("NetworkAclEntryOutbound","AWS::EC2::NetworkAclEntry",{NetworkAclId:e.ref("NetworkAcl"),RuleNumber:100,Protocol:-1,Egress:!0,RuleAction:"allow",CidrBlock:"0.0.0.0/0"},{dependsOn:"NetworkAcl"}),n.addOutputs({VPCId:{Description:"VPC ID",Value:e.ref("VPC"),Export:{Name:e.sub("${AWS::StackName}-VPC")}},PublicSubnets:{Description:"Public subnet IDs",Value:e.join(",",p.map((v)=>e.ref(v))),Export:{Name:e.sub("${AWS::StackName}-PublicSubnets")}},PrivateSubnets:{Description:"Private subnet IDs",Value:e.join(",",y.map((v)=>e.ref(v))),Export:{Name:e.sub("${AWS::StackName}-PrivateSubnets")}}})}function Nn(n,i){for(let[s,o]of Object.entries(i))ni(n,s,o)}function ni(n,i,s){let o=n.toLogicalId(`${i}-queue`),c=s.fifo||!1,u;if(s.deadLetterQueue){let p=`${o}DLQ`;n.addResource(p,"AWS::SQS::Queue",{QueueName:c?e.sub(`\${AWS::StackName}-${i}-dlq.fifo`):e.sub(`\${AWS::StackName}-${i}-dlq`),FifoQueue:c,MessageRetentionPeriod:1209600,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}-dlq`)}]},{deletionPolicy:"Retain",updateReplacePolicy:"Retain"}),u=e.getAtt(p,"Arn")}let d={QueueName:c?e.sub(`\${AWS::StackName}-${i}.fifo`):e.sub(`\${AWS::StackName}-${i}`),FifoQueue:c,VisibilityTimeout:s.visibilityTimeout||30,MessageRetentionPeriod:s.messageRetentionPeriod||345600,ReceiveMessageWaitTimeSeconds:s.receiveMessageWaitTime||0,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]};if(c&&s.contentBasedDeduplication)d.ContentBasedDeduplication=!0;if(s.deadLetterQueue&&u)d.RedrivePolicy={deadLetterTargetArn:u,maxReceiveCount:s.maxReceiveCount||3};if(n.addResource(o,"AWS::SQS::Queue",d,{dependsOn:s.deadLetterQueue?`${o}DLQ`:void 0,deletionPolicy:"Retain",updateReplacePolicy:"Retain"}),n.addResource(`${o}Policy`,"AWS::SQS::QueuePolicy",{Queues:[e.ref(o)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["lambda.amazonaws.com","events.amazonaws.com","sns.amazonaws.com"]},Action:"sqs:SendMessage",Resource:e.getAtt(o,"Arn"),Condition:{ArnEquals:{"aws:SourceArn":e.sub("arn:aws:*:${AWS::Region}:${AWS::AccountId}:*")}}}]}},{dependsOn:o}),n.addOutputs({[`${o}Url`]:{Description:`${i} queue URL`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-queue-url`)}},[`${o}Arn`]:{Description:`${i} queue ARN`,Value:e.getAtt(o,"Arn"),Export:{Name:e.sub(`\${AWS::StackName}-${i}-queue-arn`)}}}),s.deadLetterQueue)n.addOutputs({[`${o}DLQUrl`]:{Description:`${i} dead letter queue URL`,Value:e.ref(`${o}DLQ`),Export:{Name:e.sub(`\${AWS::StackName}-${i}-dlq-url`)}}})}function xn(n,i){if(i.certificate)ri(n,i.certificate);if(i.waf?.enabled)ii(n,i.waf);if(i.securityGroups)for(let[s,o]of Object.entries(i.securityGroups))ai(n,s,o)}function ri(n,i){if(!i)return;let s=[i.domain];if(i.subdomains)s.push(...i.subdomains);n.addResource("Certificate","AWS::CertificateManager::Certificate",{DomainName:i.domain,SubjectAlternativeNames:i.subdomains,ValidationMethod:i.validationMethod||"DNS",DomainValidationOptions:s.map((o)=>({DomainName:o,HostedZoneId:e.ref("HostedZone")})),Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-certificate")}]}),n.addOutputs({CertificateArn:{Description:"ACM Certificate ARN",Value:e.ref("Certificate"),Export:{Name:e.sub("${AWS::StackName}-certificate-arn")}}})}function ii(n,i){if(!i)return;let s=[],o=i.rules||["rateLimit","sqlInjection","xss"];if(o.includes("rateLimit"))s.push({Name:"RateLimitRule",Priority:1,Statement:{RateBasedStatement:{Limit:i.rateLimit||2000,AggregateKeyType:"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"RateLimitRule"}});let c=s.length+1;if(o.includes("sqlInjection"))s.push({Name:"AWSManagedRulesSQLi",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesSQLiRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesSQLi"}});if(o.includes("xss"))s.push({Name:"AWSManagedRulesXSS",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesKnownBadInputsRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesXSS"}});if(o.includes("knownBadInputs"))s.push({Name:"AWSManagedRulesKnownBadInputs",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesKnownBadInputsRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesKnownBadInputs"}});if(o.includes("coreRuleSet"))s.push({Name:"AWSManagedRulesCoreRuleSet",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesCommonRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesCoreRuleSet"}});if(o.includes("linuxRuleSet"))s.push({Name:"AWSManagedRulesLinuxRuleSet",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesLinuxRuleSet"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesLinuxRuleSet"}});if(o.includes("apiProtection"))s.push({Name:"AWSManagedRulesAPIProtection",Priority:c++,Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:"AWSManagedRulesAmazonIpReputationList"}},OverrideAction:{None:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"AWSManagedRulesAPIProtection"}});if(o.includes("geoBlock"))s.push({Name:"GeoBlockRule",Priority:c++,Statement:{GeoMatchStatement:{CountryCodes:["CN","RU"]}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"GeoBlockRule"}});if(o.includes("connectionLimit"))s.push({Name:"ConnectionLimitRule",Priority:c++,Statement:{RateBasedStatement:{Limit:100,AggregateKeyType:"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:"ConnectionLimitRule"}});if(n.addResource("WebACL","AWS::WAFv2::WebACL",{Name:e.sub("${AWS::StackName}-waf"),Scope:i.scope||"REGIONAL",DefaultAction:{Allow:{}},Rules:s,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:e.sub("${AWS::StackName}-waf")},Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-waf")}]}),n.hasResource("LoadBalancer"))n.addResource("WebACLAssociation","AWS::WAFv2::WebACLAssociation",{ResourceArn:e.ref("LoadBalancer"),WebACLArn:e.getAtt("WebACL","Arn")},{dependsOn:["WebACL","LoadBalancer"]});n.addOutputs({WebACLId:{Description:"WAF Web ACL ID",Value:e.ref("WebACL"),Export:{Name:e.sub("${AWS::StackName}-waf-id")}},WebACLArn:{Description:"WAF Web ACL ARN",Value:e.getAtt("WebACL","Arn"),Export:{Name:e.sub("${AWS::StackName}-waf-arn")}}})}function ai(n,i,s){if(!s)return;let o=n.toLogicalId(`${i}-security-group`),c=s.ingress?.map((d)=>({IpProtocol:d.protocol,FromPort:d.port,ToPort:d.port,CidrIp:d.cidr,SourceSecurityGroupId:d.source?e.ref(d.source):void 0}))||[],u=s.egress?.map((d)=>({IpProtocol:d.protocol,FromPort:d.port,ToPort:d.port,CidrIp:d.cidr||"0.0.0.0/0"}))||[{IpProtocol:"-1",CidrIp:"0.0.0.0/0"}];n.addResource(o,"AWS::EC2::SecurityGroup",{GroupDescription:`Security group for ${i}`,VpcId:e.ref("VPC"),SecurityGroupIngress:c,SecurityGroupEgress:u,Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}-sg`)}]},{dependsOn:"VPC"}),n.addOutputs({[`${o}Id`]:{Description:`${i} security group ID`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-sg-id`)}}})}function kn(n,i){for(let[s,o]of Object.entries(i)){if(o.type==="efs"){oi(n,s,o);continue}si(n,s,o)}}function si(n,i,s){let o=n.toLogicalId(`${i}-bucket`),c={BucketName:e.sub(`\${AWS::StackName}-${i}`),Tags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]};if(s.versioning)c.VersioningConfiguration={Status:"Enabled"};if(s.encryption)c.BucketEncryption={ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]};if(!s.public)c.PublicAccessBlockConfiguration={BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0};if(s.website)c.WebsiteConfiguration={IndexDocument:"index.html",ErrorDocument:"index.html"};if(s.cors&&s.cors.length>0)c.CorsConfiguration={CorsRules:s.cors.map((u)=>({AllowedOrigins:u.allowedOrigins,AllowedMethods:u.allowedMethods,AllowedHeaders:u.allowedHeaders||["*"],MaxAge:u.maxAge||3600}))};if(s.lifecycleRules&&s.lifecycleRules.length>0)c.LifecycleConfiguration={Rules:s.lifecycleRules.map((u)=>({Id:u.id,Status:u.enabled?"Enabled":"Disabled",ExpirationInDays:u.expirationDays,Transitions:u.transitions?.map((d)=>({TransitionInDays:d.days,StorageClass:d.storageClass}))}))};if(s.intelligentTiering)c.IntelligentTieringConfigurations=[{Id:"EntireBucket",Status:"Enabled",Tierings:[{AccessTier:"ARCHIVE_ACCESS",Days:90},{AccessTier:"DEEP_ARCHIVE_ACCESS",Days:180}]}];if(n.addResource(o,"AWS::S3::Bucket",c,{deletionPolicy:s.versioning?"Retain":"Delete"}),s.public)n.addResource(`${o}Policy`,"AWS::S3::BucketPolicy",{Bucket:e.ref(o),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadGetObject",Effect:"Allow",Principal:"*",Action:"s3:GetObject",Resource:e.join("",[un.s3Bucket(e.ref(o)),"/*"])}]}},{dependsOn:o});if(n.addOutputs({[`${o}Name`]:{Description:`${i} bucket name`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-bucket`)}},[`${o}Arn`]:{Description:`${i} bucket ARN`,Value:e.getAtt(o,"Arn"),Export:{Name:e.sub(`\${AWS::StackName}-${i}-bucket-arn`)}}}),s.website)n.addOutputs({[`${o}WebsiteURL`]:{Description:`${i} website URL`,Value:e.getAtt(o,"WebsiteURL")}})}function oi(n,i,s){let o=n.toLogicalId(`${i}-efs`),c={Encrypted:s.encryption!==!1,PerformanceMode:s.performanceMode||"generalPurpose",ThroughputMode:s.throughputMode||"bursting",FileSystemTags:[{Key:"Name",Value:e.sub(`\${AWS::StackName}-${i}`)}]};if(s.lifecyclePolicy){if(c.LifecyclePolicies=[],s.lifecyclePolicy.transitionToIA)c.LifecyclePolicies.push({TransitionToIA:`AFTER_${s.lifecyclePolicy.transitionToIA}_DAYS`});if(s.lifecyclePolicy.transitionToPrimaryStorageClass)c.LifecyclePolicies.push({TransitionToPrimaryStorageClass:"AFTER_1_ACCESS"})}n.addResource(o,"AWS::EFS::FileSystem",c,{deletionPolicy:"Retain"});let u=2;for(let d=0;d<u;d++)n.addResource(`${o}MountTarget${d+1}`,"AWS::EFS::MountTarget",{FileSystemId:e.ref(o),SubnetId:e.ref(`PrivateSubnet${d+1}`),SecurityGroups:[e.ref("EFSSecurityGroup")]},{dependsOn:[o,`PrivateSubnet${d+1}`]});n.addResource("EFSSecurityGroup","AWS::EC2::SecurityGroup",{GroupDescription:"Security group for EFS mount targets",VpcId:e.ref("VPC"),SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:2049,ToPort:2049,SourceSecurityGroupId:e.ref("AppSecurityGroup")}],Tags:[{Key:"Name",Value:e.sub("${AWS::StackName}-efs-sg")}]},{dependsOn:"VPC"}),n.addOutputs({[`${o}Id`]:{Description:`${i} EFS file system ID`,Value:e.ref(o),Export:{Name:e.sub(`\${AWS::StackName}-${i}-efs`)}}})}class Bm{template;config;resourceDependencies;constructor(n){this.config=n,this.resourceDependencies=new Map,this.template={AWSTemplateFormatVersion:"2010-09-09",Description:`Infrastructure for ${n.project.name} (${n.project.slug})`,Resources:{}}}build(){return this.addParameters(),this.addMappings(),this.addConditions(),this.addResources(),this.initializeOutputs(),this.resolveDependencies(),this.template}addParameters(){this.template.Parameters={Environment:{Type:"String",Default:"production",AllowedValues:["development","staging","production"],Description:"Environment name"}}}addMappings(){this.template.Mappings={RegionMap:{"us-east-1":{AMI:"ami-0f3caa1cf4417e51b"},"us-west-2":{AMI:"ami-0d1cd67c26f5fca19"},"eu-west-1":{AMI:"ami-0bbc25e23a7640b9b"}}}}addConditions(){this.template.Conditions={IsProduction:e.equals(e.ref("Environment"),"production"),HasDomain:e.not([e.equals(this.config.environments?.production?.domain||"","")])}}addResources(){let{infrastructure:n}=this.config;if(!n)return;if(n.network)this.addNetworkResources(n.network);if(n.storage)this.addStorageResources(n.storage);if(n.compute)this.addComputeResources(n.compute);if(n.databases)this.addDatabaseResources(n.databases);if(n.cache)this.addCacheResources(n.cache);if(n.cdn)this.addCDNResources(n.cdn);if(n.apiGateway)this.addApiGatewayResources(n.apiGateway);if(n.functions)this.addFunctionResources(n.functions);if(n.queues)this.addQueueResources(n.queues);if(n.messaging)this.addMessagingResources(n.messaging);if(n.monitoring)this.addMonitoringResources(n.monitoring);if(n.security)this.addSecurityResources(n.security)}initializeOutputs(){let n=this.template.Outputs||{};if(this.template.Outputs={StackName:{Description:"Stack name",Value:e.ref("AWS::StackName"),Export:{Name:e.sub("${AWS::StackName}-Name")}},Region:{Description:"AWS Region",Value:e.ref("AWS::Region"),Export:{Name:e.sub("${AWS::StackName}-Region")}},...n},this.config.environments?.production?.domain)this.template.Outputs.Domain={Description:"Production domain",Value:this.config.environments.production.domain,Condition:"HasDomain"}}addResource(n,i,s,o){let c={Type:i,Properties:s};if(o?.dependsOn)c.DependsOn=o.dependsOn,this.trackDependency(n,o.dependsOn);if(o?.condition)c.Condition=o.condition;if(o?.deletionPolicy)c.DeletionPolicy=o.deletionPolicy;if(o?.updateReplacePolicy)c.UpdateReplacePolicy=o.updateReplacePolicy;this.template.Resources[n]=c}addOutputs(n){this.template.Outputs={...this.template.Outputs,...n}}getOutputs(){return this.template.Outputs||{}}hasResource(n){return n in this.template.Resources}getResource(n){return this.template.Resources[n]}trackDependency(n,i){if(!this.resourceDependencies.has(n))this.resourceDependencies.set(n,new Set);(Array.isArray(i)?i:[i]).forEach((o)=>this.resourceDependencies.get(n).add(o))}resolveDependencies(){let n=new Set,i=new Set,s=(o)=>{if(i.has(o))throw Error(`Circular dependency detected involving resource: ${o}`);if(n.has(o))return!0;n.add(o),i.add(o);let c=this.resourceDependencies.get(o);if(c)for(let u of c)s(u);return i.delete(o),!0};for(let o of this.resourceDependencies.keys())s(o)}toLogicalId(n){return n.split(/[-_\s]/).map((i)=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join("")}addNetworkResources(n){Dn(this,n)}addStorageResources(n){kn(this,n)}addComputeResources(n){Tn(this,n)}addDatabaseResources(n){Pn(this,n)}addFunctionResources(n){En(this,n)}addCacheResources(n){An(this,n)}addQueueResources(n){Nn(this,n)}addMessagingResources(n){wn(this,n)}addCDNResources(n){Cn(this,n)}addApiGatewayResources(n){Sn(this,n)}addMonitoringResources(n){In(this,n)}addSecurityResources(n){xn(this,n)}}function fl(n){return new Bm(n).build()}function XI(n){let{name:i,slug:s,domain:o,subdomain:c}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:c&&o?`${c}.${o}`:o}},infrastructure:{storage:{assets:{public:!0,versioning:!1,website:!0,encryption:!1,cors:[{allowedOrigins:["*"],allowedMethods:["GET","HEAD"],allowedHeaders:["*"],maxAge:3600}]}},cdn:{enabled:!0,customDomain:o?{domain:c&&o?`${c}.${o}`:o,certificateArn:"TO_BE_GENERATED"}:void 0,cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0,errorPages:{404:"/index.html",403:"/index.html"}}}}}function YI(n){let{name:i,slug:s,domain:o,instanceType:c="t3.small",minInstances:u=2,maxInstances:d=10}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},compute:{server:{instanceType:c,ami:"ubuntu-22.04",keyPair:`${s}-key`,autoScaling:{min:u,max:d,desired:u,targetCPU:70},loadBalancer:{type:"application",healthCheck:{path:"/health",interval:30,timeout:5,healthyThreshold:2,unhealthyThreshold:3}},userData:{packages:["nodejs","npm","nginx"],commands:["curl -fsSL https://bun.sh/install | bash","npm install -g pm2"]}}},databases:{postgres:{engine:"postgres",version:"15",instanceClass:"db.t3.micro",allocatedStorage:20,multiAZ:!0,backupRetentionDays:7,deletionProtection:!0}},cache:{redis:{nodeType:"cache.t3.micro",numCacheNodes:1,engine:"redis",engineVersion:"7.0"}},security:{certificate:o?{domain:o,subdomains:[`*.${o}`],validationMethod:"DNS"}:void 0}}}}function ZI(n){let{name:i,slug:s,domain:o,taskCpu:c="256",taskMemory:u="512",desiredCount:d=2}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:0}},compute:{fargate:{taskDefinition:{cpu:c,memory:u,containerDefinitions:[{name:"app",image:`${s}-app:latest`,portMappings:[{containerPort:3000}],environment:[],secrets:[]}]},service:{desiredCount:d,healthCheck:{path:"/health",interval:30,timeout:5,healthyThreshold:2,unhealthyThreshold:3},autoScaling:{min:d,max:d*5,targetCPU:70,targetMemory:80}},loadBalancer:{type:"application"}}},databases:{dynamodb:{tables:{[`${s}-main`]:{partitionKey:{name:"id",type:"S"},sortKey:{name:"createdAt",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0}}}},functions:{"process-queue":{runtime:"nodejs20.x",handler:"dist/workers/queue.handler",memory:512,timeout:60,events:[{type:"sqs",queueName:`${s}-queue`}]}},security:{certificate:o?{domain:o,subdomains:[`*.${o}`],validationMethod:"DNS"}:void 0}}}}function eb(n){let{name:i,slug:s,entry:o,domain:c,runtime:u="nodejs20.x",memory:d=1024,build:p,deploy:y,assets:h,queues:b=!0,scheduler:v="on",region:A="us-east-1"}=n;return{project:{name:i,slug:s,region:A},mode:"serverless",environments:{production:{type:"production",domain:c,app:{kind:"node",runtime:u,entry:o,memory:d,build:p,deploy:y,assets:h,queues:b,scheduler:v,domain:c}}}}}function hl(n){let i=n.database!==!1,s=n.cache!==!1,o=n.queue!==!1;return{project:{name:n.name,slug:n.slug,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:n.domain}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},compute:{fargate:{taskDefinition:{cpu:"256",memory:"512",containerDefinitions:[{name:"api",image:n.imageUri,portMappings:[{containerPort:3000}],environment:[{name:"NODE_ENV",value:"production"},{name:"PORT",value:"3000"},{name:"AWS_REGION",value:e.ref("AWS::Region")},...i?[{name:"DB_HOST",value:e.getAtt("PostgresDb","Endpoint.Address")},{name:"DB_PORT",value:e.getAtt("PostgresDb","Endpoint.Port")}]:[],...s?[{name:"REDIS_HOST",value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Address")},{name:"REDIS_PORT",value:e.getAtt("RedisReplicationGroup","PrimaryEndPoint.Port")},{name:"REDIS_TLS",value:"true"}]:[],...o?[{name:"QUEUE_URL",value:e.ref("JobsQueue")}]:[],{name:"MAIL_TRANSPORT",value:"ses"}],secrets:i?[{name:"DB_USERNAME",valueFrom:e.sub("${DBSecret}:username::")},{name:"DB_PASSWORD",valueFrom:e.sub("${DBSecret}:password::")}]:[]}]},service:{desiredCount:n.desiredCount||1,healthCheck:{path:"/api/health",interval:30,timeout:5},autoScaling:{min:n.desiredCount||1,max:6,targetCPU:70}},loadBalancer:{type:"application",...n.certificateArn?{customDomain:{domain:n.domain,certificateArn:n.certificateArn}}:{},...n.originVerifySecret?{originVerifyHeader:{name:"X-Origin-Verify",value:n.originVerifySecret}}:{}}}},...i?{databases:{postgres:{engine:"postgres",version:"16",instanceClass:"db.t4g.micro",allocatedStorage:20,maxAllocatedStorage:100,multiAZ:!1,backupRetentionDays:7,deletionProtection:!0}}}:{},...s?{cache:{redis:{nodeType:"cache.t4g.micro",numCacheNodes:2,engine:"redis",engineVersion:"7.1",automaticFailoverEnabled:!0,snapshotRetentionLimit:5}}}:{},...o?{queues:{jobs:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:345600,deadLetterQueue:!0,maxReceiveCount:3,receiveMessageWaitTime:20}}}:{}}}}function tb(n){let{name:i,slug:s,domain:o,apiSubdomain:c="api"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},storage:{frontend:{public:!0,versioning:!0,website:!0,encryption:!1}},cdn:{enabled:!0,customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0,errorPages:{404:"/index.html"}},compute:{fargate:{taskDefinition:{cpu:"512",memory:"1024",containerDefinitions:[{name:"api",image:`${s}-api:latest`,portMappings:[{containerPort:3000}]}]},service:{desiredCount:2,healthCheck:{path:"/api/health",interval:30},autoScaling:{min:2,max:10,targetCPU:70}},loadBalancer:{type:"application",customDomain:{domain:`${c}.${o}`,certificateArn:"TO_BE_GENERATED"}}}},databases:{postgres:{engine:"postgres",version:"15",instanceClass:"db.t3.small",allocatedStorage:50,multiAZ:!0,backupRetentionDays:14,deletionProtection:!0}},cache:{redis:{nodeType:"cache.t3.small",numCacheNodes:2,engine:"redis",engineVersion:"7.0"}},queues:{jobs:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:345600,deadLetterQueue:!0}},security:{certificate:{domain:o,subdomains:[`*.${o}`],validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","sqlInjection","xss"]}}}}}function rb(n){let{name:i,slug:s,domain:o}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{apiGateway:{type:"HTTP",cors:{allowOrigins:["*"],allowMethods:["GET","POST","PUT","DELETE","PATCH"],allowHeaders:["Content-Type","Authorization"],maxAge:3600},customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,throttling:{rateLimit:1e4,burstLimit:5000},authorizer:{type:"JWT",identitySource:"$request.header.Authorization"}},functions:{users:{runtime:"nodejs20.x",handler:"dist/api/users.handler",memory:512,timeout:30,events:[{type:"http",path:"/users",method:"GET"},{type:"http",path:"/users",method:"POST"}]},products:{runtime:"nodejs20.x",handler:"dist/api/products.handler",memory:512,timeout:30,events:[{type:"http",path:"/products",method:"GET"}]}},databases:{dynamodb:{tables:{[`${s}-users`]:{partitionKey:{name:"userId",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0,globalSecondaryIndexes:[{name:"EmailIndex",partitionKey:{name:"email",type:"S"},projection:"ALL"}]},[`${s}-products`]:{partitionKey:{name:"productId",type:"S"},sortKey:{name:"category",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!1}}}},cache:{elasticache:{nodeType:"cache.t3.micro",numCacheNodes:1,engine:"redis",engineVersion:"7.0"}},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","sqlInjection"]}},monitoring:{alarms:[{metric:"Errors",threshold:10,period:300,evaluationPeriods:1},{metric:"Duration",threshold:3000,period:300,evaluationPeriods:2}]}}}}function nb(n){let{name:i,slug:s,domain:o,instanceType:c="t3.small"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:1}},compute:{server:{instanceType:c,ami:"ubuntu-22.04",keyPair:`${s}-key`,autoScaling:{min:2,max:6,desired:2,targetCPU:75},loadBalancer:{type:"application",healthCheck:{path:"/wp-admin/install.php",interval:30}},userData:{packages:["nginx","php8.1-fpm","php8.1-mysql","php8.1-curl","php8.1-gd","php8.1-mbstring","php8.1-xml","php8.1-zip"],commands:["cd /var/www","wget https://wordpress.org/latest.tar.gz","tar -xzf latest.tar.gz","chown -R www-data:www-data wordpress","rm /etc/nginx/sites-enabled/default","systemctl restart nginx","systemctl restart php8.1-fpm"]}}},fileSystem:{uploads:{performanceMode:"generalPurpose",throughputMode:"bursting",encrypted:!0,lifecyclePolicy:{transitionToIA:30},mountPath:"/var/www/wordpress/wp-content/uploads"}},databases:{mysql:{engine:"mysql",version:"8.0",instanceClass:"db.t3.small",allocatedStorage:50,multiAZ:!0,backupRetentionDays:7,deletionProtection:!0,databaseName:"wordpress"}},cache:{redis:{nodeType:"cache.t3.micro",numCacheNodes:1,engine:"redis",engineVersion:"7.0"}},cdn:{enabled:!0,customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,origins:[{type:"alb",pathPattern:"/wp-content/*"}]},security:{certificate:{domain:o,subdomains:[`www.${o}`],validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","sqlInjection","xss","wordpressRules"]}}}}}function ib(n){let{name:i,slug:s,domain:o,apiDomain:c}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{storage:{static:{public:!0,versioning:!0,website:!0,encryption:!1,cors:[{allowedOrigins:["*"],allowedMethods:["GET","HEAD"]}],lifecycleRules:[{id:"DeleteOldVersions",enabled:!0,expirationDays:90}]}},cdn:{enabled:!0,customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cachePolicy:{minTTL:0,defaultTTL:0,maxTTL:31536000},compress:!0,http3:!0,errorPages:{404:"/404.html",500:"/500.html"},edgeFunctions:[{eventType:"origin-request",functionArn:"TO_BE_CREATED",name:"ssr-handler"}]},functions:{ssr:{runtime:"nodejs20.x",handler:"dist/edge/ssr.handler",memory:512,timeout:5},...c?{api:{runtime:"nodejs20.x",handler:"dist/api/index.handler",memory:1024,timeout:30,events:[{type:"http",path:"/{proxy+}",method:"ANY"}]}}:{}},apiGateway:c?{type:"HTTP",customDomain:{domain:c,certificateArn:"TO_BE_GENERATED"},cors:{allowOrigins:[o],allowMethods:["GET","POST","PUT","DELETE"],allowHeaders:["Content-Type","Authorization"]}}:void 0,databases:{dynamodb:{tables:{content:{partitionKey:{name:"id",type:"S"},sortKey:{name:"type",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!1}}}},security:{certificate:{domain:o,subdomains:c?[c]:[],validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","geoBlock"]}}}}}function sb(n){let{name:i,slug:s,domain:o,services:c}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:3,natGateways:2}},compute:{services:c.map((u)=>({name:u.name,type:"fargate",taskDefinition:{cpu:u.cpu||"256",memory:u.memory||"512",containerDefinitions:[{name:u.name,image:`${s}-${u.name}:latest`,portMappings:[{containerPort:u.port}],healthCheck:{command:["CMD-SHELL",`curl -f http://localhost:${u.port}/health || exit 1`],interval:30,timeout:5,retries:3}}]},service:{desiredCount:u.desiredCount||2,serviceDiscovery:{enabled:!0,namespace:`${s}.local`},autoScaling:{min:2,max:10,targetCPU:70}}}))},apiGateway:{type:"HTTP",customDomain:{domain:o,certificateArn:"TO_BE_GENERATED"},cors:{allowOrigins:["*"],allowMethods:["GET","POST","PUT","DELETE","PATCH"]},routes:c.map((u)=>({path:`/${u.name}/{proxy+}`,integration:{type:"vpc-link",service:u.name}}))},databases:{dynamodb:{tables:Object.fromEntries(c.map((u)=>[`${s}-${u.name}`,{partitionKey:{name:"id",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0}]))}},queues:{events:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:345600,deadLetterQueue:!0}},messaging:{topics:{events:{name:`${s}-events`,subscriptions:c.map((u)=>({protocol:"sqs",endpoint:`${s}-${u.name}-queue`,filterPolicy:{service:[u.name]}}))}}},monitoring:{dashboard:{name:`${s}-microservices`,widgets:c.map((u)=>({type:"metric",metrics:[{service:u.name,metric:"CPUUtilization"},{service:u.name,metric:"MemoryUtilization"},{service:u.name,metric:"RequestCount"}]}))},alarms:c.flatMap((u)=>[{name:`${u.name}-high-cpu`,metric:"CPUUtilization",threshold:80,service:u.name},{name:`${u.name}-errors`,metric:"Errors",threshold:10,service:u.name}])},security:{certificate:{domain:o,validationMethod:"DNS"},waf:{enabled:!0,rules:["rateLimit","sqlInjection"]}}}}}function ob(n){let{name:i,slug:s,domain:o}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{apiGateway:{type:"websocket",customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,routes:[{path:"$connect",method:"WEBSOCKET",integration:"websocket-connect"},{path:"$disconnect",method:"WEBSOCKET",integration:"websocket-disconnect"},{path:"$default",method:"WEBSOCKET",integration:"websocket-default"},{path:"sendMessage",method:"WEBSOCKET",integration:"websocket-send-message"},{path:"joinRoom",method:"WEBSOCKET",integration:"websocket-join-room"}]},functions:{connect:{runtime:"nodejs20.x",handler:"dist/websocket/connect.handler",memory:512,timeout:30},disconnect:{runtime:"nodejs20.x",handler:"dist/websocket/disconnect.handler",memory:512,timeout:30},default:{runtime:"nodejs20.x",handler:"dist/websocket/default.handler",memory:512,timeout:30},"send-message":{runtime:"nodejs20.x",handler:"dist/websocket/sendMessage.handler",memory:512,timeout:30},"join-room":{runtime:"nodejs20.x",handler:"dist/websocket/joinRoom.handler",memory:512,timeout:30},broadcast:{runtime:"nodejs20.x",handler:"dist/streams/broadcast.handler",memory:1024,timeout:60,events:[{type:"dynamodb-stream",tableName:`${s}-messages`,startingPosition:"LATEST",batchSize:100}]}},databases:{dynamodb:{tables:{[`${s}-connections`]:{partitionKey:{name:"connectionId",type:"S"},billingMode:"PAY_PER_REQUEST",globalSecondaryIndexes:[{name:"RoomIndex",partitionKey:{name:"roomId",type:"S"},sortKey:{name:"connectionId",type:"S"},projection:"ALL"}]},[`${s}-messages`]:{partitionKey:{name:"roomId",type:"S"},sortKey:{name:"timestamp",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0,pointInTimeRecovery:!0,globalSecondaryIndexes:[{name:"UserIndex",partitionKey:{name:"userId",type:"S"},sortKey:{name:"timestamp",type:"S"},projection:"ALL"}]},[`${s}-rooms`]:{partitionKey:{name:"roomId",type:"S"},billingMode:"PAY_PER_REQUEST"}}}},cache:{elasticache:{nodeType:"cache.t3.small",numCacheNodes:2,engine:"redis",engineVersion:"7.0"}},monitoring:{alarms:[{metric:"WebSocketConnections",threshold:1e4,evaluationPeriods:1},{metric:"IntegrationLatency",threshold:1000,evaluationPeriods:2}],dashboard:{name:`${s}-realtime`,widgets:[{type:"metric",metrics:["WebSocketConnections","MessagesSent","IntegrationLatency"]}]}},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","connectionLimit"]}}}}}function ab(n){let{name:i,slug:s,retentionDays:o=7}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",infrastructure:{streaming:{dataStream:{name:`${s}-stream`,shardCount:2,retentionPeriod:o*24,encryption:!0}},storage:{raw:{public:!1,versioning:!0,encryption:!0,intelligentTiering:!0,lifecycleRules:[{id:"ArchiveOldData",enabled:!0,transitions:[{days:30,storageClass:"GLACIER"},{days:90,storageClass:"DEEP_ARCHIVE"}]}]},processed:{public:!1,versioning:!0,encryption:!0,intelligentTiering:!0}},functions:{"stream-processor":{runtime:"nodejs20.x",handler:"dist/processors/stream.handler",memory:2048,timeout:300,events:[{type:"kinesis",streamName:`${s}-stream`,batchSize:1000,startingPosition:"LATEST",parallelizationFactor:10}]},transformer:{runtime:"nodejs20.x",handler:"dist/processors/transform.handler",memory:3008,timeout:900,events:[{type:"s3",bucket:`${s}-raw`,prefix:"incoming/"}]},aggregator:{runtime:"nodejs20.x",handler:"dist/processors/aggregate.handler",memory:2048,timeout:600,events:[{type:"schedule",expression:"cron(0 * * * ? *)"}]}},analytics:{athena:{database:`${s}_analytics`,workgroup:`${s}-workgroup`,outputBucket:`${s}-query-results`,tables:[{name:"raw_events",location:`s3://${s}-raw/events/`,format:"parquet",partitionKeys:["year","month","day"]},{name:"processed_events",location:`s3://${s}-processed/events/`,format:"parquet",partitionKeys:["year","month","day"]}]},glue:{crawlers:[{name:`${s}-crawler`,databaseName:`${s}_analytics`,s3Targets:[`s3://${s}-raw/`,`s3://${s}-processed/`],schedule:"cron(0 2 * * ? *)"}],jobs:[{name:`${s}-etl-job`,scriptLocation:`s3://${s}-scripts/etl.py`,role:`${s}-glue-role`,maxCapacity:10,timeout:120}]}},databases:{dynamodb:{tables:{[`${s}-metadata`]:{partitionKey:{name:"pipelineId",type:"S"},sortKey:{name:"timestamp",type:"S"},billingMode:"PAY_PER_REQUEST"}}}},queues:{failedJobs:{fifo:!1,visibilityTimeout:900,messageRetentionPeriod:1209600,deadLetterQueue:!0,maxReceiveCount:3}},workflow:{pipelines:[{name:`${s}-daily-pipeline`,type:"stepFunctions",definition:{StartAt:"ExtractData",States:{ExtractData:{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Next:"TransformData"},TransformData:{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Next:"LoadData"},LoadData:{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",End:!0}}},schedule:"cron(0 0 * * ? *)"}]},monitoring:{dashboard:{name:`${s}-pipeline`,widgets:[{type:"metric",metrics:["KinesisIncomingRecords","LambdaInvocations","S3ObjectsCreated","GlueJobsSucceeded"]}]},alarms:[{metric:"LambdaErrors",threshold:10,evaluationPeriods:1},{metric:"KinesisIteratorAge",threshold:60000,evaluationPeriods:2}]}}}}function cb(n){let{name:i,slug:s,domain:o,modelS3Path:c=`s3://${s}-models/`,instanceType:u="ml.t3.medium"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"serverless",environments:{production:{type:"production",domain:o}},infrastructure:{storage:{models:{public:!1,versioning:!0,encryption:!0,intelligentTiering:!0},datasets:{public:!1,versioning:!0,encryption:!0,lifecycleRules:[{id:"ArchiveOldDatasets",enabled:!0,transitions:[{days:90,storageClass:"GLACIER"}]}]},predictions:{public:!1,versioning:!1,encryption:!0,lifecycleRules:[{id:"DeleteOldPredictions",enabled:!0,expirationDays:30}]}},machineLearning:{sagemaker:{endpoints:[{name:`${s}-inference`,modelS3Path:c,instanceType:u,initialInstanceCount:1,autoScaling:{minInstances:1,maxInstances:5,targetInvocationsPerInstance:1000}}],trainingJobs:[{name:`${s}-training`,algorithmSpecification:{trainingImage:"TO_BE_SPECIFIED",trainingInputMode:"File"},instanceType:"ml.p3.2xlarge",instanceCount:1,volumeSizeInGB:50,maxRuntimeInSeconds:86400}]}},apiGateway:{type:"HTTP",customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,cors:{allowOrigins:["*"],allowMethods:["POST"],allowHeaders:["Content-Type","Authorization"]},throttling:{rateLimit:1000,burstLimit:500}},functions:{predict:{runtime:"python3.11",handler:"handlers/predict.handler",memory:2048,timeout:60,events:[{type:"http",path:"/predict",method:"POST"}],environment:{SAGEMAKER_ENDPOINT:`${s}-inference`,MODEL_BUCKET:`${s}-models`}},"batch-predict":{runtime:"python3.11",handler:"handlers/batchPredict.handler",memory:3008,timeout:900,events:[{type:"s3",bucket:`${s}-datasets`,suffix:".csv"}]},"trigger-training":{runtime:"python3.11",handler:"handlers/training.handler",memory:1024,timeout:300,events:[{type:"schedule",expression:"cron(0 2 * * ? *)"}]}},databases:{dynamodb:{tables:{[`${s}-predictions`]:{partitionKey:{name:"requestId",type:"S"},sortKey:{name:"timestamp",type:"S"},billingMode:"PAY_PER_REQUEST",streamEnabled:!0},[`${s}-models`]:{partitionKey:{name:"modelId",type:"S"},sortKey:{name:"version",type:"S"},billingMode:"PAY_PER_REQUEST"}}}},queues:{predictions:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:86400,deadLetterQueue:!0}},monitoring:{dashboard:{name:`${s}-ml`,widgets:[{type:"metric",metrics:["SageMakerInvocations","SageMakerModelLatency","APIGatewayRequests","LambdaErrors"]}]},alarms:[{metric:"SageMakerModelLatency",threshold:1000,evaluationPeriods:2},{metric:"SageMakerInvocationErrors",threshold:10,evaluationPeriods:1}]},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","apiProtection"]}}}}}function db(n){let{name:i,slug:s,domain:o,instanceType:c="t3.medium",minInstances:u=2,maxInstances:d=10,databaseEngine:p="mysql",sessionStore:y="redis"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",environments:{production:{type:"production",domain:o}},infrastructure:{network:{vpc:{cidr:"10.0.0.0/16",availabilityZones:2,natGateways:2}},compute:{server:{instanceType:c,ami:"ubuntu-22.04",autoScaling:{min:u,max:d,targetCPU:70,scaleUpCooldown:300,scaleDownCooldown:300},loadBalancer:{type:"application",healthCheck:{path:"/health",interval:30,timeout:5,healthyThreshold:2,unhealthyThreshold:3},stickySession:{enabled:!0,duration:86400}},userData:`#!/bin/bash
2455
2455
  # Install Node.js or PHP/Python based on app needs
2456
2456
  # Configure application server (PM2, Nginx, Apache)
2457
2457
  # Mount EFS for shared file storage
2458
- `}},storage:{uploads:{type:"efs",performanceMode:"generalPurpose",throughputMode:"bursting",encrypted:!0,lifecyclePolicy:{transitionToIA:30}},backups:{public:!1,versioning:!0,encryption:!0,lifecycleRules:[{id:"ArchiveOldBackups",enabled:!0,transitions:[{days:90,storageClass:"GLACIER"}]}]},static:{public:!0,versioning:!1,encryption:!1,cors:[{allowedOrigins:[o||"*"],allowedMethods:["GET","HEAD"]}]}},cdn:{enabled:!0,origins:[{originId:"static-assets",domainName:`${s}-static.s3.amazonaws.com`,pathPattern:"/static/*"}],customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0},databases:p==="mysql"?{mysql:{engine:"mysql",version:"8.0",instanceClass:"db.t3.medium",allocatedStorage:100,maxAllocatedStorage:500,multiAZ:!0,backupRetentionDays:14,preferredBackupWindow:"03:00-04:00",preferredMaintenanceWindow:"sun:04:00-sun:05:00",enablePerformanceInsights:!0,performanceInsightsRetention:7,deletionProtection:!0,parameters:{max_connections:"500",innodb_buffer_pool_size:"{DBInstanceClassMemory*3/4}",slow_query_log:"1",long_query_time:"2"}}}:{postgres:{engine:"postgres",version:"15",instanceClass:"db.t3.medium",allocatedStorage:100,maxAllocatedStorage:500,multiAZ:!0,backupRetentionDays:14,preferredBackupWindow:"03:00-04:00",preferredMaintenanceWindow:"sun:04:00-sun:05:00",enablePerformanceInsights:!0,performanceInsightsRetention:7,deletionProtection:!0,parameters:{max_connections:"500",shared_buffers:"{DBInstanceClassMemory/4}",log_min_duration_statement:"2000"}}},cache:y==="redis"?{redis:{nodeType:"cache.t3.medium",numCacheNodes:2,engine:"redis",engineVersion:"7.0",port:6379,parameterGroup:{maxmemoryPolicy:"allkeys-lru",timeout:"300"},snapshotRetentionLimit:5,snapshotWindow:"03:00-05:00",automaticFailoverEnabled:!0}}:void 0,queues:{jobs:{fifo:!1,visibilityTimeout:900,messageRetentionPeriod:345600,receiveMessageWaitTime:20,deadLetterQueue:!0,maxReceiveCount:3},emails:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:86400,deadLetterQueue:!0}},functions:{"job-worker":{runtime:"nodejs20.x",handler:"dist/workers/jobs.handler",memory:2048,timeout:900,events:[{type:"sqs",queueName:`${s}-jobs`,batchSize:10}]},"email-sender":{runtime:"nodejs20.x",handler:"dist/workers/email.handler",memory:512,timeout:60,events:[{type:"sqs",queueName:`${s}-emails`,batchSize:10}]},cleanup:{runtime:"nodejs20.x",handler:"dist/tasks/cleanup.handler",memory:512,timeout:300,events:[{type:"schedule",expression:"cron(0 2 * * ? *)"}]}},monitoring:{dashboard:{name:`${s}-web-app`,widgets:[{type:"metric",metrics:["EC2CPUUtilization","ALBRequestCount","ALBTargetResponseTime","RDSCPUUtilization","RDSDatabaseConnections","RDSReadLatency","RDSWriteLatency"]}]},alarms:[{metric:"EC2CPUUtilization",threshold:80,evaluationPeriods:2},{metric:"RDSCPUUtilization",threshold:80,evaluationPeriods:2},{metric:"RDSDatabaseConnections",threshold:400,evaluationPeriods:1},{metric:"ALBTargetResponseTime",threshold:2000,evaluationPeriods:2},{metric:"ALBUnhealthyHostCount",threshold:1,evaluationPeriods:1}],logs:{retention:14,groups:[`${s}-app`,`${s}-nginx`,`${s}-workers`]}},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","sqlInjection","xss","knownBadInputs"]},securityGroups:{alb:{ingress:[{port:80,protocol:"tcp",cidr:"0.0.0.0/0"},{port:443,protocol:"tcp",cidr:"0.0.0.0/0"}]},app:{ingress:[{port:3000,protocol:"tcp",source:"alb-sg"}]},database:{ingress:[{port:p==="mysql"?3306:5432,protocol:"tcp",source:"app-sg"}]},...y==="redis"&&{cache:{ingress:[{port:6379,protocol:"tcp",source:"app-sg"}]}}}}}}}function db(n){let{name:i,slug:s,domain:o,repository:c,phpVersion:u="8.3",size:d="small",database:p=s.replace(/-/g,"_"),databasePassword:y,sslEmail:h,deployStrategy:b="push",provider:v="hetzner"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",cloud:{provider:v},environments:{production:{type:"production",domain:o}},infrastructure:{compute:{mode:"server",size:d,runtime:"php",webServer:"nginx",php:{versions:[u],default:u},managedServices:{mysql:!0,redis:!0},firewall:{enabled:!0},autoUpdates:!0,monitoring:!0,backups:{enabled:!0,schedule:"0 2 * * *",retentionCount:7}},appDatabase:{engine:"mysql",name:p,username:p,password:y}},sites:{main:{root:".",type:"laravel",domain:o,phpVersion:u,repository:{...c,strategy:b},scheduler:!0,queues:[{connection:"redis",queue:"default",processes:1}],ssl:{provider:"letsencrypt",email:h}}}}}function lb(n){let{name:i,slug:s,domain:o,layers:c,phpVersion:u="8.3",architecture:d="x86_64",memory:p=1024,build:y,deploy:h=["migrate --force"],cache:b="dynamodb",scheduler:v="on",region:A="us-east-1"}=n;return{project:{name:i,slug:s,region:A},mode:"serverless",environments:{production:{type:"production",domain:o,app:{kind:"php",runtime:"provided.al2023",phpVersion:u,architecture:d,layers:c,memory:p,build:y,deploy:h,assets:"public",queues:!0,scheduler:v,cache:{driver:b},domain:o}}}}}function ub(n){return{root:n.root??"packages/ui/dist",deploy:"server",type:"static",domain:n.domain,build:n.build??"cd packages/ui && bun install && bun run build",ssl:{provider:"letsencrypt"},auth:{username:n.username??"admin",password:n.password}}}var ay=rl,cy="./node_modules/@stacksjs/ts-cloud/dist/bin/dashboard-server.js";function ci(n){let i=n.split(".").filter(Boolean);return i.length<=2?n:i.slice(-2).join(".")}function li(n){let i=2166136261;for(let s=0;s<n.length;s++)i^=n.charCodeAt(s),i=Math.imul(i,16777619);return i>>>0}var dy=20000,ly=12000;function uy(n){return dy+li(n)%ly}function Mn(n,i){let s=ci(n);if(s===n)return`dashboard.${s}`;for(let o of i)if(o===s)return`dashboard.${s}`;return`dashboard.${n}`}function Ln(n,i){let s=[],o=n.infrastructure?.dns?.domain;if(o&&!n.cloud?.attachTo)s.push(o);if(i&&n.environments?.[i]?.domain)s.push(n.environments[i].domain);for(let c of Object.values(n.sites??{})){let u=c;if(!u||u.redirect)continue;let d=u.domain;if(typeof d==="string")s.push(d);else if(Array.isArray(d))s.push(...d.filter((p)=>typeof p==="string"))}return s.filter((c)=>c&&!c.startsWith("dashboard."))}function gy(n,i,s){if(s)return s;let o=Ln(n,i),c=o[0];if(!c)return null;return Mn(c,o)}function py(n,i,s){if(s)return[s];let o=Ln(n,i),c=[];for(let u of o){let d=Mn(u,o);if(!c.includes(d))c.push(d)}return c}function gr(n){return Object.entries(n.sites??{}).some(([i,s])=>{if(!s)return!1;let o=s.root??"";return pr(i)||o==="ui/dist"||o.endsWith("/ui/dist")||o.endsWith("/dist/ui")})}var Bm="dashboard-";function xm(n){return Bm+n.replace(/^dashboard\./,"").replace(/\./g,"-")}function pr(n){return n==="dashboard"||n.startsWith(Bm)}function Zi(n,i,s){if(gr(n))return[];if(n.cloud?.attachTo)return[];let o=s.password?{auth:{username:s.username||"admin",password:s.password,realm:s.realm}}:{},c=s.build===!1||s.build===void 0?{}:{build:s.build};if(s.live!==!1){let d=gy(n,i,s.domain);if(!d)return[];let p=s.port??uy(d),y=n.infrastructure?.appDatabase??n.infrastructure?.compute?.database,h={root:s.uiRoot,deploy:"server",domain:d,preStart:["bun install --production --no-save"],start:`bun ${cy} --box --host 127.0.0.1 --port ${p}`,port:p,cpuWeight:10,ioWeight:10,tasksMax:128,env:{APP_ENV:"production",NODE_ENV:"production",TS_CLOUD_DASHBOARD_TELEMETRY:"1",...y?.password?{TS_CLOUD_DASHBOARD_DB_PASSWORD:y.password}:{}},zeroDowntime:!1,sharedPaths:[ay],healthCheck:{path:"/login"},ssl:{provider:"letsencrypt"}};return[{name:xm(d),site:h}]}return py(n,i,s.domain).map((d)=>({name:xm(d),site:{root:s.uiRoot,deploy:"server",type:"static",domain:d,ssl:{provider:"letsencrypt"},...c,...o}}))}function gb(n,i,s){return Zi(n,i,s)[0]??null}function wt(n,i){let s={...n};for(let o in i){let c=i[o],u=s[o];if(c===void 0)continue;if(Array.isArray(c)&&Array.isArray(u))s[o]=[...u,...c];else if(typeof c==="object"&&c!==null&&!Array.isArray(c)&&typeof u==="object"&&u!==null&&!Array.isArray(u))s[o]=wt(u,c);else s[o]=c}return s}function Om(n,i){return wt(n,i)}function pb(...n){return n.reduce((i,s)=>wt(i,s),{})}function mb(n,i){return(s)=>{let o=n(s);if(typeof i==="function")return Om(o,i(o,s));return Om(o,i)}}function gn(n){return{infrastructure:n}}function fb(n){return gn({monitoring:n})}function hb(n){return gn({security:n})}function Ab(n){return gn({databases:n})}function yb(n){return gn({cache:n})}function Sb(n){return gn({cdn:n})}function Ib(n){return gn({queues:n})}import{existsSync as On,readFileSync as It}from"node:fs";import{homedir as $n}from"node:os";import{join as Bn}from"node:path";function my(){let n=process.env.AWS_ACCESS_KEY_ID,i=process.env.AWS_SECRET_ACCESS_KEY;if(!n||!i)return null;return{accessKeyId:n,secretAccessKey:i,sessionToken:process.env.AWS_SESSION_TOKEN}}function fy(n){let i=n?.profile||process.env.AWS_PROFILE||"default",s=n?.credentialsFile||Bn($n(),".aws","credentials");if(!On(s))return null;try{let o=It(s,"utf-8");return ui(o,i)}catch{return null}}function ui(n,i){let s=n.split(`
2459
- `),o=null,c,u,d;for(let p of s){let y=p.trim();if(!y||y.startsWith("#")||y.startsWith(";"))continue;let h=y.match(/^\[([^\]]+)\]$/);if(h){if(o===i&&c&&u)return{accessKeyId:c,secretAccessKey:u,sessionToken:d};o=h[1],c=void 0,u=void 0,d=void 0;continue}if(o===i){let[b,...v]=y.split("="),A=v.join("=").trim();switch(b.trim().toLowerCase()){case"aws_access_key_id":c=A;break;case"aws_secret_access_key":u=A;break;case"aws_session_token":d=A;break}}}if(o===i&&c&&u)return{accessKeyId:c,secretAccessKey:u,sessionToken:d};return null}async function hy(n){let i=n?.timeout??1000,s="http://169.254.169.254";try{let o=await ze("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}},i);if(!o.ok)return null;let c=await o.text(),u=await ze("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":c}},i);if(!u.ok)return null;let d=(await u.text()).trim(),p=await ze(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${d}`,{headers:{"X-aws-ec2-metadata-token":c}},i);if(!p.ok)return null;let y=await p.json();return{accessKeyId:y.AccessKeyId,secretAccessKey:y.SecretAccessKey,sessionToken:y.Token,expiration:new Date(y.Expiration)}}catch{return null}}async function Ay(n){let i=n?.timeout??1000,s=process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,o=process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI,c=null;if(s)c=`http://169.254.170.2${s}`;else if(o)c=o;if(!c)return null;try{let u={},d=process.env.AWS_CONTAINER_AUTHORIZATION_TOKEN;if(d)u.Authorization=d;let p=await ze(c,{headers:u},i);if(!p.ok)return null;let y=await p.json();return{accessKeyId:y.AccessKeyId,secretAccessKey:y.SecretAccessKey,sessionToken:y.Token,expiration:new Date(y.Expiration)}}catch{return null}}async function yy(n){let i=n?.timeout??5000,s=process.env.AWS_WEB_IDENTITY_TOKEN_FILE,o=process.env.AWS_ROLE_ARN,c=process.env.AWS_ROLE_SESSION_NAME||"ts-cloud-session";if(!s||!o)return null;try{let u=It(s,"utf-8").trim(),d=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"us-east-1",p=d.startsWith("us-gov")?`https://sts.${d}.amazonaws.com`:d==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${d}.amazonaws.com`,y=new URLSearchParams({Action:"AssumeRoleWithWebIdentity",Version:"2011-06-15",RoleArn:o,RoleSessionName:c,WebIdentityToken:u}),h=await ze(`${p}/?${y.toString()}`,{method:"POST"},i);if(!h.ok)return null;let b=await h.text(),v=qe(b,"AccessKeyId"),A=qe(b,"SecretAccessKey"),T=qe(b,"SessionToken"),R=qe(b,"Expiration");if(!v||!A)return null;return{accessKeyId:v,secretAccessKey:A,sessionToken:T??void 0,expiration:R?new Date(R):void 0}}catch{return null}}async function es(n){let i=my();if(i)return i;let s=fy(n);if(s)return s;let o=await yy(n);if(o)return o;let c=await Ay(n);if(c)return c;let u=await hy(n);if(u)return u;throw Error("Could not find AWS credentials. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or configure ~/.aws/credentials, or run on an EC2 instance with an IAM role.")}function bb(n){let i=null,s=null;return async()=>{if(i){if(!i.expiration)return i;let o=300000;if(i.expiration.getTime()-Date.now()>o)return i}if(s)return s;return s=es(n).then((o)=>(i=o,s=null,o)).catch((o)=>{throw s=null,o}),s}}async function ze(n,i,s){let o=new AbortController,c=setTimeout(()=>o.abort(),s);try{let u=await fetch(n,{...i,signal:o.signal});return clearTimeout(c),u}catch(u){throw clearTimeout(c),u}}function qe(n,i){let s=new RegExp(`<${i}>([^<]+)</${i}>`),o=n.match(s);return o?o[1]:null}async function jo(n){return es({profile:n})}function Sy(n){let i=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION;if(i)return i;let s=Bn($n(),".aws","config");if(On(s))try{let o=It(s,"utf-8"),c=n||process.env.AWS_PROFILE||"default",u=c==="default"?"[default]":`[profile ${c}]`,d=o.split(`
2460
- `),p=!1;for(let y of d){let h=y.trim();if(h.startsWith("[")){p=h===u;continue}if(p&&h.startsWith("region")){let[,b]=h.split("=");if(b)return b.trim()}}}catch{}return"us-east-1"}async function _m(n){let i=n||await es(),s=Sy(),{signRequest:o}=await import("./chunk-kfcct0jz.js"),c=s.startsWith("us-gov")?`https://sts.${s}.amazonaws.com`:s==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${s}.amazonaws.com`,u="Action=GetCallerIdentity&Version=2011-06-15",d=o({method:"POST",url:c,body:"Action=GetCallerIdentity&Version=2011-06-15",headers:{"Content-Type":"application/x-www-form-urlencoded"},...i,service:"sts",region:s}),p=await fetch(d.url,{method:d.method,headers:d.headers,body:d.body});if(!p.ok)throw Error(`Failed to get account ID: ${await p.text()}`);let y=await p.text(),h=qe(y,"Account");if(!h)throw Error("Failed to parse account ID from response");return h}var mi=5242880,xt=5242880;var pi=5242880;class Mt{region;endpoint;forcePathStyle;credentials;credentialOptions;retryOptions;constructor(n={}){this.region=n.region||process.env.AWS_REGION||"us-east-1",this.endpoint=n.endpoint||`https://s3.${this.region}.amazonaws.com`,this.forcePathStyle=n.forcePathStyle||!1,this.credentials=n.credentials,this.credentialOptions=n.credentialOptions,this.retryOptions=n.retryOptions||{}}async getCredentials(){if(this.credentials)return this.credentials;return es(this.credentialOptions)}buildUrl(n,i){let s=i?encodeURIComponent(i).replace(/%2F/g,"/"):"";if(this.forcePathStyle)return i?`${this.endpoint}/${n}/${s}`:`${this.endpoint}/${n}`;let o=new URL(this.endpoint);return o.hostname=`${n}.${o.hostname}`,i?`${o.origin}/${s}`:o.origin}async get(n,i,s={}){let o=await this.getCredentials(),c=this.buildUrl(n,i),u={};if(s.range)u.Range=s.range;if(s.ifModifiedSince)u["If-Modified-Since"]=s.ifModifiedSince.toUTCString();if(s.ifMatch)u["If-Match"]=s.ifMatch;if(s.ifNoneMatch)u["If-None-Match"]=s.ifNoneMatch;let d=new URL(c);if(s.responseContentType)d.searchParams.set("response-content-type",s.responseContentType);if(s.responseContentDisposition)d.searchParams.set("response-content-disposition",s.responseContentDisposition);let p=k({method:"GET",url:d.toString(),headers:u,...o,service:"s3",region:this.region}),y=await fetch(p.url,{method:p.method,headers:p.headers});if(!y.ok&&y.status!==304){let h=await y.text();throw new V(`Failed to get object: ${h}`,y.status,n,i)}return y}async getText(n,i,s={}){return(await this.get(n,i,s)).text()}async getJSON(n,i,s={}){return(await this.get(n,i,s)).json()}async getBuffer(n,i,s={}){return(await this.get(n,i,s)).arrayBuffer()}async put(n,i,s,o={}){let c,u;if(typeof s==="string")c=new TextEncoder().encode(s).length,u=s;else if(s instanceof ArrayBuffer)c=s.byteLength,u=s;else if(s instanceof Uint8Array)c=s.byteLength,u=s;else if(s instanceof Blob)c=s.size,u=s;else return this.uploadMultipart(n,i,s,{...o,partSize:xt});if(c>pi){let d=fi(u).stream();return this.uploadMultipart(n,i,d,{...o,partSize:xt})}return this.putSimple(n,i,u,c,o)}async putSimple(n,i,s,o,c){let u=await this.getCredentials(),d=this.buildUrl(n,i),p={"Content-Length":String(o),"Content-Type":c.contentType||Fn(i)};if(c.contentEncoding)p["Content-Encoding"]=c.contentEncoding;if(c.cacheControl)p["Cache-Control"]=c.cacheControl;if(c.contentDisposition)p["Content-Disposition"]=c.contentDisposition;if(c.storageClass)p["x-amz-storage-class"]=c.storageClass;if(c.serverSideEncryption)p["x-amz-server-side-encryption"]=c.serverSideEncryption;if(c.acl)p["x-amz-acl"]=c.acl;if(c.tagging)p["x-amz-tagging"]=c.tagging;if(c.metadata)for(let[A,T]of Object.entries(c.metadata))p[`x-amz-meta-${A.toLowerCase()}`]=T;let y;if(typeof s==="string")y=s;else if(s instanceof Blob)y=await s.text();else y=new TextDecoder().decode(s instanceof ArrayBuffer?new Uint8Array(s):s);let h=k({method:"PUT",url:d,headers:p,body:y,...u,service:"s3",region:this.region}),b=await fetch(h.url,{method:h.method,headers:h.headers,body:s});if(!b.ok){let A=await b.text();throw new V(`Failed to put object: ${A}`,b.status,n,i)}return{etag:(b.headers.get("ETag")||"").replace(/"/g,"")}}async delete(n,i){let s=await this.getCredentials(),o=this.buildUrl(n,i),c=k({method:"DELETE",url:o,...s,service:"s3",region:this.region}),u=await fetch(c.url,{method:c.method,headers:c.headers});if(!u.ok&&u.status!==204){let d=await u.text();throw new V(`Failed to delete object: ${d}`,u.status,n,i)}}async deleteMany(n,i){let s=await this.getCredentials(),o=`${this.buildUrl(n)}?delete`,u=`<?xml version="1.0" encoding="UTF-8"?><Delete><Quiet>false</Quiet>${i.map((R)=>`<Object><Key>${yi(R)}</Key></Object>`).join("")}</Delete>`,d=k({method:"POST",url:o,headers:{"Content-Type":"application/xml"},body:u,...s,service:"s3",region:this.region}),p=await fetch(d.url,{method:d.method,headers:d.headers,body:u});if(!p.ok){let R=await p.text();throw new V(`Failed to delete objects: ${R}`,p.status,n)}let y=await p.text(),h=[],b=[],v=/<Deleted><Key>([^<]+)<\/Key>/g,A;while((A=v.exec(y))!==null)h.push(A[1]);let T=/<Error><Key>([^<]+)<\/Key><Code>([^<]+)<\/Code><Message>([^<]+)<\/Message>/g;while((A=T.exec(y))!==null)b.push({key:A[1],error:`${A[2]}: ${A[3]}`});return{deleted:h,errors:b}}async list(n,i={}){let s=await this.getCredentials(),o=new URL(this.buildUrl(n));if(o.searchParams.set("list-type","2"),i.prefix)o.searchParams.set("prefix",i.prefix);if(i.delimiter)o.searchParams.set("delimiter",i.delimiter);if(i.maxKeys)o.searchParams.set("max-keys",String(i.maxKeys));if(i.continuationToken)o.searchParams.set("continuation-token",i.continuationToken);if(i.startAfter)o.searchParams.set("start-after",i.startAfter);let c=k({method:"GET",url:o.toString(),...s,service:"s3",region:this.region}),u=await fetch(c.url,{method:c.method,headers:c.headers});if(!u.ok){let p=await u.text();throw new V(`Failed to list objects: ${p}`,u.status,n)}let d=await u.text();return gi(d)}async*listAll(n,i={}){let s;do{let o=await this.list(n,{...i,continuationToken:s});for(let c of o.contents)yield c;s=o.nextContinuationToken}while(s)}async head(n,i){let s=await this.getCredentials(),o=this.buildUrl(n,i),c=k({method:"HEAD",url:o,...s,service:"s3",region:this.region}),u=await fetch(c.url,{method:c.method,headers:c.headers});if(u.status===404)return null;if(!u.ok){let p=await u.text();throw new V(`Failed to head object: ${p}`,u.status,n,i)}let d={};return u.headers.forEach((p,y)=>{if(y.toLowerCase().startsWith("x-amz-meta-"))d[y.slice(11)]=p}),{contentLength:Number(u.headers.get("Content-Length")||0),contentType:u.headers.get("Content-Type")||"application/octet-stream",etag:(u.headers.get("ETag")||"").replace(/"/g,""),lastModified:new Date(u.headers.get("Last-Modified")||0),metadata:d,storageClass:u.headers.get("x-amz-storage-class")||void 0,serverSideEncryption:u.headers.get("x-amz-server-side-encryption")||void 0}}async exists(n,i){return await this.head(n,i)!==null}async copy(n,i,s,o,c={}){let u=await this.getCredentials(),d=this.buildUrl(s,o),p={"x-amz-copy-source":`/${n}/${encodeURIComponent(i)}`};if(c.metadataDirective)p["x-amz-metadata-directive"]=c.metadataDirective;if(c.contentType)p["Content-Type"]=c.contentType;if(c.storageClass)p["x-amz-storage-class"]=c.storageClass;if(c.acl)p["x-amz-acl"]=c.acl;if(c.metadata)for(let[T,R]of Object.entries(c.metadata))p[`x-amz-meta-${T.toLowerCase()}`]=R;let y=k({method:"PUT",url:d,headers:p,...u,service:"s3",region:this.region}),h=await fetch(y.url,{method:y.method,headers:y.headers});if(!h.ok){let T=await h.text();throw new V(`Failed to copy object: ${T}`,h.status,s,o)}let v=(await h.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:v?v[1]:""}}async getPresignedUrl(n,i,s={}){let o=await this.getCredentials(),c=this.buildUrl(n,i);return ra({url:c,method:s.method||"GET",expiresIn:s.expiresIn||3600,...o,service:"s3",region:this.region})}async uploadMultipart(n,i,s,o={}){let c=await this.getCredentials(),u=Math.max(o.partSize||xt,mi),d,p;if(s instanceof ReadableStream)d=s;else if(s instanceof Blob)d=s.stream(),p=s.size;else{let b=new Blob([s]);d=b.stream(),p=b.size}let{uploadId:y,baseUrl:h}=await this.initiateMultipartUpload(n,i,o);try{let b=await this.uploadParts(n,i,h,y,d,u,c,p,o.concurrency||4,o.onProgress);return await this.completeMultipartUpload(n,i,h,y,b)}catch(b){throw await this.abortMultipartUpload(n,i,y,h).catch(()=>{}),b}}async initiateMultipartUpload(n,i,s){let o=await this.getCredentials(),c=this.buildUrl(n,i),u=`${c}?uploads`,d={"Content-Type":s.contentType||Fn(i)};if(s.storageClass)d["x-amz-storage-class"]=s.storageClass;if(s.serverSideEncryption)d["x-amz-server-side-encryption"]=s.serverSideEncryption;if(s.acl)d["x-amz-acl"]=s.acl;if(s.metadata)for(let[A,T]of Object.entries(s.metadata))d[`x-amz-meta-${A.toLowerCase()}`]=T;let p=k({method:"POST",url:u,headers:d,...o,service:"s3",region:this.region}),y=await fetch(p.url,{method:p.method,headers:p.headers});if(!y.ok){let A=await y.text();throw new V(`Failed to initiate multipart upload: ${A}`,y.status,n,i)}let b=(await y.text()).match(/<UploadId>([^<]+)<\/UploadId>/);if(!b)throw new V("Failed to parse upload ID from response",0,n,i);let v=c;if(y.url)try{let A=new URL(y.url);A.search="",v=A.toString()}catch{}return{uploadId:b[1],baseUrl:v}}async uploadParts(n,i,s,o,c,u,d,p,y,h){let b=[],v=c.getReader(),A=1,T=new Uint8Array(0),R=0,P=p?Math.ceil(p/u):void 0,I=new Map,M=async(N,O)=>{let B=`${s}?partNumber=${O}&uploadId=${encodeURIComponent(o)}`,F={"Content-Length":String(N.byteLength),"x-amz-content-sha256":"UNSIGNED-PAYLOAD"},U=k({method:"PUT",url:B,headers:F,...d,service:"s3",region:this.region}),j=await fetch(U.url,{method:U.method,headers:U.headers,body:N,redirect:"error"});if(!j.ok){let z=await j.text();throw new V(`Failed to upload part ${O}: ${z}`,j.status,n,i)}let H=(j.headers.get("ETag")||"").replace(/"/g,"");if(!H)throw new V(`Missing ETag for part ${O}`,j.status,n,i);return{partNumber:O,etag:H}},L=async()=>{let N=await Promise.race(I.values());I.delete(N.partNumber),b.push(N)};while(!0){let{done:N,value:O}=await v.read();if(O){let B=new Uint8Array(T.length+O.length);B.set(T),B.set(O,T.length),T=B}while(T.length>=u||N&&T.length>0){let B=T.slice(0,u);T=T.slice(u);let F=A++;if(I.size>=y)await L();if(I.set(F,M(B,F)),R+=B.byteLength,h)h({loaded:R,total:p||R,part:F,totalParts:P||F})}if(N)break}while(I.size>0)await L();return b.sort((N,O)=>N.partNumber-O.partNumber),b}async completeMultipartUpload(n,i,s,o,c){let u=await this.getCredentials(),d=`${s}?uploadId=${encodeURIComponent(o)}`,y=`<?xml version="1.0" encoding="UTF-8"?><CompleteMultipartUpload>${c.map((R)=>`<Part><PartNumber>${R.partNumber}</PartNumber><ETag>"${R.etag}"</ETag></Part>`).join("")}</CompleteMultipartUpload>`,h=k({method:"POST",url:d,headers:{"Content-Type":"application/xml"},body:y,...u,service:"s3",region:this.region}),b=await fetch(h.url,{method:h.method,headers:h.headers,body:y});if(!b.ok){let R=await b.text();throw new V(`Failed to complete multipart upload: ${R}`,b.status,n,i)}let A=(await b.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:A?A[1]:""}}async abortMultipartUpload(n,i,s,o){let c=await this.getCredentials(),u=`${o??this.buildUrl(n,i)}?uploadId=${encodeURIComponent(s)}`,d=k({method:"DELETE",url:u,...c,service:"s3",region:this.region});await fetch(d.url,{method:d.method,headers:d.headers})}async emptyAndDeleteBucket(n){let s=[];for await(let d of this.listAll(n,{}))if(s.push(d.key),s.length>=1000)await this.deleteMany(n,s),s=[];if(s.length>0)await this.deleteMany(n,s);let o=await this.getCredentials(),c=this.buildUrl(n),u=k({method:"DELETE",url:c,...o,service:"s3",region:this.region});await fetch(u.url,{method:u.method,headers:u.headers})}}class V extends Error{statusCode;bucket;key;constructor(n,i,s,o){super(n);this.statusCode=i;this.bucket=s;this.key=o;this.name="S3Error"}}function gi(n){let i=[],s=[],o=/<Contents>([\s\S]*?)<\/Contents>/g,c;while((c=o.exec(n))!==null){let d=c[1];i.push({key:ue(d,"Key")||"",lastModified:new Date(ue(d,"LastModified")||0),etag:(ue(d,"ETag")||"").replace(/"/g,""),size:Number(ue(d,"Size")||0),storageClass:ue(d,"StorageClass")||"STANDARD"})}let u=/<CommonPrefixes><Prefix>([^<]+)<\/Prefix><\/CommonPrefixes>/g;while((c=u.exec(n))!==null)s.push(c[1]);return{contents:i,commonPrefixes:s,isTruncated:ue(n,"IsTruncated")==="true",continuationToken:ue(n,"ContinuationToken")||void 0,nextContinuationToken:ue(n,"NextContinuationToken")||void 0,keyCount:Number(ue(n,"KeyCount")||0),maxKeys:Number(ue(n,"MaxKeys")||1000),prefix:ue(n,"Prefix")||void 0,delimiter:ue(n,"Delimiter")||void 0}}function ue(n,i){let s=new RegExp(`<${i}>([^<]*)</${i}>`),o=n.match(s);return o?o[1]:null}function yi(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function Fn(n){let i=n.split(".").pop()?.toLowerCase();return{html:"text/html",htm:"text/html",css:"text/css",js:"application/javascript",mjs:"application/javascript",json:"application/json",xml:"application/xml",txt:"text/plain",md:"text/markdown",csv:"text/csv",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mp3:"audio/mpeg",wav:"audio/wav",ogg:"audio/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",zip:"application/zip",gz:"application/gzip",tar:"application/x-tar",rar:"application/vnd.rar","7z":"application/x-7z-compressed",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject",wasm:"application/wasm"}[i||""]||"application/octet-stream"}function fi(n){if(n instanceof Blob)return n;if(typeof n==="string")return new Blob([n],{type:"text/plain"});return new Blob([n])}function Iy(n){return new Mt(n)}class tt extends Error{code;solution;details;constructor(n,i,s,o){super(n);this.code=i;this.solution=s;this.details=o;this.name="CloudError",Error.captureStackTrace?.(this,tt)}toString(){let n=`${this.name} [${this.code}]: ${this.message}`;if(this.solution)n+=`
2458
+ `}},storage:{uploads:{type:"efs",performanceMode:"generalPurpose",throughputMode:"bursting",encrypted:!0,lifecyclePolicy:{transitionToIA:30}},backups:{public:!1,versioning:!0,encryption:!0,lifecycleRules:[{id:"ArchiveOldBackups",enabled:!0,transitions:[{days:90,storageClass:"GLACIER"}]}]},static:{public:!0,versioning:!1,encryption:!1,cors:[{allowedOrigins:[o||"*"],allowedMethods:["GET","HEAD"]}]}},cdn:{enabled:!0,origins:[{originId:"static-assets",domainName:`${s}-static.s3.amazonaws.com`,pathPattern:"/static/*"}],customDomain:o?{domain:o,certificateArn:"TO_BE_GENERATED"}:void 0,cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0},databases:p==="mysql"?{mysql:{engine:"mysql",version:"8.0",instanceClass:"db.t3.medium",allocatedStorage:100,maxAllocatedStorage:500,multiAZ:!0,backupRetentionDays:14,preferredBackupWindow:"03:00-04:00",preferredMaintenanceWindow:"sun:04:00-sun:05:00",enablePerformanceInsights:!0,performanceInsightsRetention:7,deletionProtection:!0,parameters:{max_connections:"500",innodb_buffer_pool_size:"{DBInstanceClassMemory*3/4}",slow_query_log:"1",long_query_time:"2"}}}:{postgres:{engine:"postgres",version:"15",instanceClass:"db.t3.medium",allocatedStorage:100,maxAllocatedStorage:500,multiAZ:!0,backupRetentionDays:14,preferredBackupWindow:"03:00-04:00",preferredMaintenanceWindow:"sun:04:00-sun:05:00",enablePerformanceInsights:!0,performanceInsightsRetention:7,deletionProtection:!0,parameters:{max_connections:"500",shared_buffers:"{DBInstanceClassMemory/4}",log_min_duration_statement:"2000"}}},cache:y==="redis"?{redis:{nodeType:"cache.t3.medium",numCacheNodes:2,engine:"redis",engineVersion:"7.0",port:6379,parameterGroup:{maxmemoryPolicy:"allkeys-lru",timeout:"300"},snapshotRetentionLimit:5,snapshotWindow:"03:00-05:00",automaticFailoverEnabled:!0}}:void 0,queues:{jobs:{fifo:!1,visibilityTimeout:900,messageRetentionPeriod:345600,receiveMessageWaitTime:20,deadLetterQueue:!0,maxReceiveCount:3},emails:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:86400,deadLetterQueue:!0}},functions:{"job-worker":{runtime:"nodejs20.x",handler:"dist/workers/jobs.handler",memory:2048,timeout:900,events:[{type:"sqs",queueName:`${s}-jobs`,batchSize:10}]},"email-sender":{runtime:"nodejs20.x",handler:"dist/workers/email.handler",memory:512,timeout:60,events:[{type:"sqs",queueName:`${s}-emails`,batchSize:10}]},cleanup:{runtime:"nodejs20.x",handler:"dist/tasks/cleanup.handler",memory:512,timeout:300,events:[{type:"schedule",expression:"cron(0 2 * * ? *)"}]}},monitoring:{dashboard:{name:`${s}-web-app`,widgets:[{type:"metric",metrics:["EC2CPUUtilization","ALBRequestCount","ALBTargetResponseTime","RDSCPUUtilization","RDSDatabaseConnections","RDSReadLatency","RDSWriteLatency"]}]},alarms:[{metric:"EC2CPUUtilization",threshold:80,evaluationPeriods:2},{metric:"RDSCPUUtilization",threshold:80,evaluationPeriods:2},{metric:"RDSDatabaseConnections",threshold:400,evaluationPeriods:1},{metric:"ALBTargetResponseTime",threshold:2000,evaluationPeriods:2},{metric:"ALBUnhealthyHostCount",threshold:1,evaluationPeriods:1}],logs:{retention:14,groups:[`${s}-app`,`${s}-nginx`,`${s}-workers`]}},security:{certificate:o?{domain:o,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","sqlInjection","xss","knownBadInputs"]},securityGroups:{alb:{ingress:[{port:80,protocol:"tcp",cidr:"0.0.0.0/0"},{port:443,protocol:"tcp",cidr:"0.0.0.0/0"}]},app:{ingress:[{port:3000,protocol:"tcp",source:"alb-sg"}]},database:{ingress:[{port:p==="mysql"?3306:5432,protocol:"tcp",source:"app-sg"}]},...y==="redis"&&{cache:{ingress:[{port:6379,protocol:"tcp",source:"app-sg"}]}}}}}}}function lb(n){let{name:i,slug:s,domain:o,repository:c,phpVersion:u="8.3",size:d="small",database:p=s.replace(/-/g,"_"),databasePassword:y,sslEmail:h,deployStrategy:b="push",provider:v="hetzner"}=n;return{project:{name:i,slug:s,region:"us-east-1"},mode:"server",cloud:{provider:v},environments:{production:{type:"production",domain:o}},infrastructure:{compute:{mode:"server",size:d,runtime:"php",webServer:"nginx",php:{versions:[u],default:u},managedServices:{mysql:!0,redis:!0},firewall:{enabled:!0},autoUpdates:!0,monitoring:!0,backups:{enabled:!0,schedule:"0 2 * * *",retentionCount:7}},appDatabase:{engine:"mysql",name:p,username:p,password:y}},sites:{main:{root:".",type:"laravel",domain:o,phpVersion:u,repository:{...c,strategy:b},scheduler:!0,queues:[{connection:"redis",queue:"default",processes:1}],ssl:{provider:"letsencrypt",email:h}}}}}function ub(n){let{name:i,slug:s,domain:o,layers:c,phpVersion:u="8.3",architecture:d="x86_64",memory:p=1024,build:y,deploy:h=["migrate --force"],cache:b="dynamodb",scheduler:v="on",region:A="us-east-1"}=n;return{project:{name:i,slug:s,region:A},mode:"serverless",environments:{production:{type:"production",domain:o,app:{kind:"php",runtime:"provided.al2023",phpVersion:u,architecture:d,layers:c,memory:p,build:y,deploy:h,assets:"public",queues:!0,scheduler:v,cache:{driver:b},domain:o}}}}}function gb(n){return{root:n.root??"packages/ui/dist",deploy:"server",type:"static",domain:n.domain,build:n.build??"cd packages/ui && bun install && bun run build",ssl:{provider:"letsencrypt"},auth:{username:n.username??"admin",password:n.password}}}var cy=rl,dy="./node_modules/@stacksjs/ts-cloud/dist/bin/dashboard-server.js";function ci(n){let i=n.split(".").filter(Boolean);return i.length<=2?n:i.slice(-2).join(".")}function li(n){let i=2166136261;for(let s=0;s<n.length;s++)i^=n.charCodeAt(s),i=Math.imul(i,16777619);return i>>>0}var ly=20000,uy=12000;function gy(n){return ly+li(n)%uy}function Mn(n,i){let s=ci(n);if(s===n)return`dashboard.${s}`;for(let o of i)if(o===s)return`dashboard.${s}`;return`dashboard.${n}`}function Ln(n,i){let s=[],o=n.infrastructure?.dns?.domain;if(o&&!n.cloud?.attachTo)s.push(o);if(i&&n.environments?.[i]?.domain)s.push(n.environments[i].domain);for(let c of Object.values(n.sites??{})){let u=c;if(!u||u.redirect)continue;let d=u.domain;if(typeof d==="string")s.push(d);else if(Array.isArray(d))s.push(...d.filter((p)=>typeof p==="string"))}return s.filter((c)=>c&&!c.startsWith("dashboard."))}function py(n,i,s){if(s)return s;let o=Ln(n,i),c=o[0];if(!c)return null;return Mn(c,o)}function my(n,i,s){if(s)return[s];let o=Ln(n,i),c=[];for(let u of o){let d=Mn(u,o);if(!c.includes(d))c.push(d)}return c}function gr(n){return Object.entries(n.sites??{}).some(([i,s])=>{if(!s)return!1;let o=s.root??"";return pr(i)||o==="ui/dist"||o.endsWith("/ui/dist")||o.endsWith("/dist/ui")})}var xm="dashboard-";function Om(n){return xm+n.replace(/^dashboard\./,"").replace(/\./g,"-")}function pr(n){return n==="dashboard"||n.startsWith(xm)}function Zi(n,i,s){if(gr(n))return[];if(n.cloud?.attachTo)return[];let o=s.password?{auth:{username:s.username||"admin",password:s.password,realm:s.realm}}:{},c=s.build===!1||s.build===void 0?{}:{build:s.build};if(s.live!==!1){let d=py(n,i,s.domain);if(!d)return[];let p=s.port??gy(d),y=n.infrastructure?.appDatabase??n.infrastructure?.compute?.database,h={root:s.uiRoot,deploy:"server",domain:d,preStart:["bun install --production --no-save"],start:`bun ${dy} --box --host 127.0.0.1 --port ${p}`,port:p,cpuWeight:10,ioWeight:10,tasksMax:128,env:{APP_ENV:"production",NODE_ENV:"production",TS_CLOUD_DASHBOARD_TELEMETRY:"1",...y?.password?{TS_CLOUD_DASHBOARD_DB_PASSWORD:y.password}:{}},zeroDowntime:!1,sharedPaths:[cy],healthCheck:{path:"/login"},ssl:{provider:"letsencrypt"}};return[{name:Om(d),site:h}]}return my(n,i,s.domain).map((d)=>({name:Om(d),site:{root:s.uiRoot,deploy:"server",type:"static",domain:d,ssl:{provider:"letsencrypt"},...c,...o}}))}function pb(n,i,s){return Zi(n,i,s)[0]??null}function wt(n,i){let s={...n};for(let o in i){let c=i[o],u=s[o];if(c===void 0)continue;if(Array.isArray(c)&&Array.isArray(u))s[o]=[...u,...c];else if(typeof c==="object"&&c!==null&&!Array.isArray(c)&&typeof u==="object"&&u!==null&&!Array.isArray(u))s[o]=wt(u,c);else s[o]=c}return s}function _m(n,i){return wt(n,i)}function mb(...n){return n.reduce((i,s)=>wt(i,s),{})}function fb(n,i){return(s)=>{let o=n(s);if(typeof i==="function")return _m(o,i(o,s));return _m(o,i)}}function gn(n){return{infrastructure:n}}function hb(n){return gn({monitoring:n})}function Ab(n){return gn({security:n})}function yb(n){return gn({databases:n})}function Sb(n){return gn({cache:n})}function Ib(n){return gn({cdn:n})}function bb(n){return gn({queues:n})}import{existsSync as On,readFileSync as It}from"node:fs";import{homedir as $n}from"node:os";import{join as Bn}from"node:path";function fy(){let n=process.env.AWS_ACCESS_KEY_ID,i=process.env.AWS_SECRET_ACCESS_KEY;if(!n||!i)return null;return{accessKeyId:n,secretAccessKey:i,sessionToken:process.env.AWS_SESSION_TOKEN}}function hy(n){let i=n?.profile||process.env.AWS_PROFILE||"default",s=n?.credentialsFile||Bn($n(),".aws","credentials");if(!On(s))return null;try{let o=It(s,"utf-8");return ui(o,i)}catch{return null}}function ui(n,i){let s=n.split(`
2459
+ `),o=null,c,u,d;for(let p of s){let y=p.trim();if(!y||y.startsWith("#")||y.startsWith(";"))continue;let h=y.match(/^\[([^\]]+)\]$/);if(h){if(o===i&&c&&u)return{accessKeyId:c,secretAccessKey:u,sessionToken:d};o=h[1],c=void 0,u=void 0,d=void 0;continue}if(o===i){let[b,...v]=y.split("="),A=v.join("=").trim();switch(b.trim().toLowerCase()){case"aws_access_key_id":c=A;break;case"aws_secret_access_key":u=A;break;case"aws_session_token":d=A;break}}}if(o===i&&c&&u)return{accessKeyId:c,secretAccessKey:u,sessionToken:d};return null}async function Ay(n){let i=n?.timeout??1000,s="http://169.254.169.254";try{let o=await ze("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}},i);if(!o.ok)return null;let c=await o.text(),u=await ze("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":c}},i);if(!u.ok)return null;let d=(await u.text()).trim(),p=await ze(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${d}`,{headers:{"X-aws-ec2-metadata-token":c}},i);if(!p.ok)return null;let y=await p.json();return{accessKeyId:y.AccessKeyId,secretAccessKey:y.SecretAccessKey,sessionToken:y.Token,expiration:new Date(y.Expiration)}}catch{return null}}async function yy(n){let i=n?.timeout??1000,s=process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,o=process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI,c=null;if(s)c=`http://169.254.170.2${s}`;else if(o)c=o;if(!c)return null;try{let u={},d=process.env.AWS_CONTAINER_AUTHORIZATION_TOKEN;if(d)u.Authorization=d;let p=await ze(c,{headers:u},i);if(!p.ok)return null;let y=await p.json();return{accessKeyId:y.AccessKeyId,secretAccessKey:y.SecretAccessKey,sessionToken:y.Token,expiration:new Date(y.Expiration)}}catch{return null}}async function Sy(n){let i=n?.timeout??5000,s=process.env.AWS_WEB_IDENTITY_TOKEN_FILE,o=process.env.AWS_ROLE_ARN,c=process.env.AWS_ROLE_SESSION_NAME||"ts-cloud-session";if(!s||!o)return null;try{let u=It(s,"utf-8").trim(),d=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"us-east-1",p=d.startsWith("us-gov")?`https://sts.${d}.amazonaws.com`:d==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${d}.amazonaws.com`,y=new URLSearchParams({Action:"AssumeRoleWithWebIdentity",Version:"2011-06-15",RoleArn:o,RoleSessionName:c,WebIdentityToken:u}),h=await ze(`${p}/?${y.toString()}`,{method:"POST"},i);if(!h.ok)return null;let b=await h.text(),v=qe(b,"AccessKeyId"),A=qe(b,"SecretAccessKey"),T=qe(b,"SessionToken"),R=qe(b,"Expiration");if(!v||!A)return null;return{accessKeyId:v,secretAccessKey:A,sessionToken:T??void 0,expiration:R?new Date(R):void 0}}catch{return null}}async function es(n){let i=fy();if(i)return i;let s=hy(n);if(s)return s;let o=await Sy(n);if(o)return o;let c=await yy(n);if(c)return c;let u=await Ay(n);if(u)return u;throw Error("Could not find AWS credentials. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or configure ~/.aws/credentials, or run on an EC2 instance with an IAM role.")}function Cb(n){let i=null,s=null;return async()=>{if(i){if(!i.expiration)return i;let o=300000;if(i.expiration.getTime()-Date.now()>o)return i}if(s)return s;return s=es(n).then((o)=>(i=o,s=null,o)).catch((o)=>{throw s=null,o}),s}}async function ze(n,i,s){let o=new AbortController,c=setTimeout(()=>o.abort(),s);try{let u=await fetch(n,{...i,signal:o.signal});return clearTimeout(c),u}catch(u){throw clearTimeout(c),u}}function qe(n,i){let s=new RegExp(`<${i}>([^<]+)</${i}>`),o=n.match(s);return o?o[1]:null}async function jo(n){return es({profile:n})}function Iy(n){let i=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION;if(i)return i;let s=Bn($n(),".aws","config");if(On(s))try{let o=It(s,"utf-8"),c=n||process.env.AWS_PROFILE||"default",u=c==="default"?"[default]":`[profile ${c}]`,d=o.split(`
2460
+ `),p=!1;for(let y of d){let h=y.trim();if(h.startsWith("[")){p=h===u;continue}if(p&&h.startsWith("region")){let[,b]=h.split("=");if(b)return b.trim()}}}catch{}return"us-east-1"}async function Lm(n){let i=n||await es(),s=Iy(),{signRequest:o}=await import("./chunk-ecnzvq90.js"),c=s.startsWith("us-gov")?`https://sts.${s}.amazonaws.com`:s==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${s}.amazonaws.com`,u="Action=GetCallerIdentity&Version=2011-06-15",d=o({method:"POST",url:c,body:"Action=GetCallerIdentity&Version=2011-06-15",headers:{"Content-Type":"application/x-www-form-urlencoded"},...i,service:"sts",region:s}),p=await fetch(d.url,{method:d.method,headers:d.headers,body:d.body});if(!p.ok)throw Error(`Failed to get account ID: ${await p.text()}`);let y=await p.text(),h=qe(y,"Account");if(!h)throw Error("Failed to parse account ID from response");return h}var mi=5242880,xt=5242880;var pi=5242880;class Mt{region;endpoint;forcePathStyle;credentials;credentialOptions;retryOptions;constructor(n={}){this.region=n.region||process.env.AWS_REGION||"us-east-1",this.endpoint=n.endpoint||`https://s3.${this.region}.amazonaws.com`,this.forcePathStyle=n.forcePathStyle||!1,this.credentials=n.credentials,this.credentialOptions=n.credentialOptions,this.retryOptions=n.retryOptions||{}}async getCredentials(){if(this.credentials)return this.credentials;return es(this.credentialOptions)}buildUrl(n,i){let s=i?encodeURIComponent(i).replace(/%2F/g,"/"):"";if(this.forcePathStyle)return i?`${this.endpoint}/${n}/${s}`:`${this.endpoint}/${n}`;let o=new URL(this.endpoint);return o.hostname=`${n}.${o.hostname}`,i?`${o.origin}/${s}`:o.origin}async get(n,i,s={}){let o=await this.getCredentials(),c=this.buildUrl(n,i),u={};if(s.range)u.Range=s.range;if(s.ifModifiedSince)u["If-Modified-Since"]=s.ifModifiedSince.toUTCString();if(s.ifMatch)u["If-Match"]=s.ifMatch;if(s.ifNoneMatch)u["If-None-Match"]=s.ifNoneMatch;let d=new URL(c);if(s.responseContentType)d.searchParams.set("response-content-type",s.responseContentType);if(s.responseContentDisposition)d.searchParams.set("response-content-disposition",s.responseContentDisposition);let p=k({method:"GET",url:d.toString(),headers:u,...o,service:"s3",region:this.region}),y=await fetch(p.url,{method:p.method,headers:p.headers});if(!y.ok&&y.status!==304){let h=await y.text();throw new V(`Failed to get object: ${h}`,y.status,n,i)}return y}async getText(n,i,s={}){return(await this.get(n,i,s)).text()}async getJSON(n,i,s={}){return(await this.get(n,i,s)).json()}async getBuffer(n,i,s={}){return(await this.get(n,i,s)).arrayBuffer()}async put(n,i,s,o={}){let c,u;if(typeof s==="string")c=new TextEncoder().encode(s).length,u=s;else if(s instanceof ArrayBuffer)c=s.byteLength,u=s;else if(s instanceof Uint8Array)c=s.byteLength,u=s;else if(s instanceof Blob)c=s.size,u=s;else return this.uploadMultipart(n,i,s,{...o,partSize:xt});if(c>pi){let d=fi(u).stream();return this.uploadMultipart(n,i,d,{...o,partSize:xt})}return this.putSimple(n,i,u,c,o)}async putSimple(n,i,s,o,c){let u=await this.getCredentials(),d=this.buildUrl(n,i),p={"Content-Length":String(o),"Content-Type":c.contentType||Fn(i)};if(c.contentEncoding)p["Content-Encoding"]=c.contentEncoding;if(c.cacheControl)p["Cache-Control"]=c.cacheControl;if(c.contentDisposition)p["Content-Disposition"]=c.contentDisposition;if(c.storageClass)p["x-amz-storage-class"]=c.storageClass;if(c.serverSideEncryption)p["x-amz-server-side-encryption"]=c.serverSideEncryption;if(c.acl)p["x-amz-acl"]=c.acl;if(c.tagging)p["x-amz-tagging"]=c.tagging;if(c.metadata)for(let[A,T]of Object.entries(c.metadata))p[`x-amz-meta-${A.toLowerCase()}`]=T;let y;if(typeof s==="string")y=s;else if(s instanceof Blob)y=await s.text();else y=new TextDecoder().decode(s instanceof ArrayBuffer?new Uint8Array(s):s);let h=k({method:"PUT",url:d,headers:p,body:y,...u,service:"s3",region:this.region}),b=await fetch(h.url,{method:h.method,headers:h.headers,body:s});if(!b.ok){let A=await b.text();throw new V(`Failed to put object: ${A}`,b.status,n,i)}return{etag:(b.headers.get("ETag")||"").replace(/"/g,"")}}async delete(n,i){let s=await this.getCredentials(),o=this.buildUrl(n,i),c=k({method:"DELETE",url:o,...s,service:"s3",region:this.region}),u=await fetch(c.url,{method:c.method,headers:c.headers});if(!u.ok&&u.status!==204){let d=await u.text();throw new V(`Failed to delete object: ${d}`,u.status,n,i)}}async deleteMany(n,i){let s=await this.getCredentials(),o=`${this.buildUrl(n)}?delete`,u=`<?xml version="1.0" encoding="UTF-8"?><Delete><Quiet>false</Quiet>${i.map((R)=>`<Object><Key>${yi(R)}</Key></Object>`).join("")}</Delete>`,d=k({method:"POST",url:o,headers:{"Content-Type":"application/xml"},body:u,...s,service:"s3",region:this.region}),p=await fetch(d.url,{method:d.method,headers:d.headers,body:u});if(!p.ok){let R=await p.text();throw new V(`Failed to delete objects: ${R}`,p.status,n)}let y=await p.text(),h=[],b=[],v=/<Deleted><Key>([^<]+)<\/Key>/g,A;while((A=v.exec(y))!==null)h.push(A[1]);let T=/<Error><Key>([^<]+)<\/Key><Code>([^<]+)<\/Code><Message>([^<]+)<\/Message>/g;while((A=T.exec(y))!==null)b.push({key:A[1],error:`${A[2]}: ${A[3]}`});return{deleted:h,errors:b}}async list(n,i={}){let s=await this.getCredentials(),o=new URL(this.buildUrl(n));if(o.searchParams.set("list-type","2"),i.prefix)o.searchParams.set("prefix",i.prefix);if(i.delimiter)o.searchParams.set("delimiter",i.delimiter);if(i.maxKeys)o.searchParams.set("max-keys",String(i.maxKeys));if(i.continuationToken)o.searchParams.set("continuation-token",i.continuationToken);if(i.startAfter)o.searchParams.set("start-after",i.startAfter);let c=k({method:"GET",url:o.toString(),...s,service:"s3",region:this.region}),u=await fetch(c.url,{method:c.method,headers:c.headers});if(!u.ok){let p=await u.text();throw new V(`Failed to list objects: ${p}`,u.status,n)}let d=await u.text();return gi(d)}async*listAll(n,i={}){let s;do{let o=await this.list(n,{...i,continuationToken:s});for(let c of o.contents)yield c;s=o.nextContinuationToken}while(s)}async head(n,i){let s=await this.getCredentials(),o=this.buildUrl(n,i),c=k({method:"HEAD",url:o,...s,service:"s3",region:this.region}),u=await fetch(c.url,{method:c.method,headers:c.headers});if(u.status===404)return null;if(!u.ok){let p=await u.text();throw new V(`Failed to head object: ${p}`,u.status,n,i)}let d={};return u.headers.forEach((p,y)=>{if(y.toLowerCase().startsWith("x-amz-meta-"))d[y.slice(11)]=p}),{contentLength:Number(u.headers.get("Content-Length")||0),contentType:u.headers.get("Content-Type")||"application/octet-stream",etag:(u.headers.get("ETag")||"").replace(/"/g,""),lastModified:new Date(u.headers.get("Last-Modified")||0),metadata:d,storageClass:u.headers.get("x-amz-storage-class")||void 0,serverSideEncryption:u.headers.get("x-amz-server-side-encryption")||void 0}}async exists(n,i){return await this.head(n,i)!==null}async copy(n,i,s,o,c={}){let u=await this.getCredentials(),d=this.buildUrl(s,o),p={"x-amz-copy-source":`/${n}/${encodeURIComponent(i)}`};if(c.metadataDirective)p["x-amz-metadata-directive"]=c.metadataDirective;if(c.contentType)p["Content-Type"]=c.contentType;if(c.storageClass)p["x-amz-storage-class"]=c.storageClass;if(c.acl)p["x-amz-acl"]=c.acl;if(c.metadata)for(let[T,R]of Object.entries(c.metadata))p[`x-amz-meta-${T.toLowerCase()}`]=R;let y=k({method:"PUT",url:d,headers:p,...u,service:"s3",region:this.region}),h=await fetch(y.url,{method:y.method,headers:y.headers});if(!h.ok){let T=await h.text();throw new V(`Failed to copy object: ${T}`,h.status,s,o)}let v=(await h.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:v?v[1]:""}}async getPresignedUrl(n,i,s={}){let o=await this.getCredentials(),c=this.buildUrl(n,i);return ra({url:c,method:s.method||"GET",expiresIn:s.expiresIn||3600,...o,service:"s3",region:this.region})}async uploadMultipart(n,i,s,o={}){let c=await this.getCredentials(),u=Math.max(o.partSize||xt,mi),d,p;if(s instanceof ReadableStream)d=s;else if(s instanceof Blob)d=s.stream(),p=s.size;else{let b=new Blob([s]);d=b.stream(),p=b.size}let{uploadId:y,baseUrl:h}=await this.initiateMultipartUpload(n,i,o);try{let b=await this.uploadParts(n,i,h,y,d,u,c,p,o.concurrency||4,o.onProgress);return await this.completeMultipartUpload(n,i,h,y,b)}catch(b){throw await this.abortMultipartUpload(n,i,y,h).catch(()=>{}),b}}async initiateMultipartUpload(n,i,s){let o=await this.getCredentials(),c=this.buildUrl(n,i),u=`${c}?uploads`,d={"Content-Type":s.contentType||Fn(i)};if(s.storageClass)d["x-amz-storage-class"]=s.storageClass;if(s.serverSideEncryption)d["x-amz-server-side-encryption"]=s.serverSideEncryption;if(s.acl)d["x-amz-acl"]=s.acl;if(s.metadata)for(let[A,T]of Object.entries(s.metadata))d[`x-amz-meta-${A.toLowerCase()}`]=T;let p=k({method:"POST",url:u,headers:d,...o,service:"s3",region:this.region}),y=await fetch(p.url,{method:p.method,headers:p.headers});if(!y.ok){let A=await y.text();throw new V(`Failed to initiate multipart upload: ${A}`,y.status,n,i)}let b=(await y.text()).match(/<UploadId>([^<]+)<\/UploadId>/);if(!b)throw new V("Failed to parse upload ID from response",0,n,i);let v=c;if(y.url)try{let A=new URL(y.url);A.search="",v=A.toString()}catch{}return{uploadId:b[1],baseUrl:v}}async uploadParts(n,i,s,o,c,u,d,p,y,h){let b=[],v=c.getReader(),A=1,T=new Uint8Array(0),R=0,P=p?Math.ceil(p/u):void 0,I=new Map,M=async(N,O)=>{let B=`${s}?partNumber=${O}&uploadId=${encodeURIComponent(o)}`,F={"Content-Length":String(N.byteLength),"x-amz-content-sha256":"UNSIGNED-PAYLOAD"},U=k({method:"PUT",url:B,headers:F,...d,service:"s3",region:this.region}),j=await fetch(U.url,{method:U.method,headers:U.headers,body:N,redirect:"error"});if(!j.ok){let z=await j.text();throw new V(`Failed to upload part ${O}: ${z}`,j.status,n,i)}let H=(j.headers.get("ETag")||"").replace(/"/g,"");if(!H)throw new V(`Missing ETag for part ${O}`,j.status,n,i);return{partNumber:O,etag:H}},L=async()=>{let N=await Promise.race(I.values());I.delete(N.partNumber),b.push(N)};while(!0){let{done:N,value:O}=await v.read();if(O){let B=new Uint8Array(T.length+O.length);B.set(T),B.set(O,T.length),T=B}while(T.length>=u||N&&T.length>0){let B=T.slice(0,u);T=T.slice(u);let F=A++;if(I.size>=y)await L();if(I.set(F,M(B,F)),R+=B.byteLength,h)h({loaded:R,total:p||R,part:F,totalParts:P||F})}if(N)break}while(I.size>0)await L();return b.sort((N,O)=>N.partNumber-O.partNumber),b}async completeMultipartUpload(n,i,s,o,c){let u=await this.getCredentials(),d=`${s}?uploadId=${encodeURIComponent(o)}`,y=`<?xml version="1.0" encoding="UTF-8"?><CompleteMultipartUpload>${c.map((R)=>`<Part><PartNumber>${R.partNumber}</PartNumber><ETag>"${R.etag}"</ETag></Part>`).join("")}</CompleteMultipartUpload>`,h=k({method:"POST",url:d,headers:{"Content-Type":"application/xml"},body:y,...u,service:"s3",region:this.region}),b=await fetch(h.url,{method:h.method,headers:h.headers,body:y});if(!b.ok){let R=await b.text();throw new V(`Failed to complete multipart upload: ${R}`,b.status,n,i)}let A=(await b.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:A?A[1]:""}}async abortMultipartUpload(n,i,s,o){let c=await this.getCredentials(),u=`${o??this.buildUrl(n,i)}?uploadId=${encodeURIComponent(s)}`,d=k({method:"DELETE",url:u,...c,service:"s3",region:this.region});await fetch(d.url,{method:d.method,headers:d.headers})}async emptyAndDeleteBucket(n){let s=[];for await(let d of this.listAll(n,{}))if(s.push(d.key),s.length>=1000)await this.deleteMany(n,s),s=[];if(s.length>0)await this.deleteMany(n,s);let o=await this.getCredentials(),c=this.buildUrl(n),u=k({method:"DELETE",url:c,...o,service:"s3",region:this.region});await fetch(u.url,{method:u.method,headers:u.headers})}}class V extends Error{statusCode;bucket;key;constructor(n,i,s,o){super(n);this.statusCode=i;this.bucket=s;this.key=o;this.name="S3Error"}}function gi(n){let i=[],s=[],o=/<Contents>([\s\S]*?)<\/Contents>/g,c;while((c=o.exec(n))!==null){let d=c[1];i.push({key:ue(d,"Key")||"",lastModified:new Date(ue(d,"LastModified")||0),etag:(ue(d,"ETag")||"").replace(/"/g,""),size:Number(ue(d,"Size")||0),storageClass:ue(d,"StorageClass")||"STANDARD"})}let u=/<CommonPrefixes><Prefix>([^<]+)<\/Prefix><\/CommonPrefixes>/g;while((c=u.exec(n))!==null)s.push(c[1]);return{contents:i,commonPrefixes:s,isTruncated:ue(n,"IsTruncated")==="true",continuationToken:ue(n,"ContinuationToken")||void 0,nextContinuationToken:ue(n,"NextContinuationToken")||void 0,keyCount:Number(ue(n,"KeyCount")||0),maxKeys:Number(ue(n,"MaxKeys")||1000),prefix:ue(n,"Prefix")||void 0,delimiter:ue(n,"Delimiter")||void 0}}function ue(n,i){let s=new RegExp(`<${i}>([^<]*)</${i}>`),o=n.match(s);return o?o[1]:null}function yi(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function Fn(n){let i=n.split(".").pop()?.toLowerCase();return{html:"text/html",htm:"text/html",css:"text/css",js:"application/javascript",mjs:"application/javascript",json:"application/json",xml:"application/xml",txt:"text/plain",md:"text/markdown",csv:"text/csv",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mp3:"audio/mpeg",wav:"audio/wav",ogg:"audio/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",zip:"application/zip",gz:"application/gzip",tar:"application/x-tar",rar:"application/vnd.rar","7z":"application/x-7z-compressed",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject",wasm:"application/wasm"}[i||""]||"application/octet-stream"}function fi(n){if(n instanceof Blob)return n;if(typeof n==="string")return new Blob([n],{type:"text/plain"});return new Blob([n])}function by(n){return new Mt(n)}class tt extends Error{code;solution;details;constructor(n,i,s,o){super(n);this.code=i;this.solution=s;this.details=o;this.name="CloudError",Error.captureStackTrace?.(this,tt)}toString(){let n=`${this.name} [${this.code}]: ${this.message}`;if(this.solution)n+=`
2461
2461
 
2462
2462
  \uD83D\uDCA1 Solution: ${this.solution}`;if(this.details&&Object.keys(this.details).length>0){n+=`
2463
2463
 
2464
2464
  Details:`;for(let[i,s]of Object.entries(this.details))n+=`
2465
- ${i}: ${JSON.stringify(s)}`}return n}}class zo extends tt{constructor(n,i,s){super(n,"CONFIG_ERROR",i,s);this.name="ConfigurationError"}}class Bt extends tt{constructor(n,i,s){super(n,"CREDENTIAL_ERROR",i,s);this.name="CredentialError"}}class by extends tt{constructor(n,i,s){super(n,"DEPLOYMENT_ERROR",i,s);this.name="DeploymentError"}}class Lm extends tt{constructor(n,i,s){super(n,"VALIDATION_ERROR",i,s);this.name="ValidationError"}}class Cy extends tt{statusCode;constructor(n,i,s,o){super(n,"AWS_API_ERROR",s,o);this.statusCode=i;this.name="AWSAPIError"}}var Ey={NO_CREDENTIALS:{message:"AWS credentials not found",solution:`Configure AWS credentials using one of these methods:
2465
+ ${i}: ${JSON.stringify(s)}`}return n}}class zo extends tt{constructor(n,i,s){super(n,"CONFIG_ERROR",i,s);this.name="ConfigurationError"}}class Bt extends tt{constructor(n,i,s){super(n,"CREDENTIAL_ERROR",i,s);this.name="CredentialError"}}class Cy extends tt{constructor(n,i,s){super(n,"DEPLOYMENT_ERROR",i,s);this.name="DeploymentError"}}class $m extends tt{constructor(n,i,s){super(n,"VALIDATION_ERROR",i,s);this.name="ValidationError"}}class Ey extends tt{statusCode;constructor(n,i,s,o){super(n,"AWS_API_ERROR",s,o);this.statusCode=i;this.name="AWSAPIError"}}var vy={NO_CREDENTIALS:{message:"AWS credentials not found",solution:`Configure AWS credentials using one of these methods:
2466
2466
  1. Set environment variables: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
2467
2467
  2. Create ~/.aws/credentials file with your credentials
2468
2468
  3. Use an IAM role (for EC2 instances)
2469
- 4. Run 'aws configure' if you have AWS CLI installed`},INVALID_CREDENTIALS:{message:"AWS credentials are invalid",solution:"Verify your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are correct. Run: aws sts get-caller-identity"},EXPIRED_CREDENTIALS:{message:"AWS credentials have expired",solution:"Refresh your AWS credentials. If using temporary credentials, generate new ones."},MISSING_CONFIG:{message:"Configuration file not found",solution:"Create a cloud.config.ts file in your project root. Use: cloud init"},INVALID_CONFIG:{message:"Configuration is invalid",solution:"Check your cloud.config.ts file for syntax errors. Use: cloud config:validate"},MISSING_REQUIRED_FIELD:{message:"Required configuration field is missing",solution:"Add the missing field to your cloud.config.ts file"},INVALID_REGION:{message:"AWS region is invalid",solution:"Use a valid AWS region like us-east-1, us-west-2, eu-west-1, etc."},STACK_ALREADY_EXISTS:{message:"CloudFormation stack already exists",solution:"Use: cloud deploy --update to update the existing stack, or cloud destroy to delete it first"},STACK_IN_PROGRESS:{message:"Stack operation already in progress",solution:"Wait for the current operation to complete, or cancel it in the AWS Console"},INSUFFICIENT_PERMISSIONS:{message:"Insufficient IAM permissions",solution:"Ensure your IAM user/role has the necessary permissions for CloudFormation and the resources you're deploying"},RESOURCE_LIMIT_EXCEEDED:{message:"AWS service limit exceeded",solution:"Request a service limit increase in the AWS Console, or clean up unused resources"},ROLLBACK_COMPLETE:{message:"Stack creation failed and rolled back",solution:"Check the CloudFormation events to see which resource failed. Fix the issue and try again."},CIRCULAR_DEPENDENCY:{message:"Circular dependency detected in resources",solution:"Review your resource dependencies and remove the circular reference"},INVALID_RESOURCE_NAME:{message:"Resource name contains invalid characters",solution:"Use only alphanumeric characters and hyphens in resource names"},DUPLICATE_RESOURCE:{message:"Duplicate resource name detected",solution:"Ensure all resource names are unique in your configuration"},VPC_CIDR_CONFLICT:{message:"VPC CIDR block conflicts with existing VPC",solution:"Use a different CIDR block that doesn't overlap with existing VPCs"},SUBNET_CIDR_INVALID:{message:"Subnet CIDR block is invalid or outside VPC range",solution:"Ensure subnet CIDR is within the VPC CIDR range and properly sized"},DB_INSTANCE_LIMIT:{message:"RDS instance limit reached",solution:"Delete unused RDS instances or request a limit increase"},INVALID_DB_NAME:{message:"Database name contains invalid characters",solution:"Use only alphanumeric characters and underscores, starting with a letter"},BUCKET_ALREADY_EXISTS:{message:"S3 bucket name already exists globally",solution:"S3 bucket names must be globally unique. Try a different name with your organization prefix"},INVALID_BUCKET_NAME:{message:"S3 bucket name is invalid",solution:"Use lowercase letters, numbers, and hyphens. Must start/end with letter/number. 3-63 characters."},TEMPLATE_TOO_LARGE:{message:"CloudFormation template exceeds size limit",solution:"Split your infrastructure into multiple stacks or use nested stacks"},INVALID_TEMPLATE:{message:"CloudFormation template is invalid",solution:"Validate your template with: cloud config:validate"},PARAMETER_NOT_FOUND:{message:"CloudFormation parameter not found",solution:"Check that all referenced parameters are defined in your template"}};function vy(n){return Ey[n]}function $m(n,i){let s=vy(n);return new tt(s.message,n,s.solution,i)}class q{static verboseMode=!1;static debugMode=!1;static setVerbose(n){this.verboseMode=n}static setDebug(n){this.debugMode=n}static verbose(n,...i){if(this.verboseMode)console.log(`[VERBOSE] ${n}`,...i)}static debug(n,...i){if(this.debugMode)console.log(`[DEBUG] ${n}`,...i)}static info(n,...i){console.log(`ℹ ${n}`,...i)}static warn(n,...i){console.warn(`⚠ ${n}`,...i)}static error(n,i){if(console.error(`✖ ${n}`),i){if(i instanceof tt)console.error(i.toString());else console.error(i.message);if(this.debugMode&&i.stack)console.error(`
2470
- Stack trace:`),console.error(i.stack)}}static success(n){console.log(`✔ ${n}`)}}function Cb(n){if(!n)throw $m("MISSING_CONFIG");if(!n.project)throw new zo("Missing required field: project","Add a project configuration with name, slug, and region",{field:"project"});if(!n.project.name)throw new zo("Missing required field: project.name","Add a project name to your configuration",{field:"project.name"});if(!n.project.slug)throw new zo("Missing required field: project.slug","Add a project slug (lowercase, alphanumeric with hyphens)",{field:"project.slug"});if(!/^[a-z0-9-]+$/.test(n.project.slug))throw new Lm("Invalid project slug format","Use only lowercase letters, numbers, and hyphens",{slug:n.project.slug});if(n.project.region){if(!["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ap-southeast-1","ap-southeast-2","ap-northeast-1","ap-northeast-2","sa-east-1","ca-central-1"].includes(n.project.region))throw $m("INVALID_REGION",{region:n.project.region})}q.success("Configuration validation passed")}function Eb(n){let i=[];if(n.environments?.production&&n.infrastructure?.database){let s=n.infrastructure.database;if((s.postgres||s.mysql)&&!s.postgres?.multiAZ&&!s.mysql?.multiAZ)i.push("Production database should use Multi-AZ for high availability")}if(n.infrastructure?.storage){for(let[s,o]of Object.entries(n.infrastructure.storage))if(o.encryption===!1)i.push(`Storage "${s}" is not encrypted - consider enabling encryption for security`)}if(n.infrastructure?.storage){for(let[s,o]of Object.entries(n.infrastructure.storage))if(o.public===!0)i.push(`Storage "${s}" is publicly accessible - ensure this is intentional`)}if(n.infrastructure?.database){let s=n.infrastructure.database;if(s.postgres||s.mysql){let o=s.postgres?.backupRetentionDays||s.mysql?.backupRetentionDays;if(!o||o<7)i.push("Database backup retention is less than 7 days - consider increasing for production")}}if(!n.infrastructure?.monitoring)i.push("No monitoring configured - consider adding CloudWatch alarms");return i}async function vb(n="default"){try{q.verbose("Resolving AWS credentials...");let i=await jo(n);if(!i.accessKeyId||!i.secretAccessKey)throw new Bt("AWS credentials are incomplete","Ensure both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set");q.verbose("Credentials resolved successfully"),q.debug("Access Key ID:",i.accessKeyId.substring(0,8)+"..."),q.verbose("Testing credentials with GetCallerIdentity...");let s;try{s=await _m(i),q.verbose("Credentials are valid"),q.debug("Account ID:",s)}catch(o){if(o instanceof Error)if(o.message.includes("InvalidClientTokenId"))throw new Bt("Invalid AWS access key ID","Check that your AWS_ACCESS_KEY_ID is correct");else if(o.message.includes("SignatureDoesNotMatch"))throw new Bt("Invalid AWS secret access key","Check that your AWS_SECRET_ACCESS_KEY is correct");else if(o.message.includes("ExpiredToken"))throw new Bt("AWS credentials have expired","Refresh your temporary credentials or use long-term credentials");else throw new Bt(`Failed to validate credentials: ${o.message}`,"Verify your AWS credentials are correct and have the necessary permissions");throw o}return{valid:!0,accountId:s,region:i.region}}catch(i){if(i instanceof Bt)throw i;return{valid:!1,error:i instanceof Error?i.message:"Unknown error"}}}async function Tb(n,i){return{allowed:i,denied:[]}}function Ty(n){let i=new Set(["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:GetTemplate","cloudformation:ListStacks"]);if(n.infrastructure){if(n.infrastructure.storage)i.add("s3:CreateBucket"),i.add("s3:DeleteBucket"),i.add("s3:PutBucketPolicy"),i.add("s3:PutBucketVersioning"),i.add("s3:PutBucketEncryption"),i.add("s3:PutObject"),i.add("s3:GetObject");if(n.infrastructure.compute){if(n.infrastructure.compute.server)i.add("ec2:RunInstances"),i.add("ec2:TerminateInstances"),i.add("ec2:DescribeInstances"),i.add("autoscaling:CreateAutoScalingGroup"),i.add("autoscaling:UpdateAutoScalingGroup"),i.add("autoscaling:DeleteAutoScalingGroup"),i.add("elasticloadbalancing:CreateLoadBalancer"),i.add("elasticloadbalancing:DeleteLoadBalancer");if(n.infrastructure.compute.fargate)i.add("ecs:CreateCluster"),i.add("ecs:DeleteCluster"),i.add("ecs:CreateService"),i.add("ecs:UpdateService"),i.add("ecs:DeleteService"),i.add("ecs:RegisterTaskDefinition")}if(n.infrastructure.database){if(n.infrastructure.database.postgres||n.infrastructure.database.mysql)i.add("rds:CreateDBInstance"),i.add("rds:DeleteDBInstance"),i.add("rds:ModifyDBInstance"),i.add("rds:DescribeDBInstances");if(n.infrastructure.database.dynamodb)i.add("dynamodb:CreateTable"),i.add("dynamodb:DeleteTable"),i.add("dynamodb:UpdateTable"),i.add("dynamodb:DescribeTable")}if(n.infrastructure.functions)i.add("lambda:CreateFunction"),i.add("lambda:DeleteFunction"),i.add("lambda:UpdateFunctionCode"),i.add("lambda:UpdateFunctionConfiguration"),i.add("lambda:AddPermission");if(n.infrastructure.cdn)i.add("cloudfront:CreateDistribution"),i.add("cloudfront:UpdateDistribution"),i.add("cloudfront:DeleteDistribution"),i.add("cloudfront:GetDistribution");if(n.infrastructure.network)i.add("ec2:CreateVpc"),i.add("ec2:DeleteVpc"),i.add("ec2:CreateSubnet"),i.add("ec2:DeleteSubnet"),i.add("ec2:CreateInternetGateway"),i.add("ec2:DeleteInternetGateway"),i.add("ec2:CreateNatGateway"),i.add("ec2:DeleteNatGateway"),i.add("ec2:CreateRouteTable"),i.add("ec2:DeleteRouteTable"),i.add("ec2:CreateSecurityGroup"),i.add("ec2:DeleteSecurityGroup")}return i.add("iam:CreateRole"),i.add("iam:DeleteRole"),i.add("iam:AttachRolePolicy"),i.add("iam:DetachRolePolicy"),i.add("iam:PutRolePolicy"),i.add("iam:GetRole"),i.add("iam:PassRole"),Array.from(i).sort()}function wb(n){let i=Ty(n);return JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Action:i,Resource:"*"}]},null,2)}var te={ec2:{"Running On-Demand Instances":20,"Elastic IPs":5,VPCs:5,"Internet Gateways":5,"NAT Gateways":5,"Security Groups":500},rds:{"DB Instances":40,"DB Snapshots":100,"DB Parameter Groups":50},lambda:{"Concurrent Executions":1000,"Function Storage":80530636800},s3:{Buckets:100},cloudformation:{Stacks:200,StackSets:100},elasticache:{Nodes:100,Clusters:100},dynamodb:{Tables:256},ecs:{Clusters:1e4,"Services per Cluster":2000}};async function Rb(n){let i=[];if(q.verbose("Checking AWS service quotas..."),n.infrastructure?.compute?.server){let o=n.infrastructure.compute.server.autoScaling?.max||1;i.push({service:"EC2",quotaName:"Running On-Demand Instances",currentValue:o,limit:te.ec2["Running On-Demand Instances"],percentage:o/te.ec2["Running On-Demand Instances"]*100,warning:o>te.ec2["Running On-Demand Instances"]*0.8})}if(n.infrastructure?.network?.vpc)i.push({service:"EC2",quotaName:"VPCs",currentValue:1,limit:te.ec2.VPCs,percentage:1/te.ec2.VPCs*100,warning:!1});if(n.infrastructure?.database?.postgres||n.infrastructure?.database?.mysql)i.push({service:"RDS",quotaName:"DB Instances",currentValue:1,limit:te.rds["DB Instances"],percentage:1/te.rds["DB Instances"]*100,warning:!1});if(n.infrastructure?.storage){let o=Object.keys(n.infrastructure.storage).length;i.push({service:"S3",quotaName:"Buckets",currentValue:o,limit:te.s3.Buckets,percentage:o/te.s3.Buckets*100,warning:o>te.s3.Buckets*0.8})}if(n.infrastructure?.functions){let o=0;for(let c of Object.values(n.infrastructure.functions))if(Array.isArray(c))o+=c.length;i.push({service:"Lambda",quotaName:"Functions (estimated)",currentValue:o,limit:1000,percentage:o/1000*100,warning:o>800})}if(n.infrastructure?.database?.dynamodb){let o=n.infrastructure.database.dynamodb.tables?.length||0;i.push({service:"DynamoDB",quotaName:"Tables",currentValue:o,limit:te.dynamodb.Tables,percentage:o/te.dynamodb.Tables*100,warning:o>te.dynamodb.Tables*0.8})}let s=i.filter((o)=>o.warning);if(s.length>0){q.warn("Service quota warnings detected:");for(let o of s)q.warn(` ${o.service} - ${o.quotaName}: ${o.currentValue}/${o.limit} (${o.percentage.toFixed(1)}%)`)}else q.verbose("All service quotas are within limits");return i}function Db(n){if(n.length===0)return"No quotas to check";let i=`Service Quota Usage:
2469
+ 4. Run 'aws configure' if you have AWS CLI installed`},INVALID_CREDENTIALS:{message:"AWS credentials are invalid",solution:"Verify your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are correct. Run: aws sts get-caller-identity"},EXPIRED_CREDENTIALS:{message:"AWS credentials have expired",solution:"Refresh your AWS credentials. If using temporary credentials, generate new ones."},MISSING_CONFIG:{message:"Configuration file not found",solution:"Create a cloud.config.ts file in your project root. Use: cloud init"},INVALID_CONFIG:{message:"Configuration is invalid",solution:"Check your cloud.config.ts file for syntax errors. Use: cloud config:validate"},MISSING_REQUIRED_FIELD:{message:"Required configuration field is missing",solution:"Add the missing field to your cloud.config.ts file"},INVALID_REGION:{message:"AWS region is invalid",solution:"Use a valid AWS region like us-east-1, us-west-2, eu-west-1, etc."},STACK_ALREADY_EXISTS:{message:"CloudFormation stack already exists",solution:"Use: cloud deploy --update to update the existing stack, or cloud destroy to delete it first"},STACK_IN_PROGRESS:{message:"Stack operation already in progress",solution:"Wait for the current operation to complete, or cancel it in the AWS Console"},INSUFFICIENT_PERMISSIONS:{message:"Insufficient IAM permissions",solution:"Ensure your IAM user/role has the necessary permissions for CloudFormation and the resources you're deploying"},RESOURCE_LIMIT_EXCEEDED:{message:"AWS service limit exceeded",solution:"Request a service limit increase in the AWS Console, or clean up unused resources"},ROLLBACK_COMPLETE:{message:"Stack creation failed and rolled back",solution:"Check the CloudFormation events to see which resource failed. Fix the issue and try again."},CIRCULAR_DEPENDENCY:{message:"Circular dependency detected in resources",solution:"Review your resource dependencies and remove the circular reference"},INVALID_RESOURCE_NAME:{message:"Resource name contains invalid characters",solution:"Use only alphanumeric characters and hyphens in resource names"},DUPLICATE_RESOURCE:{message:"Duplicate resource name detected",solution:"Ensure all resource names are unique in your configuration"},VPC_CIDR_CONFLICT:{message:"VPC CIDR block conflicts with existing VPC",solution:"Use a different CIDR block that doesn't overlap with existing VPCs"},SUBNET_CIDR_INVALID:{message:"Subnet CIDR block is invalid or outside VPC range",solution:"Ensure subnet CIDR is within the VPC CIDR range and properly sized"},DB_INSTANCE_LIMIT:{message:"RDS instance limit reached",solution:"Delete unused RDS instances or request a limit increase"},INVALID_DB_NAME:{message:"Database name contains invalid characters",solution:"Use only alphanumeric characters and underscores, starting with a letter"},BUCKET_ALREADY_EXISTS:{message:"S3 bucket name already exists globally",solution:"S3 bucket names must be globally unique. Try a different name with your organization prefix"},INVALID_BUCKET_NAME:{message:"S3 bucket name is invalid",solution:"Use lowercase letters, numbers, and hyphens. Must start/end with letter/number. 3-63 characters."},TEMPLATE_TOO_LARGE:{message:"CloudFormation template exceeds size limit",solution:"Split your infrastructure into multiple stacks or use nested stacks"},INVALID_TEMPLATE:{message:"CloudFormation template is invalid",solution:"Validate your template with: cloud config:validate"},PARAMETER_NOT_FOUND:{message:"CloudFormation parameter not found",solution:"Check that all referenced parameters are defined in your template"}};function Ty(n){return vy[n]}function Mm(n,i){let s=Ty(n);return new tt(s.message,n,s.solution,i)}class q{static verboseMode=!1;static debugMode=!1;static setVerbose(n){this.verboseMode=n}static setDebug(n){this.debugMode=n}static verbose(n,...i){if(this.verboseMode)console.log(`[VERBOSE] ${n}`,...i)}static debug(n,...i){if(this.debugMode)console.log(`[DEBUG] ${n}`,...i)}static info(n,...i){console.log(`ℹ ${n}`,...i)}static warn(n,...i){console.warn(`⚠ ${n}`,...i)}static error(n,i){if(console.error(`✖ ${n}`),i){if(i instanceof tt)console.error(i.toString());else console.error(i.message);if(this.debugMode&&i.stack)console.error(`
2470
+ Stack trace:`),console.error(i.stack)}}static success(n){console.log(`✔ ${n}`)}}function Eb(n){if(!n)throw Mm("MISSING_CONFIG");if(!n.project)throw new zo("Missing required field: project","Add a project configuration with name, slug, and region",{field:"project"});if(!n.project.name)throw new zo("Missing required field: project.name","Add a project name to your configuration",{field:"project.name"});if(!n.project.slug)throw new zo("Missing required field: project.slug","Add a project slug (lowercase, alphanumeric with hyphens)",{field:"project.slug"});if(!/^[a-z0-9-]+$/.test(n.project.slug))throw new $m("Invalid project slug format","Use only lowercase letters, numbers, and hyphens",{slug:n.project.slug});if(n.project.region){if(!["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ap-southeast-1","ap-southeast-2","ap-northeast-1","ap-northeast-2","sa-east-1","ca-central-1"].includes(n.project.region))throw Mm("INVALID_REGION",{region:n.project.region})}q.success("Configuration validation passed")}function vb(n){let i=[];if(n.environments?.production&&n.infrastructure?.database){let s=n.infrastructure.database;if((s.postgres||s.mysql)&&!s.postgres?.multiAZ&&!s.mysql?.multiAZ)i.push("Production database should use Multi-AZ for high availability")}if(n.infrastructure?.storage){for(let[s,o]of Object.entries(n.infrastructure.storage))if(o.encryption===!1)i.push(`Storage "${s}" is not encrypted - consider enabling encryption for security`)}if(n.infrastructure?.storage){for(let[s,o]of Object.entries(n.infrastructure.storage))if(o.public===!0)i.push(`Storage "${s}" is publicly accessible - ensure this is intentional`)}if(n.infrastructure?.database){let s=n.infrastructure.database;if(s.postgres||s.mysql){let o=s.postgres?.backupRetentionDays||s.mysql?.backupRetentionDays;if(!o||o<7)i.push("Database backup retention is less than 7 days - consider increasing for production")}}if(!n.infrastructure?.monitoring)i.push("No monitoring configured - consider adding CloudWatch alarms");return i}async function Tb(n="default"){try{q.verbose("Resolving AWS credentials...");let i=await jo(n);if(!i.accessKeyId||!i.secretAccessKey)throw new Bt("AWS credentials are incomplete","Ensure both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set");q.verbose("Credentials resolved successfully"),q.debug("Access Key ID:",i.accessKeyId.substring(0,8)+"..."),q.verbose("Testing credentials with GetCallerIdentity...");let s;try{s=await Lm(i),q.verbose("Credentials are valid"),q.debug("Account ID:",s)}catch(o){if(o instanceof Error)if(o.message.includes("InvalidClientTokenId"))throw new Bt("Invalid AWS access key ID","Check that your AWS_ACCESS_KEY_ID is correct");else if(o.message.includes("SignatureDoesNotMatch"))throw new Bt("Invalid AWS secret access key","Check that your AWS_SECRET_ACCESS_KEY is correct");else if(o.message.includes("ExpiredToken"))throw new Bt("AWS credentials have expired","Refresh your temporary credentials or use long-term credentials");else throw new Bt(`Failed to validate credentials: ${o.message}`,"Verify your AWS credentials are correct and have the necessary permissions");throw o}return{valid:!0,accountId:s,region:i.region}}catch(i){if(i instanceof Bt)throw i;return{valid:!1,error:i instanceof Error?i.message:"Unknown error"}}}async function wb(n,i){return{allowed:i,denied:[]}}function wy(n){let i=new Set(["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:GetTemplate","cloudformation:ListStacks"]);if(n.infrastructure){if(n.infrastructure.storage)i.add("s3:CreateBucket"),i.add("s3:DeleteBucket"),i.add("s3:PutBucketPolicy"),i.add("s3:PutBucketVersioning"),i.add("s3:PutBucketEncryption"),i.add("s3:PutObject"),i.add("s3:GetObject");if(n.infrastructure.compute){if(n.infrastructure.compute.server)i.add("ec2:RunInstances"),i.add("ec2:TerminateInstances"),i.add("ec2:DescribeInstances"),i.add("autoscaling:CreateAutoScalingGroup"),i.add("autoscaling:UpdateAutoScalingGroup"),i.add("autoscaling:DeleteAutoScalingGroup"),i.add("elasticloadbalancing:CreateLoadBalancer"),i.add("elasticloadbalancing:DeleteLoadBalancer");if(n.infrastructure.compute.fargate)i.add("ecs:CreateCluster"),i.add("ecs:DeleteCluster"),i.add("ecs:CreateService"),i.add("ecs:UpdateService"),i.add("ecs:DeleteService"),i.add("ecs:RegisterTaskDefinition")}if(n.infrastructure.database){if(n.infrastructure.database.postgres||n.infrastructure.database.mysql)i.add("rds:CreateDBInstance"),i.add("rds:DeleteDBInstance"),i.add("rds:ModifyDBInstance"),i.add("rds:DescribeDBInstances");if(n.infrastructure.database.dynamodb)i.add("dynamodb:CreateTable"),i.add("dynamodb:DeleteTable"),i.add("dynamodb:UpdateTable"),i.add("dynamodb:DescribeTable")}if(n.infrastructure.functions)i.add("lambda:CreateFunction"),i.add("lambda:DeleteFunction"),i.add("lambda:UpdateFunctionCode"),i.add("lambda:UpdateFunctionConfiguration"),i.add("lambda:AddPermission");if(n.infrastructure.cdn)i.add("cloudfront:CreateDistribution"),i.add("cloudfront:UpdateDistribution"),i.add("cloudfront:DeleteDistribution"),i.add("cloudfront:GetDistribution");if(n.infrastructure.network)i.add("ec2:CreateVpc"),i.add("ec2:DeleteVpc"),i.add("ec2:CreateSubnet"),i.add("ec2:DeleteSubnet"),i.add("ec2:CreateInternetGateway"),i.add("ec2:DeleteInternetGateway"),i.add("ec2:CreateNatGateway"),i.add("ec2:DeleteNatGateway"),i.add("ec2:CreateRouteTable"),i.add("ec2:DeleteRouteTable"),i.add("ec2:CreateSecurityGroup"),i.add("ec2:DeleteSecurityGroup")}return i.add("iam:CreateRole"),i.add("iam:DeleteRole"),i.add("iam:AttachRolePolicy"),i.add("iam:DetachRolePolicy"),i.add("iam:PutRolePolicy"),i.add("iam:GetRole"),i.add("iam:PassRole"),Array.from(i).sort()}function Rb(n){let i=wy(n);return JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Action:i,Resource:"*"}]},null,2)}var te={ec2:{"Running On-Demand Instances":20,"Elastic IPs":5,VPCs:5,"Internet Gateways":5,"NAT Gateways":5,"Security Groups":500},rds:{"DB Instances":40,"DB Snapshots":100,"DB Parameter Groups":50},lambda:{"Concurrent Executions":1000,"Function Storage":80530636800},s3:{Buckets:100},cloudformation:{Stacks:200,StackSets:100},elasticache:{Nodes:100,Clusters:100},dynamodb:{Tables:256},ecs:{Clusters:1e4,"Services per Cluster":2000}};async function Db(n){let i=[];if(q.verbose("Checking AWS service quotas..."),n.infrastructure?.compute?.server){let o=n.infrastructure.compute.server.autoScaling?.max||1;i.push({service:"EC2",quotaName:"Running On-Demand Instances",currentValue:o,limit:te.ec2["Running On-Demand Instances"],percentage:o/te.ec2["Running On-Demand Instances"]*100,warning:o>te.ec2["Running On-Demand Instances"]*0.8})}if(n.infrastructure?.network?.vpc)i.push({service:"EC2",quotaName:"VPCs",currentValue:1,limit:te.ec2.VPCs,percentage:1/te.ec2.VPCs*100,warning:!1});if(n.infrastructure?.database?.postgres||n.infrastructure?.database?.mysql)i.push({service:"RDS",quotaName:"DB Instances",currentValue:1,limit:te.rds["DB Instances"],percentage:1/te.rds["DB Instances"]*100,warning:!1});if(n.infrastructure?.storage){let o=Object.keys(n.infrastructure.storage).length;i.push({service:"S3",quotaName:"Buckets",currentValue:o,limit:te.s3.Buckets,percentage:o/te.s3.Buckets*100,warning:o>te.s3.Buckets*0.8})}if(n.infrastructure?.functions){let o=0;for(let c of Object.values(n.infrastructure.functions))if(Array.isArray(c))o+=c.length;i.push({service:"Lambda",quotaName:"Functions (estimated)",currentValue:o,limit:1000,percentage:o/1000*100,warning:o>800})}if(n.infrastructure?.database?.dynamodb){let o=n.infrastructure.database.dynamodb.tables?.length||0;i.push({service:"DynamoDB",quotaName:"Tables",currentValue:o,limit:te.dynamodb.Tables,percentage:o/te.dynamodb.Tables*100,warning:o>te.dynamodb.Tables*0.8})}let s=i.filter((o)=>o.warning);if(s.length>0){q.warn("Service quota warnings detected:");for(let o of s)q.warn(` ${o.service} - ${o.quotaName}: ${o.currentValue}/${o.limit} (${o.percentage.toFixed(1)}%)`)}else q.verbose("All service quotas are within limits");return i}function Pb(n){if(n.length===0)return"No quotas to check";let i=`Service Quota Usage:
2471
2471
 
2472
2472
  `,s=n.reduce((o,c)=>{if(!o[c.service])o[c.service]=[];return o[c.service].push(c),o},{});for(let[o,c]of Object.entries(s)){i+=`${o}:
2473
2473
  `;for(let u of c){let d=u.warning?"⚠":"✓";i+=` ${d} ${u.quotaName}: ${u.currentValue}/${u.limit} (${u.percentage.toFixed(1)}%)
2474
2474
  `}i+=`
2475
- `}return i}function Pb(n){let i=[];for(let s of n)if(s.percentage>=100)i.push(`Request quota increase for ${s.service} - ${s.quotaName} (currently ${s.limit})`);else if(s.warning)i.push(`Consider requesting quota increase for ${s.service} - ${s.quotaName} (${s.percentage.toFixed(1)}% used)`);return i}import{createHash as Wn}from"node:crypto";import{existsSync as ut,mkdirSync as hi,readdirSync as Gn,readFileSync as _n,unlinkSync as Qe,writeFileSync as bi}from"node:fs";import{join as Lt}from"node:path";class Al{cacheDir;ttl;constructor(n,i={}){this.cacheDir=n,this.ttl=i.ttl||86400000}ensureCacheDir(){if(!ut(this.cacheDir))hi(this.cacheDir,{recursive:!0})}getCachePath(n){let i=Wn("sha256").update(n).digest("hex");return Lt(this.cacheDir,`${i}.json`)}get(n){let i=this.getCachePath(n);if(!ut(i))return;try{let s=_n(i,"utf-8"),o=JSON.parse(s);if(Date.now()-o.timestamp>this.ttl){Qe(i);return}return o.value}catch{Qe(i);return}}set(n,i,s){this.ensureCacheDir();let o=this.getCachePath(n),c={value:i,timestamp:Date.now(),hash:s};bi(o,JSON.stringify(c),"utf-8")}has(n){return this.get(n)!==void 0}clear(){if(!ut(this.cacheDir))return;let n=Gn(this.cacheDir);for(let i of n)Qe(Lt(this.cacheDir,i))}prune(){if(!ut(this.cacheDir))return;let n=Gn(this.cacheDir),i=Date.now();for(let s of n){let o=Lt(this.cacheDir,s);try{let c=_n(o,"utf-8"),u=JSON.parse(c);if(i-u.timestamp>this.ttl)Qe(o)}catch{Qe(o)}}}}class yl{cache;constructor(n=Q("cache","templates")){this.cache=new Al(n,{ttl:86400000})}getTemplate(n){return this.cache.get(`template:${n}`)}setTemplate(n,i){let s=this.hashTemplate(i);this.cache.set(`template:${n}`,i,s)}hasChanged(n,i){let s=this.cache.get(`template:${n}`);if(!s)return!0;let o=this.hashTemplate(s),c=this.hashTemplate(i);return o!==c}hashTemplate(n){return Wn("sha256").update(n).digest("hex")}clear(){this.cache.clear()}prune(){this.cache.prune()}}var Ot=null;function wy(){if(!Ot)Ot=new yl;return Ot}import{createHash as $t}from"node:crypto";import{createReadStream as Si,readdirSync as Ai,statSync as dt}from"node:fs";import{join as Ci,relative as vi}from"node:path";async function Mm(n,i={}){let s=i.algorithm||"sha256",o=i.chunkSize||65536;return new Promise((c,u)=>{let d=$t(s),p=Si(n,{highWaterMark:o});p.on("data",(y)=>d.update(y)),p.on("end",()=>c(d.digest("hex"))),p.on("error",u)})}function Fm(n,i="sha256"){return $t(i).update(n).digest("hex")}function kb(n,i="sha256"){return $t(i).update(n).digest("hex")}async function Nb(n,i={}){let s=i.ignorePatterns||["node_modules",".git","dist","build",cn()],o=[];async function c(u){let d=Ai(u,{withFileTypes:!0});for(let p of d){let y=Ci(u,p.name),h=vi(n,y);if(s.some((b)=>h.includes(b)))continue;if(p.isDirectory())await c(y);else if(p.isFile()){let b=dt(y),v=await Mm(y,i);o.push({path:h,hash:v,size:b.size,mtime:b.mtimeMs})}}}return await c(n),o}function Bb(n){let s=[...n].sort((o,c)=>o.path.localeCompare(c.path)).map((o)=>`${o.path}:${o.hash}`).join(`
2476
- `);return Fm(s)}function xb(n){let i=dt(n);return Fm(`${n}:${i.size}:${i.mtimeMs}`)}function Ob(n,i){let s=new Map(n.map((p)=>[p.path,p])),o=new Map(i.map((p)=>[p.path,p])),c=[],u=[],d=[];for(let[p,y]of o){let h=s.get(p);if(!h)c.push(y);else if(h.hash!==y.hash)u.push(y)}for(let[p,y]of s)if(!o.has(p))d.push(y);return{added:c,modified:u,deleted:d}}class Ry{cache;constructor(){this.cache=new Map}get(n){let i=dt(n),s=this.cache.get(n);if(s&&s.mtime===i.mtimeMs&&s.size===i.size)return s.hash;return}set(n,i){let s=dt(n);this.cache.set(n,{hash:i,mtime:s.mtimeMs,size:s.size})}async getOrCompute(n,i={}){let s=this.get(n);if(s)return s;let o=await Mm(n,i);return this.set(n,o),o}clear(){this.cache.clear()}}async function Sl(n,i={}){let s=i.concurrency||5,o=i.stopOnError??!0,c=[],u=[],d=Date.now(),p=[...n],y=[];async function h(A,T){try{let R=await A();c[T]=R}catch(R){let P=R instanceof Error?R:Error(String(R));if(u.push(P),o)throw p.length=0,P}}let b=0;while(p.length>0||y.length>0){while(y.length<s&&p.length>0){let A=p.shift(),T=b++,R=h(A,T);y.push(R)}if(y.length>0){await Promise.race(y);for(let A=y.length-1;A>=0;A--)if(await Promise.race([y[A].then(()=>!0),Promise.resolve(!1)]))y.splice(A,1)}if(o&&u.length>0)break}let v=Date.now()-d;return{results:c.filter((A)=>A!==void 0),errors:u,duration:v}}async function _b(n,i,s={}){let o=n.map((c)=>()=>i(c));return Sl(o,s)}async function Lb(n,i,s=5){let o=n.map((u,d)=>()=>i(u,d)),c=await Sl(o,{concurrency:s,stopOnError:!1});if(c.errors.length>0)throw AggregateError(c.errors,"Parallel map failed");return c.results}async function $b(n,i={}){let s=i.retries||3,o=i.retryDelay||1000,c=n.map((u)=>async()=>{let d;for(let p=0;p<=s;p++)try{return await u()}catch(y){if(d=y instanceof Error?y:Error(String(y)),p<s)await Vn(o*(p+1))}throw d});return Sl(c,i)}async function Mb(n){let i=[];for(let s of n){let o=await s();i.push(o)}return i}function Vn(n){return new Promise((i)=>setTimeout(i,n))}async function Fb(n,i,s="Operation timed out"){return Promise.race([n(),new Promise((o,c)=>setTimeout(()=>c(Error(s)),i))])}class Dy{maxConcurrent;minInterval;queue=[];running=0;lastExecution=0;constructor(n=5,i=100){this.maxConcurrent=n;this.minInterval=i}async execute(n){await this.waitForSlot(),this.running++,this.lastExecution=Date.now();try{return await n()}finally{this.running--,this.processQueue()}}waitForSlot(){if(this.running<this.maxConcurrent){let n=Date.now()-this.lastExecution;if(n>=this.minInterval)return Promise.resolve();return Vn(this.minInterval-n)}return new Promise((n)=>this.queue.push(n))}processQueue(){if(this.queue.length>0&&this.running<this.maxConcurrent)this.queue.shift()()}stats(){return{running:this.running,queued:this.queue.length}}}function Py(n,i){let s=[];for(let o=0;o<n.length;o+=i)s.push(n.slice(o,o+i));return s}async function Ub(n,i,s){let o=Py(n,i),c=[];for(let u of o){let d=await s(u);c.push(...d)}return c}function Qb(n,i){let s=[],o=[],c=[],u=[],d=n.Resources||{},p=i.Resources||{},y=new Set(Object.keys(d)),h=new Set(Object.keys(p));for(let A of h)if(!y.has(A))s.push(A);for(let A of y)if(!h.has(A))c.push(A);for(let A of h)if(y.has(A)){let T=d[A],R=p[A];if(JSON.stringify(T)!==JSON.stringify(R))o.push(A);else u.push(A)}let b=JSON.stringify(n.Parameters||{})!==JSON.stringify(i.Parameters||{}),v=JSON.stringify(n.Outputs||{})!==JSON.stringify(i.Outputs||{});return{added:s,modified:o,deleted:c,unchanged:u,parametersChanged:b,outputsChanged:v,hasChanges:s.length>0||o.length>0||c.length>0||b||v}}function Hb(n){let i=[];if(!n.hasChanges)return"No changes detected";if(n.added.length>0){i.push(`Added resources (${n.added.length}):`);for(let s of n.added)i.push(` + ${s}`)}if(n.modified.length>0){i.push(`Modified resources (${n.modified.length}):`);for(let s of n.modified)i.push(` ~ ${s}`)}if(n.deleted.length>0){i.push(`Deleted resources (${n.deleted.length}):`);for(let s of n.deleted)i.push(` - ${s}`)}if(n.parametersChanged)i.push("Parameters changed");if(n.outputsChanged)i.push("Outputs changed");return i.join(`
2477
- `)}function Gb(n,i,s){if(n.deleted.length>0)return!0;for(let o of n.modified){let c=i.Resources[o],u=s.Resources[o];if(c.Type!==u.Type)return!0;let d=Ti(u.Type);for(let p of d){let y=c.Properties?.[p],h=u.Properties?.[p];if(JSON.stringify(y)!==JSON.stringify(h))return!0}}return!1}function Ti(n){return{"AWS::S3::Bucket":["BucketName"],"AWS::EC2::Instance":["ImageId","InstanceType","KeyName"],"AWS::RDS::DBInstance":["DBInstanceIdentifier","Engine"],"AWS::DynamoDB::Table":["TableName","KeySchema"],"AWS::Lambda::Function":["FunctionName"],"AWS::ECS::Service":["ServiceName"],"AWS::ElasticLoadBalancingV2::LoadBalancer":["Name","Type"]}[n]||[]}function Vb(n){let i=[],s=[],o=[];i.push(...n.added);for(let c of n.modified)s.push(c);return o.push(...n.deleted),{safe:i,caution:s,dangerous:o}}function qb(n){if(!n.hasChanges)return{strategy:"skip",reason:"No changes detected"};if(n.deleted.length>0)return{strategy:"replace",reason:"Resources will be deleted"};if(n.added.length>0&&n.modified.length===0)return{strategy:"update",reason:"Only new resources added"};return{strategy:"update",reason:"Resources will be updated"}}function jb(n){let i=n.added.length+n.modified.length+n.deleted.length+n.unchanged.length,s=n.added.length+n.modified.length+n.deleted.length,o=i>0?s/i*100:0;return{total:i,added:n.added.length,modified:n.modified.length,deleted:n.deleted.length,unchanged:n.unchanged.length,changePercentage:o}}var ky={$schema:"http://json-schema.org/draft-07/schema#",title:"ts-cloud Configuration",description:"Configuration schema for ts-cloud infrastructure-as-code",type:"object",required:["project"],properties:{project:{type:"object",description:"Project configuration",required:["name","slug"],properties:{name:{type:"string",description:"Human-readable project name",minLength:1},slug:{type:"string",description:"URL-safe project identifier (lowercase, alphanumeric, hyphens only)",pattern:"^[a-z0-9-]+$",minLength:1,maxLength:63},region:{type:"string",description:"Default AWS region",enum:["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ap-southeast-1","ap-southeast-2","ap-northeast-1","ap-northeast-2","sa-east-1","ca-central-1"]}}},mode:{type:"string",description:"Deployment mode (server and serverless are mutually exclusive; auto-detected when omitted)",enum:["server","serverless"]},environments:{type:"object",description:"Environment-specific configurations",properties:{production:{$ref:"#/definitions/environment"},staging:{$ref:"#/definitions/environment"},development:{$ref:"#/definitions/environment"}}},infrastructure:{type:"object",description:"Infrastructure configuration",properties:{network:{$ref:"#/definitions/network"},storage:{type:"object",description:"S3 storage configuration",additionalProperties:{$ref:"#/definitions/storage"}},compute:{$ref:"#/definitions/compute"},database:{$ref:"#/definitions/database"},cache:{$ref:"#/definitions/cache"},cdn:{$ref:"#/definitions/cdn"},sftp:{$ref:"#/definitions/sftp"},functions:{type:"object",description:"Lambda functions configuration",additionalProperties:{type:"array",items:{$ref:"#/definitions/function"}}},monitoring:{$ref:"#/definitions/monitoring"},security:{$ref:"#/definitions/security"},queue:{type:"object",description:"SQS queue configuration",additionalProperties:{$ref:"#/definitions/queue"}}}}},definitions:{environment:{type:"object",properties:{domain:{type:"string",description:"Custom domain for this environment"},region:{type:"string",description:"AWS region override for this environment"},app:{type:"object",description:"Serverless application manifest (Laravel-Vapor-equivalent). Defining this opts the environment into the serverless app deploy pipeline (http/queue/cli Lambda functions, assets, build/deploy hooks).",properties:{runtime:{type:"string",description:"Lambda runtime override (usually derived from kind + runtimeVersion)"},runtimeVersion:{type:"string",description:"Node major (18/20/22 managed, 24+ custom layer) or Bun release for node/bun apps"},kind:{type:"string",enum:["node","bun","php"],description:"Application kind (drives packaging + runtime)"},entry:{type:"string",description:"Entry file exporting the request handler"},memory:{type:"number",description:"HTTP function memory in MB"},timeout:{type:"number",description:"HTTP request timeout in seconds"},gatewayVersion:{type:"number",enum:[1,2],description:"API Gateway version (2 = HTTP API, 1 = REST)"},warm:{type:"number",description:"Keep-warm / provisioned concurrency count"},lambdaInsights:{type:"object",description:"CloudWatch Lambda Insights extension configuration for zip deployments",required:["layerArn"],properties:{layerArn:{type:"string",description:"Region- and architecture-specific Lambda Insights extension layer ARN"}}},queues:{description:"Queue names (true = single default queue, false = disabled)"},scheduler:{type:"string",enum:["off","on","sub-minute"],description:"Task scheduler mode"},build:{type:"array",items:{type:"string"},description:"Commands run locally before packaging"},deploy:{type:"array",items:{type:"string"},description:"Commands run remotely after activation (e.g. migrations)"},octane:{type:"boolean",description:"Persistent application mode (Laravel Octane)"},packaging:{type:"string",enum:["zip","image"],description:"Deployment package format (zip or container image)"},phpVersion:{type:"string",description:"PHP version for the runtime layer (kind: php)"},architecture:{type:"string",enum:["x86_64","arm64"],description:"CPU architecture"}}}}},network:{type:"object",properties:{vpc:{type:"object",properties:{cidr:{type:"string",description:"VPC CIDR block",pattern:"^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$",default:"10.0.0.0/16"},availabilityZones:{type:"number",description:"Number of availability zones",minimum:1,maximum:3,default:2},natGateways:{type:"number",description:"Number of NAT gateways (0 for no NAT, saves cost)",minimum:0,maximum:3,default:1}}}}},storage:{type:"object",properties:{public:{type:"boolean",description:"Allow public access",default:!1},versioning:{type:"boolean",description:"Enable versioning",default:!1},encryption:{type:"boolean",description:"Enable server-side encryption",default:!0},website:{type:"boolean",description:"Enable static website hosting",default:!1},cors:{type:"object",description:"CORS configuration",properties:{allowedOrigins:{type:"array",items:{type:"string"}},allowedMethods:{type:"array",items:{type:"string",enum:["GET","PUT","POST","DELETE","HEAD"]}}}}}},compute:{type:"object",properties:{server:{type:"object",description:"EC2 server configuration",properties:{instanceType:{type:"string",description:"EC2 instance type",enum:["t3.micro","t3.small","t3.medium","t3.large","t3.xlarge","t3.2xlarge"]},autoScaling:{type:"object",properties:{min:{type:"number",minimum:1},max:{type:"number",minimum:1},desired:{type:"number",minimum:1}}}}},fargate:{type:"object",description:"ECS Fargate configuration",properties:{cpu:{type:"number",description:"CPU units (256, 512, 1024, 2048, 4096)",enum:[256,512,1024,2048,4096]},memory:{type:"number",description:"Memory in MB"},desiredCount:{type:"number",description:"Desired number of tasks",minimum:1}}}}},database:{type:"object",properties:{postgres:{type:"object",properties:{instanceClass:{type:"string",description:"RDS instance class",pattern:"^db\\.[a-z0-9]+\\.[a-z0-9]+$"},engine:{type:"string",const:"postgres"},version:{type:"string",description:"PostgreSQL version"},multiAZ:{type:"boolean",description:"Enable Multi-AZ deployment",default:!1},backupRetentionDays:{type:"number",description:"Backup retention period in days",minimum:0,maximum:35,default:7}}},mysql:{type:"object",properties:{instanceClass:{type:"string",pattern:"^db\\.[a-z0-9]+\\.[a-z0-9]+$"},engine:{type:"string",const:"mysql"},version:{type:"string"},multiAZ:{type:"boolean",default:!1},backupRetentionDays:{type:"number",minimum:0,maximum:35,default:7}}},dynamodb:{type:"object",properties:{tables:{type:"array",items:{type:"object",required:["name","partitionKey"],properties:{name:{type:"string"},partitionKey:{type:"string"},sortKey:{type:"string"},billingMode:{type:"string",enum:["PAY_PER_REQUEST","PROVISIONED"],default:"PAY_PER_REQUEST"}}}}}}}},cache:{type:"object",properties:{redis:{type:"object",properties:{nodeType:{type:"string",description:"ElastiCache node type",pattern:"^cache\\.[a-z0-9]+\\.[a-z0-9]+$"},numCacheNodes:{type:"number",minimum:1,default:1},engineVersion:{type:"string",description:"Redis engine version"}}},memcached:{type:"object",properties:{nodeType:{type:"string",pattern:"^cache\\.[a-z0-9]+\\.[a-z0-9]+$"},numCacheNodes:{type:"number",minimum:1,default:1}}}}},cdn:{type:"object",properties:{enabled:{type:"boolean",default:!0},originShield:{type:"boolean",description:"Enable CloudFront Origin Shield",default:!1},originShieldRegion:{type:"string",description:"AWS region used by CloudFront Origin Shield"},compress:{type:"boolean",description:"Enable automatic compression",default:!0},http3:{type:"boolean",description:"Enable HTTP/3 support",default:!0},customDomain:{type:"object",properties:{domain:{type:"string"},certificateArn:{type:"string"}}},cachePolicy:{type:"object",properties:{minTTL:{type:"number",minimum:0},defaultTTL:{type:"number",minimum:0},maxTTL:{type:"number",minimum:0}}}}},sftp:{type:"object",required:["bucket","users"],properties:{bucket:{type:"string",description:"S3 bucket backing the SFTP server"},endpointType:{type:"string",enum:["PUBLIC","VPC"],default:"PUBLIC"},endpointDetails:{type:"object",required:["vpcId","subnetIds"],properties:{vpcId:{type:"string"},subnetIds:{type:"array",items:{type:"string"},minItems:1},securityGroupIds:{type:"array",items:{type:"string"}},addressAllocationIds:{type:"array",items:{type:"string"}}}},securityPolicyName:{type:"string"},logging:{type:"boolean",default:!0},users:{type:"object",additionalProperties:{type:"object",required:["sshPublicKeys"],properties:{sshPublicKeys:{type:"array",items:{type:"string"},minItems:1},homeDirectory:{type:"string"},roleArn:{type:"string"}}}}}},function:{type:"object",required:["name","runtime"],properties:{name:{type:"string"},runtime:{type:"string",enum:["nodejs18.x","nodejs20.x","python3.10","python3.11","python3.12"]},handler:{type:"string",default:"index.handler"},timeout:{type:"number",minimum:1,maximum:900,default:30},memory:{type:"number",minimum:128,maximum:10240,default:1024}}},monitoring:{type:"object",properties:{alarms:{type:"array",items:{type:"object",required:["metric","threshold"],properties:{metric:{type:"string"},threshold:{type:"number"},evaluationPeriods:{type:"number",minimum:1,default:2}}}},dashboard:{type:"object",properties:{name:{type:"string"},widgets:{type:"array"}}}}},security:{type:"object",properties:{waf:{type:"boolean",description:"Enable AWS WAF",default:!1},certificates:{type:"array",items:{type:"object",required:["domain"],properties:{domain:{type:"string"},subdomains:{type:"array",items:{type:"string"}}}}}}},queue:{type:"object",properties:{fifo:{type:"boolean",default:!1},deadLetterQueue:{type:"boolean",default:!0},visibilityTimeout:{type:"number",minimum:0,maximum:43200,default:30},messageRetentionPeriod:{type:"number",minimum:60,maximum:1209600,default:345600}}}}};function zb(n){let i=[];if(!n.project)i.push("Missing required field: project");else{if(!n.project.name)i.push("Missing required field: project.name");if(!n.project.slug)i.push("Missing required field: project.slug")}if(n.project?.slug&&!/^[a-z0-9-]+$/.test(n.project.slug))i.push("Invalid project.slug: must contain only lowercase letters, numbers, and hyphens");let s=["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ap-southeast-1","ap-southeast-2","ap-northeast-1","ap-northeast-2","sa-east-1","ca-central-1"];if(n.project?.region&&!s.includes(n.project.region))i.push(`Invalid region: ${n.project.region}. Must be one of: ${s.join(", ")}`);if(n.mode&&!["server","serverless"].includes(n.mode))i.push("Invalid mode: must be one of server or serverless");return{valid:i.length===0,errors:i}}var Um={enabled:process.env.TS_CLOUD_LOCAL==="true"||!0,localstackEndpoint:process.env.LOCALSTACK_ENDPOINT||"http://localhost:4566",postgresUrl:process.env.POSTGRES_URL||"postgresql://tscloud:tscloud@localhost:5432/tscloud",redisUrl:process.env.REDIS_URL||"redis://localhost:6379",dynamodbEndpoint:process.env.DYNAMODB_ENDPOINT||"http://localhost:8000",s3Endpoint:process.env.S3_ENDPOINT||"http://localhost:9000",emailEndpoint:process.env.EMAIL_ENDPOINT||"smtp://localhost:1025",awsRegion:process.env.AWS_REGION||"us-east-1",awsAccessKeyId:process.env.AWS_ACCESS_KEY_ID||"test",awsSecretAccessKey:process.env.AWS_SECRET_ACCESS_KEY||"test"};function Il(){return Um}function Kb(){return Um.enabled}function Wb(n){let i=Il();if(!i.enabled)return"";switch(n.toLowerCase()){case"dynamodb":return i.dynamodbEndpoint;case"s3":return i.s3Endpoint;case"localstack":case"cloudformation":case"lambda":case"apigateway":case"sns":case"sqs":case"cloudwatch":case"iam":case"sts":return i.localstackEndpoint;default:return i.localstackEndpoint}}function Jb(){let n=Il();return{accessKeyId:n.awsAccessKeyId,secretAccessKey:n.awsSecretAccessKey,region:n.awsRegion}}function Xb(){let n=Il();if(!n.enabled)return{};return{AWS_ACCESS_KEY_ID:n.awsAccessKeyId,AWS_SECRET_ACCESS_KEY:n.awsSecretAccessKey,AWS_REGION:n.awsRegion,AWS_ENDPOINT_URL:n.localstackEndpoint,LOCALSTACK_ENDPOINT:n.localstackEndpoint,TS_CLOUD_LOCAL:"true"}}class Qm{stacks=new Map;stackEvents=new Map;async createStack(n){let i=`arn:aws:cloudformation:${n.region||"us-east-1"}:123456789012:stack/${n.StackName}/${Date.now()}`;return this.stacks.set(n.StackName,{StackId:i,StackName:n.StackName,StackStatus:"CREATE_IN_PROGRESS",CreationTime:new Date().toISOString(),TemplateBody:n.TemplateBody,Parameters:n.Parameters||[]}),this.addEvent(n.StackName,{EventId:Date.now().toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"CREATE_IN_PROGRESS"}),setTimeout(()=>{let s=this.stacks.get(n.StackName);if(s)s.StackStatus="CREATE_COMPLETE",this.addEvent(n.StackName,{EventId:(Date.now()+1).toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"CREATE_COMPLETE"})},100),{StackId:i}}async updateStack(n){let i=this.stacks.get(n.StackName);if(!i)throw Error(`Stack ${n.StackName} does not exist`);return i.StackStatus="UPDATE_IN_PROGRESS",i.TemplateBody=n.TemplateBody||i.TemplateBody,this.addEvent(n.StackName,{EventId:Date.now().toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"UPDATE_IN_PROGRESS"}),setTimeout(()=>{i.StackStatus="UPDATE_COMPLETE",this.addEvent(n.StackName,{EventId:(Date.now()+1).toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"UPDATE_COMPLETE"})},100),{StackId:i.StackId}}async deleteStack(n){let i=this.stacks.get(n.StackName);if(!i)throw Error(`Stack ${n.StackName} does not exist`);i.StackStatus="DELETE_IN_PROGRESS",this.addEvent(n.StackName,{EventId:Date.now().toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"DELETE_IN_PROGRESS"}),setTimeout(()=>{this.stacks.delete(n.StackName),this.addEvent(n.StackName,{EventId:(Date.now()+1).toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"DELETE_COMPLETE"})},100)}async describeStacks(n){if(n.StackName){let i=this.stacks.get(n.StackName);if(!i)throw Error(`Stack ${n.StackName} does not exist`);return{Stacks:[i]}}return{Stacks:Array.from(this.stacks.values())}}async describeStackEvents(n){return{StackEvents:this.stackEvents.get(n.StackName)||[]}}addEvent(n,i){if(!this.stackEvents.has(n))this.stackEvents.set(n,[]);this.stackEvents.get(n).unshift(i)}reset(){this.stacks.clear(),this.stackEvents.clear()}}class Hm{buckets=new Map;async createBucket(n){return this.buckets.set(n.Bucket,new Map),{Location:`/${n.Bucket}`}}async deleteBucket(n){this.buckets.delete(n.Bucket)}async putObject(n){let i=this.buckets.get(n.Bucket);if(!i)i=new Map,this.buckets.set(n.Bucket,i);return i.set(n.Key,Buffer.from(n.Body||"")),{ETag:`"${Date.now()}"`}}async getObject(n){let i=this.buckets.get(n.Bucket);if(!i)throw Error(`Bucket ${n.Bucket} does not exist`);let s=i.get(n.Key);if(!s)throw Error(`Object ${n.Key} does not exist`);return{Body:s,ContentLength:s.length}}async deleteObject(n){let i=this.buckets.get(n.Bucket);if(i)i.delete(n.Key)}async listObjects(n){let i=this.buckets.get(n.Bucket);if(!i)throw Error(`Bucket ${n.Bucket} does not exist`);return{Contents:Array.from(i.keys()).map((o)=>({Key:o,Size:i.get(o).length,LastModified:new Date().toISOString()}))}}reset(){this.buckets.clear()}}class Gm{tables=new Map;data=new Map;async createTable(n){return this.tables.set(n.TableName,{TableName:n.TableName,KeySchema:n.KeySchema,AttributeDefinitions:n.AttributeDefinitions,TableStatus:"ACTIVE",CreationDateTime:new Date().toISOString()}),this.data.set(n.TableName,new Map),{TableDescription:this.tables.get(n.TableName)}}async deleteTable(n){this.tables.delete(n.TableName),this.data.delete(n.TableName)}async putItem(n){let i=this.data.get(n.TableName);if(!i)i=new Map,this.data.set(n.TableName,i);let s=JSON.stringify(n.Item);i.set(s,n.Item)}async getItem(n){let i=this.data.get(n.TableName);if(!i)return{};let s=JSON.stringify(n.Key),o=i.get(s);return o?{Item:o}:{}}async deleteItem(n){let i=this.data.get(n.TableName);if(i){let s=JSON.stringify(n.Key);i.delete(s)}}async scan(n){let i=this.data.get(n.TableName);if(!i)return{Items:[]};return{Items:Array.from(i.values())}}reset(){this.tables.clear(),this.data.clear()}}function Yb(n){return{cloudformation:new Qm,s3:new Hm,dynamodb:new Gm}}class bl{environments=new Map;async createPreviewEnvironment(n){let{branch:i,pr:s,commitSha:o,ttl:c=24,baseConfig:u,region:d="us-east-1"}=n,p=this.generatePreviewId(i,s,o),y=this.generatePreviewName(i,s),h=`preview-${y}`,b=new Date,v=new Date(b.getTime()+c*60*60*1000),A={id:p,name:y,branch:i,pr:s,commitSha:o,createdAt:b,expiresAt:v,status:"creating",stackName:h,region:d,resources:[]};this.environments.set(p,A);try{let T=this.createPreviewConfig(u,y);return A.status="active",A.url=`https://${y}.preview.example.com`,A}catch(T){throw A.status="failed",T}}async destroyPreviewEnvironment(n){let i=this.environments.get(n);if(!i)throw Error(`Preview environment ${n} not found`);i.status="destroying";try{i.status="destroyed",this.environments.delete(n)}catch(s){throw Error(`Failed to destroy preview environment: ${s}`)}}getPreviewEnvironment(n){return this.environments.get(n)}getPreviewEnvironmentByBranch(n){return Array.from(this.environments.values()).find((i)=>i.branch===n)}getPreviewEnvironmentByPR(n){return Array.from(this.environments.values()).find((i)=>i.pr===n)}listPreviewEnvironments(){return Array.from(this.environments.values())}listActivePreviewEnvironments(){return this.listPreviewEnvironments().filter((n)=>n.status==="active")}async cleanupExpiredEnvironments(n={}){let{maxAge:i,keepCount:s,dryRun:o=!1}=n,c=[],u=[],d=new Date,p=this.listPreviewEnvironments().sort((y,h)=>h.createdAt.getTime()-y.createdAt.getTime());for(let y=0;y<p.length;y++){let h=p[y];if(h.status!=="active")continue;let b=!1;if(h.expiresAt<d)b=!0;if(i){if((d.getTime()-h.createdAt.getTime())/3600000>i)b=!0}if(s&&y>=s)b=!0;if(b)if(o)c.push(h.id);else try{await this.destroyPreviewEnvironment(h.id),c.push(h.id)}catch(v){u.push(h.id)}}return{destroyed:c,failed:u}}async updatePreviewEnvironment(n,i){let s=this.environments.get(n);if(!s)throw Error(`Preview environment ${n} not found`);s.commitSha=i,s.status="creating";try{return s.status="active",s}catch(o){throw s.status="failed",o}}async getPreviewEnvironmentsCost(){let n={},i=0;for(let s of this.environments.values())n[s.id]=0,i+=0;return{total:i,byEnvironment:n}}generatePreviewId(n,i,s){let o=n.replace(/[^a-z0-9-]/gi,"-").toLowerCase(),c=s?.substring(0,7)||Date.now().toString();return i?`pr-${i}-${c}`:`${o}-${c}`}generatePreviewName(n,i){let s=n.replace(/[^a-z0-9-]/gi,"-").toLowerCase();return i?`pr-${i}`:s}createPreviewConfig(n,i){return{...n,project:{...n.project,name:`${n.project.name} Preview (${i})`,slug:`${n.project.slug}-preview-${i}`}}}}var Ny=new bl;function By(n={}){let{workflowName:i="Preview Environment",trigger:s="pull_request",branches:o=["main","develop"],awsRegion:c="us-east-1",awsRole:u,configFile:d="cloud.config.ts",ttl:p=24}=n;return`name: ${i}
2475
+ `}return i}function kb(n){let i=[];for(let s of n)if(s.percentage>=100)i.push(`Request quota increase for ${s.service} - ${s.quotaName} (currently ${s.limit})`);else if(s.warning)i.push(`Consider requesting quota increase for ${s.service} - ${s.quotaName} (${s.percentage.toFixed(1)}% used)`);return i}import{createHash as Wn}from"node:crypto";import{existsSync as ut,mkdirSync as hi,readdirSync as Gn,readFileSync as _n,unlinkSync as Qe,writeFileSync as bi}from"node:fs";import{join as Lt}from"node:path";class Al{cacheDir;ttl;constructor(n,i={}){this.cacheDir=n,this.ttl=i.ttl||86400000}ensureCacheDir(){if(!ut(this.cacheDir))hi(this.cacheDir,{recursive:!0})}getCachePath(n){let i=Wn("sha256").update(n).digest("hex");return Lt(this.cacheDir,`${i}.json`)}get(n){let i=this.getCachePath(n);if(!ut(i))return;try{let s=_n(i,"utf-8"),o=JSON.parse(s);if(Date.now()-o.timestamp>this.ttl){Qe(i);return}return o.value}catch{Qe(i);return}}set(n,i,s){this.ensureCacheDir();let o=this.getCachePath(n),c={value:i,timestamp:Date.now(),hash:s};bi(o,JSON.stringify(c),"utf-8")}has(n){return this.get(n)!==void 0}clear(){if(!ut(this.cacheDir))return;let n=Gn(this.cacheDir);for(let i of n)Qe(Lt(this.cacheDir,i))}prune(){if(!ut(this.cacheDir))return;let n=Gn(this.cacheDir),i=Date.now();for(let s of n){let o=Lt(this.cacheDir,s);try{let c=_n(o,"utf-8"),u=JSON.parse(c);if(i-u.timestamp>this.ttl)Qe(o)}catch{Qe(o)}}}}class yl{cache;constructor(n=Q("cache","templates")){this.cache=new Al(n,{ttl:86400000})}getTemplate(n){return this.cache.get(`template:${n}`)}setTemplate(n,i){let s=this.hashTemplate(i);this.cache.set(`template:${n}`,i,s)}hasChanged(n,i){let s=this.cache.get(`template:${n}`);if(!s)return!0;let o=this.hashTemplate(s),c=this.hashTemplate(i);return o!==c}hashTemplate(n){return Wn("sha256").update(n).digest("hex")}clear(){this.cache.clear()}prune(){this.cache.prune()}}var Ot=null;function Ry(){if(!Ot)Ot=new yl;return Ot}import{createHash as $t}from"node:crypto";import{createReadStream as Si,readdirSync as Ai,statSync as dt}from"node:fs";import{join as Ci,relative as vi}from"node:path";async function Fm(n,i={}){let s=i.algorithm||"sha256",o=i.chunkSize||65536;return new Promise((c,u)=>{let d=$t(s),p=Si(n,{highWaterMark:o});p.on("data",(y)=>d.update(y)),p.on("end",()=>c(d.digest("hex"))),p.on("error",u)})}function Um(n,i="sha256"){return $t(i).update(n).digest("hex")}function Nb(n,i="sha256"){return $t(i).update(n).digest("hex")}async function Bb(n,i={}){let s=i.ignorePatterns||["node_modules",".git","dist","build",cn()],o=[];async function c(u){let d=Ai(u,{withFileTypes:!0});for(let p of d){let y=Ci(u,p.name),h=vi(n,y);if(s.some((b)=>h.includes(b)))continue;if(p.isDirectory())await c(y);else if(p.isFile()){let b=dt(y),v=await Fm(y,i);o.push({path:h,hash:v,size:b.size,mtime:b.mtimeMs})}}}return await c(n),o}function xb(n){let s=[...n].sort((o,c)=>o.path.localeCompare(c.path)).map((o)=>`${o.path}:${o.hash}`).join(`
2476
+ `);return Um(s)}function Ob(n){let i=dt(n);return Um(`${n}:${i.size}:${i.mtimeMs}`)}function _b(n,i){let s=new Map(n.map((p)=>[p.path,p])),o=new Map(i.map((p)=>[p.path,p])),c=[],u=[],d=[];for(let[p,y]of o){let h=s.get(p);if(!h)c.push(y);else if(h.hash!==y.hash)u.push(y)}for(let[p,y]of s)if(!o.has(p))d.push(y);return{added:c,modified:u,deleted:d}}class Dy{cache;constructor(){this.cache=new Map}get(n){let i=dt(n),s=this.cache.get(n);if(s&&s.mtime===i.mtimeMs&&s.size===i.size)return s.hash;return}set(n,i){let s=dt(n);this.cache.set(n,{hash:i,mtime:s.mtimeMs,size:s.size})}async getOrCompute(n,i={}){let s=this.get(n);if(s)return s;let o=await Fm(n,i);return this.set(n,o),o}clear(){this.cache.clear()}}async function Sl(n,i={}){let s=i.concurrency||5,o=i.stopOnError??!0,c=[],u=[],d=Date.now(),p=[...n],y=[];async function h(A,T){try{let R=await A();c[T]=R}catch(R){let P=R instanceof Error?R:Error(String(R));if(u.push(P),o)throw p.length=0,P}}let b=0;while(p.length>0||y.length>0){while(y.length<s&&p.length>0){let A=p.shift(),T=b++,R=h(A,T);y.push(R)}if(y.length>0){await Promise.race(y);for(let A=y.length-1;A>=0;A--)if(await Promise.race([y[A].then(()=>!0),Promise.resolve(!1)]))y.splice(A,1)}if(o&&u.length>0)break}let v=Date.now()-d;return{results:c.filter((A)=>A!==void 0),errors:u,duration:v}}async function Lb(n,i,s={}){let o=n.map((c)=>()=>i(c));return Sl(o,s)}async function $b(n,i,s=5){let o=n.map((u,d)=>()=>i(u,d)),c=await Sl(o,{concurrency:s,stopOnError:!1});if(c.errors.length>0)throw AggregateError(c.errors,"Parallel map failed");return c.results}async function Mb(n,i={}){let s=i.retries||3,o=i.retryDelay||1000,c=n.map((u)=>async()=>{let d;for(let p=0;p<=s;p++)try{return await u()}catch(y){if(d=y instanceof Error?y:Error(String(y)),p<s)await Vn(o*(p+1))}throw d});return Sl(c,i)}async function Fb(n){let i=[];for(let s of n){let o=await s();i.push(o)}return i}function Vn(n){return new Promise((i)=>setTimeout(i,n))}async function Ub(n,i,s="Operation timed out"){return Promise.race([n(),new Promise((o,c)=>setTimeout(()=>c(Error(s)),i))])}class Py{maxConcurrent;minInterval;queue=[];running=0;lastExecution=0;constructor(n=5,i=100){this.maxConcurrent=n;this.minInterval=i}async execute(n){await this.waitForSlot(),this.running++,this.lastExecution=Date.now();try{return await n()}finally{this.running--,this.processQueue()}}waitForSlot(){if(this.running<this.maxConcurrent){let n=Date.now()-this.lastExecution;if(n>=this.minInterval)return Promise.resolve();return Vn(this.minInterval-n)}return new Promise((n)=>this.queue.push(n))}processQueue(){if(this.queue.length>0&&this.running<this.maxConcurrent)this.queue.shift()()}stats(){return{running:this.running,queued:this.queue.length}}}function ky(n,i){let s=[];for(let o=0;o<n.length;o+=i)s.push(n.slice(o,o+i));return s}async function Qb(n,i,s){let o=ky(n,i),c=[];for(let u of o){let d=await s(u);c.push(...d)}return c}function Hb(n,i){let s=[],o=[],c=[],u=[],d=n.Resources||{},p=i.Resources||{},y=new Set(Object.keys(d)),h=new Set(Object.keys(p));for(let A of h)if(!y.has(A))s.push(A);for(let A of y)if(!h.has(A))c.push(A);for(let A of h)if(y.has(A)){let T=d[A],R=p[A];if(JSON.stringify(T)!==JSON.stringify(R))o.push(A);else u.push(A)}let b=JSON.stringify(n.Parameters||{})!==JSON.stringify(i.Parameters||{}),v=JSON.stringify(n.Outputs||{})!==JSON.stringify(i.Outputs||{});return{added:s,modified:o,deleted:c,unchanged:u,parametersChanged:b,outputsChanged:v,hasChanges:s.length>0||o.length>0||c.length>0||b||v}}function Gb(n){let i=[];if(!n.hasChanges)return"No changes detected";if(n.added.length>0){i.push(`Added resources (${n.added.length}):`);for(let s of n.added)i.push(` + ${s}`)}if(n.modified.length>0){i.push(`Modified resources (${n.modified.length}):`);for(let s of n.modified)i.push(` ~ ${s}`)}if(n.deleted.length>0){i.push(`Deleted resources (${n.deleted.length}):`);for(let s of n.deleted)i.push(` - ${s}`)}if(n.parametersChanged)i.push("Parameters changed");if(n.outputsChanged)i.push("Outputs changed");return i.join(`
2477
+ `)}function Vb(n,i,s){if(n.deleted.length>0)return!0;for(let o of n.modified){let c=i.Resources[o],u=s.Resources[o];if(c.Type!==u.Type)return!0;let d=Ti(u.Type);for(let p of d){let y=c.Properties?.[p],h=u.Properties?.[p];if(JSON.stringify(y)!==JSON.stringify(h))return!0}}return!1}function Ti(n){return{"AWS::S3::Bucket":["BucketName"],"AWS::EC2::Instance":["ImageId","InstanceType","KeyName"],"AWS::RDS::DBInstance":["DBInstanceIdentifier","Engine"],"AWS::DynamoDB::Table":["TableName","KeySchema"],"AWS::Lambda::Function":["FunctionName"],"AWS::ECS::Service":["ServiceName"],"AWS::ElasticLoadBalancingV2::LoadBalancer":["Name","Type"]}[n]||[]}function qb(n){let i=[],s=[],o=[];i.push(...n.added);for(let c of n.modified)s.push(c);return o.push(...n.deleted),{safe:i,caution:s,dangerous:o}}function jb(n){if(!n.hasChanges)return{strategy:"skip",reason:"No changes detected"};if(n.deleted.length>0)return{strategy:"replace",reason:"Resources will be deleted"};if(n.added.length>0&&n.modified.length===0)return{strategy:"update",reason:"Only new resources added"};return{strategy:"update",reason:"Resources will be updated"}}function zb(n){let i=n.added.length+n.modified.length+n.deleted.length+n.unchanged.length,s=n.added.length+n.modified.length+n.deleted.length,o=i>0?s/i*100:0;return{total:i,added:n.added.length,modified:n.modified.length,deleted:n.deleted.length,unchanged:n.unchanged.length,changePercentage:o}}var Ny={$schema:"http://json-schema.org/draft-07/schema#",title:"ts-cloud Configuration",description:"Configuration schema for ts-cloud infrastructure-as-code",type:"object",required:["project"],properties:{project:{type:"object",description:"Project configuration",required:["name","slug"],properties:{name:{type:"string",description:"Human-readable project name",minLength:1},slug:{type:"string",description:"URL-safe project identifier (lowercase, alphanumeric, hyphens only)",pattern:"^[a-z0-9-]+$",minLength:1,maxLength:63},region:{type:"string",description:"Default AWS region",enum:["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ap-southeast-1","ap-southeast-2","ap-northeast-1","ap-northeast-2","sa-east-1","ca-central-1"]}}},mode:{type:"string",description:"Deployment mode (server and serverless are mutually exclusive; auto-detected when omitted)",enum:["server","serverless"]},environments:{type:"object",description:"Environment-specific configurations",properties:{production:{$ref:"#/definitions/environment"},staging:{$ref:"#/definitions/environment"},development:{$ref:"#/definitions/environment"}}},infrastructure:{type:"object",description:"Infrastructure configuration",properties:{network:{$ref:"#/definitions/network"},storage:{type:"object",description:"S3 storage configuration",additionalProperties:{$ref:"#/definitions/storage"}},compute:{$ref:"#/definitions/compute"},database:{$ref:"#/definitions/database"},cache:{$ref:"#/definitions/cache"},cdn:{$ref:"#/definitions/cdn"},sftp:{$ref:"#/definitions/sftp"},functions:{type:"object",description:"Lambda functions configuration",additionalProperties:{type:"array",items:{$ref:"#/definitions/function"}}},monitoring:{$ref:"#/definitions/monitoring"},security:{$ref:"#/definitions/security"},queue:{type:"object",description:"SQS queue configuration",additionalProperties:{$ref:"#/definitions/queue"}}}}},definitions:{environment:{type:"object",properties:{domain:{type:"string",description:"Custom domain for this environment"},region:{type:"string",description:"AWS region override for this environment"},app:{type:"object",description:"Serverless application manifest (Laravel-Vapor-equivalent). Defining this opts the environment into the serverless app deploy pipeline (http/queue/cli Lambda functions, assets, build/deploy hooks).",properties:{runtime:{type:"string",description:"Lambda runtime override (usually derived from kind + runtimeVersion)"},runtimeVersion:{type:"string",description:"Node major (18/20/22 managed, 24+ custom layer) or Bun release for node/bun apps"},kind:{type:"string",enum:["node","bun","php"],description:"Application kind (drives packaging + runtime)"},entry:{type:"string",description:"Entry file exporting the request handler"},memory:{type:"number",description:"HTTP function memory in MB"},timeout:{type:"number",description:"HTTP request timeout in seconds"},gatewayVersion:{type:"number",enum:[1,2],description:"API Gateway version (2 = HTTP API, 1 = REST)"},warm:{type:"number",description:"Keep-warm / provisioned concurrency count"},lambdaInsights:{type:"object",description:"CloudWatch Lambda Insights extension configuration for zip deployments",required:["layerArn"],properties:{layerArn:{type:"string",description:"Region- and architecture-specific Lambda Insights extension layer ARN"}}},queues:{description:"Queue names (true = single default queue, false = disabled)"},scheduler:{type:"string",enum:["off","on","sub-minute"],description:"Task scheduler mode"},build:{type:"array",items:{type:"string"},description:"Commands run locally before packaging"},deploy:{type:"array",items:{type:"string"},description:"Commands run remotely after activation (e.g. migrations)"},octane:{type:"boolean",description:"Persistent application mode (Laravel Octane)"},packaging:{type:"string",enum:["zip","image"],description:"Deployment package format (zip or container image)"},phpVersion:{type:"string",description:"PHP version for the runtime layer (kind: php)"},architecture:{type:"string",enum:["x86_64","arm64"],description:"CPU architecture"}}}}},network:{type:"object",properties:{vpc:{type:"object",properties:{cidr:{type:"string",description:"VPC CIDR block",pattern:"^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$",default:"10.0.0.0/16"},availabilityZones:{type:"number",description:"Number of availability zones",minimum:1,maximum:3,default:2},natGateways:{type:"number",description:"Number of NAT gateways (0 for no NAT, saves cost)",minimum:0,maximum:3,default:1}}}}},storage:{type:"object",properties:{public:{type:"boolean",description:"Allow public access",default:!1},versioning:{type:"boolean",description:"Enable versioning",default:!1},encryption:{type:"boolean",description:"Enable server-side encryption",default:!0},website:{type:"boolean",description:"Enable static website hosting",default:!1},cors:{type:"object",description:"CORS configuration",properties:{allowedOrigins:{type:"array",items:{type:"string"}},allowedMethods:{type:"array",items:{type:"string",enum:["GET","PUT","POST","DELETE","HEAD"]}}}}}},compute:{type:"object",properties:{server:{type:"object",description:"EC2 server configuration",properties:{instanceType:{type:"string",description:"EC2 instance type",enum:["t3.micro","t3.small","t3.medium","t3.large","t3.xlarge","t3.2xlarge"]},autoScaling:{type:"object",properties:{min:{type:"number",minimum:1},max:{type:"number",minimum:1},desired:{type:"number",minimum:1}}}}},fargate:{type:"object",description:"ECS Fargate configuration",properties:{cpu:{type:"number",description:"CPU units (256, 512, 1024, 2048, 4096)",enum:[256,512,1024,2048,4096]},memory:{type:"number",description:"Memory in MB"},desiredCount:{type:"number",description:"Desired number of tasks",minimum:1}}}}},database:{type:"object",properties:{postgres:{type:"object",properties:{instanceClass:{type:"string",description:"RDS instance class",pattern:"^db\\.[a-z0-9]+\\.[a-z0-9]+$"},engine:{type:"string",const:"postgres"},version:{type:"string",description:"PostgreSQL version"},multiAZ:{type:"boolean",description:"Enable Multi-AZ deployment",default:!1},backupRetentionDays:{type:"number",description:"Backup retention period in days",minimum:0,maximum:35,default:7}}},mysql:{type:"object",properties:{instanceClass:{type:"string",pattern:"^db\\.[a-z0-9]+\\.[a-z0-9]+$"},engine:{type:"string",const:"mysql"},version:{type:"string"},multiAZ:{type:"boolean",default:!1},backupRetentionDays:{type:"number",minimum:0,maximum:35,default:7}}},dynamodb:{type:"object",properties:{tables:{type:"array",items:{type:"object",required:["name","partitionKey"],properties:{name:{type:"string"},partitionKey:{type:"string"},sortKey:{type:"string"},billingMode:{type:"string",enum:["PAY_PER_REQUEST","PROVISIONED"],default:"PAY_PER_REQUEST"}}}}}}}},cache:{type:"object",properties:{redis:{type:"object",properties:{nodeType:{type:"string",description:"ElastiCache node type",pattern:"^cache\\.[a-z0-9]+\\.[a-z0-9]+$"},numCacheNodes:{type:"number",minimum:1,default:1},engineVersion:{type:"string",description:"Redis engine version"}}},memcached:{type:"object",properties:{nodeType:{type:"string",pattern:"^cache\\.[a-z0-9]+\\.[a-z0-9]+$"},numCacheNodes:{type:"number",minimum:1,default:1}}}}},cdn:{type:"object",properties:{enabled:{type:"boolean",default:!0},originShield:{type:"boolean",description:"Enable CloudFront Origin Shield",default:!1},originShieldRegion:{type:"string",description:"AWS region used by CloudFront Origin Shield"},compress:{type:"boolean",description:"Enable automatic compression",default:!0},http3:{type:"boolean",description:"Enable HTTP/3 support",default:!0},customDomain:{type:"object",properties:{domain:{type:"string"},certificateArn:{type:"string"}}},cachePolicy:{type:"object",properties:{minTTL:{type:"number",minimum:0},defaultTTL:{type:"number",minimum:0},maxTTL:{type:"number",minimum:0}}}}},sftp:{type:"object",required:["bucket","users"],properties:{bucket:{type:"string",description:"S3 bucket backing the SFTP server"},endpointType:{type:"string",enum:["PUBLIC","VPC"],default:"PUBLIC"},endpointDetails:{type:"object",required:["vpcId","subnetIds"],properties:{vpcId:{type:"string"},subnetIds:{type:"array",items:{type:"string"},minItems:1},securityGroupIds:{type:"array",items:{type:"string"}},addressAllocationIds:{type:"array",items:{type:"string"}}}},securityPolicyName:{type:"string"},logging:{type:"boolean",default:!0},users:{type:"object",additionalProperties:{type:"object",required:["sshPublicKeys"],properties:{sshPublicKeys:{type:"array",items:{type:"string"},minItems:1},homeDirectory:{type:"string"},roleArn:{type:"string"}}}}}},function:{type:"object",required:["name","runtime"],properties:{name:{type:"string"},runtime:{type:"string",enum:["nodejs18.x","nodejs20.x","python3.10","python3.11","python3.12"]},handler:{type:"string",default:"index.handler"},timeout:{type:"number",minimum:1,maximum:900,default:30},memory:{type:"number",minimum:128,maximum:10240,default:1024}}},monitoring:{type:"object",properties:{alarms:{type:"array",items:{type:"object",required:["metric","threshold"],properties:{metric:{type:"string"},threshold:{type:"number"},evaluationPeriods:{type:"number",minimum:1,default:2}}}},dashboard:{type:"object",properties:{name:{type:"string"},widgets:{type:"array"}}}}},security:{type:"object",properties:{waf:{type:"boolean",description:"Enable AWS WAF",default:!1},certificates:{type:"array",items:{type:"object",required:["domain"],properties:{domain:{type:"string"},subdomains:{type:"array",items:{type:"string"}}}}}}},queue:{type:"object",properties:{fifo:{type:"boolean",default:!1},deadLetterQueue:{type:"boolean",default:!0},visibilityTimeout:{type:"number",minimum:0,maximum:43200,default:30},messageRetentionPeriod:{type:"number",minimum:60,maximum:1209600,default:345600}}}}};function Kb(n){let i=[];if(!n.project)i.push("Missing required field: project");else{if(!n.project.name)i.push("Missing required field: project.name");if(!n.project.slug)i.push("Missing required field: project.slug")}if(n.project?.slug&&!/^[a-z0-9-]+$/.test(n.project.slug))i.push("Invalid project.slug: must contain only lowercase letters, numbers, and hyphens");let s=["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ap-southeast-1","ap-southeast-2","ap-northeast-1","ap-northeast-2","sa-east-1","ca-central-1"];if(n.project?.region&&!s.includes(n.project.region))i.push(`Invalid region: ${n.project.region}. Must be one of: ${s.join(", ")}`);if(n.mode&&!["server","serverless"].includes(n.mode))i.push("Invalid mode: must be one of server or serverless");return{valid:i.length===0,errors:i}}var Qm={enabled:process.env.TS_CLOUD_LOCAL==="true"||!0,localstackEndpoint:process.env.LOCALSTACK_ENDPOINT||"http://localhost:4566",postgresUrl:process.env.POSTGRES_URL||"postgresql://tscloud:tscloud@localhost:5432/tscloud",redisUrl:process.env.REDIS_URL||"redis://localhost:6379",dynamodbEndpoint:process.env.DYNAMODB_ENDPOINT||"http://localhost:8000",s3Endpoint:process.env.S3_ENDPOINT||"http://localhost:9000",emailEndpoint:process.env.EMAIL_ENDPOINT||"smtp://localhost:1025",awsRegion:process.env.AWS_REGION||"us-east-1",awsAccessKeyId:process.env.AWS_ACCESS_KEY_ID||"test",awsSecretAccessKey:process.env.AWS_SECRET_ACCESS_KEY||"test"};function Il(){return Qm}function Wb(){return Qm.enabled}function Jb(n){let i=Il();if(!i.enabled)return"";switch(n.toLowerCase()){case"dynamodb":return i.dynamodbEndpoint;case"s3":return i.s3Endpoint;case"localstack":case"cloudformation":case"lambda":case"apigateway":case"sns":case"sqs":case"cloudwatch":case"iam":case"sts":return i.localstackEndpoint;default:return i.localstackEndpoint}}function Xb(){let n=Il();return{accessKeyId:n.awsAccessKeyId,secretAccessKey:n.awsSecretAccessKey,region:n.awsRegion}}function Yb(){let n=Il();if(!n.enabled)return{};return{AWS_ACCESS_KEY_ID:n.awsAccessKeyId,AWS_SECRET_ACCESS_KEY:n.awsSecretAccessKey,AWS_REGION:n.awsRegion,AWS_ENDPOINT_URL:n.localstackEndpoint,LOCALSTACK_ENDPOINT:n.localstackEndpoint,TS_CLOUD_LOCAL:"true"}}class Hm{stacks=new Map;stackEvents=new Map;async createStack(n){let i=`arn:aws:cloudformation:${n.region||"us-east-1"}:123456789012:stack/${n.StackName}/${Date.now()}`;return this.stacks.set(n.StackName,{StackId:i,StackName:n.StackName,StackStatus:"CREATE_IN_PROGRESS",CreationTime:new Date().toISOString(),TemplateBody:n.TemplateBody,Parameters:n.Parameters||[]}),this.addEvent(n.StackName,{EventId:Date.now().toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"CREATE_IN_PROGRESS"}),setTimeout(()=>{let s=this.stacks.get(n.StackName);if(s)s.StackStatus="CREATE_COMPLETE",this.addEvent(n.StackName,{EventId:(Date.now()+1).toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"CREATE_COMPLETE"})},100),{StackId:i}}async updateStack(n){let i=this.stacks.get(n.StackName);if(!i)throw Error(`Stack ${n.StackName} does not exist`);return i.StackStatus="UPDATE_IN_PROGRESS",i.TemplateBody=n.TemplateBody||i.TemplateBody,this.addEvent(n.StackName,{EventId:Date.now().toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"UPDATE_IN_PROGRESS"}),setTimeout(()=>{i.StackStatus="UPDATE_COMPLETE",this.addEvent(n.StackName,{EventId:(Date.now()+1).toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"UPDATE_COMPLETE"})},100),{StackId:i.StackId}}async deleteStack(n){let i=this.stacks.get(n.StackName);if(!i)throw Error(`Stack ${n.StackName} does not exist`);i.StackStatus="DELETE_IN_PROGRESS",this.addEvent(n.StackName,{EventId:Date.now().toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"DELETE_IN_PROGRESS"}),setTimeout(()=>{this.stacks.delete(n.StackName),this.addEvent(n.StackName,{EventId:(Date.now()+1).toString(),StackName:n.StackName,LogicalResourceId:n.StackName,ResourceType:"AWS::CloudFormation::Stack",Timestamp:new Date().toISOString(),ResourceStatus:"DELETE_COMPLETE"})},100)}async describeStacks(n){if(n.StackName){let i=this.stacks.get(n.StackName);if(!i)throw Error(`Stack ${n.StackName} does not exist`);return{Stacks:[i]}}return{Stacks:Array.from(this.stacks.values())}}async describeStackEvents(n){return{StackEvents:this.stackEvents.get(n.StackName)||[]}}addEvent(n,i){if(!this.stackEvents.has(n))this.stackEvents.set(n,[]);this.stackEvents.get(n).unshift(i)}reset(){this.stacks.clear(),this.stackEvents.clear()}}class Gm{buckets=new Map;async createBucket(n){return this.buckets.set(n.Bucket,new Map),{Location:`/${n.Bucket}`}}async deleteBucket(n){this.buckets.delete(n.Bucket)}async putObject(n){let i=this.buckets.get(n.Bucket);if(!i)i=new Map,this.buckets.set(n.Bucket,i);return i.set(n.Key,Buffer.from(n.Body||"")),{ETag:`"${Date.now()}"`}}async getObject(n){let i=this.buckets.get(n.Bucket);if(!i)throw Error(`Bucket ${n.Bucket} does not exist`);let s=i.get(n.Key);if(!s)throw Error(`Object ${n.Key} does not exist`);return{Body:s,ContentLength:s.length}}async deleteObject(n){let i=this.buckets.get(n.Bucket);if(i)i.delete(n.Key)}async listObjects(n){let i=this.buckets.get(n.Bucket);if(!i)throw Error(`Bucket ${n.Bucket} does not exist`);return{Contents:Array.from(i.keys()).map((o)=>({Key:o,Size:i.get(o).length,LastModified:new Date().toISOString()}))}}reset(){this.buckets.clear()}}class Vm{tables=new Map;data=new Map;async createTable(n){return this.tables.set(n.TableName,{TableName:n.TableName,KeySchema:n.KeySchema,AttributeDefinitions:n.AttributeDefinitions,TableStatus:"ACTIVE",CreationDateTime:new Date().toISOString()}),this.data.set(n.TableName,new Map),{TableDescription:this.tables.get(n.TableName)}}async deleteTable(n){this.tables.delete(n.TableName),this.data.delete(n.TableName)}async putItem(n){let i=this.data.get(n.TableName);if(!i)i=new Map,this.data.set(n.TableName,i);let s=JSON.stringify(n.Item);i.set(s,n.Item)}async getItem(n){let i=this.data.get(n.TableName);if(!i)return{};let s=JSON.stringify(n.Key),o=i.get(s);return o?{Item:o}:{}}async deleteItem(n){let i=this.data.get(n.TableName);if(i){let s=JSON.stringify(n.Key);i.delete(s)}}async scan(n){let i=this.data.get(n.TableName);if(!i)return{Items:[]};return{Items:Array.from(i.values())}}reset(){this.tables.clear(),this.data.clear()}}function Zb(n){return{cloudformation:new Hm,s3:new Gm,dynamodb:new Vm}}class bl{environments=new Map;async createPreviewEnvironment(n){let{branch:i,pr:s,commitSha:o,ttl:c=24,baseConfig:u,region:d="us-east-1"}=n,p=this.generatePreviewId(i,s,o),y=this.generatePreviewName(i,s),h=`preview-${y}`,b=new Date,v=new Date(b.getTime()+c*60*60*1000),A={id:p,name:y,branch:i,pr:s,commitSha:o,createdAt:b,expiresAt:v,status:"creating",stackName:h,region:d,resources:[]};this.environments.set(p,A);try{let T=this.createPreviewConfig(u,y);return A.status="active",A.url=`https://${y}.preview.example.com`,A}catch(T){throw A.status="failed",T}}async destroyPreviewEnvironment(n){let i=this.environments.get(n);if(!i)throw Error(`Preview environment ${n} not found`);i.status="destroying";try{i.status="destroyed",this.environments.delete(n)}catch(s){throw Error(`Failed to destroy preview environment: ${s}`)}}getPreviewEnvironment(n){return this.environments.get(n)}getPreviewEnvironmentByBranch(n){return Array.from(this.environments.values()).find((i)=>i.branch===n)}getPreviewEnvironmentByPR(n){return Array.from(this.environments.values()).find((i)=>i.pr===n)}listPreviewEnvironments(){return Array.from(this.environments.values())}listActivePreviewEnvironments(){return this.listPreviewEnvironments().filter((n)=>n.status==="active")}async cleanupExpiredEnvironments(n={}){let{maxAge:i,keepCount:s,dryRun:o=!1}=n,c=[],u=[],d=new Date,p=this.listPreviewEnvironments().sort((y,h)=>h.createdAt.getTime()-y.createdAt.getTime());for(let y=0;y<p.length;y++){let h=p[y];if(h.status!=="active")continue;let b=!1;if(h.expiresAt<d)b=!0;if(i){if((d.getTime()-h.createdAt.getTime())/3600000>i)b=!0}if(s&&y>=s)b=!0;if(b)if(o)c.push(h.id);else try{await this.destroyPreviewEnvironment(h.id),c.push(h.id)}catch(v){u.push(h.id)}}return{destroyed:c,failed:u}}async updatePreviewEnvironment(n,i){let s=this.environments.get(n);if(!s)throw Error(`Preview environment ${n} not found`);s.commitSha=i,s.status="creating";try{return s.status="active",s}catch(o){throw s.status="failed",o}}async getPreviewEnvironmentsCost(){let n={},i=0;for(let s of this.environments.values())n[s.id]=0,i+=0;return{total:i,byEnvironment:n}}generatePreviewId(n,i,s){let o=n.replace(/[^a-z0-9-]/gi,"-").toLowerCase(),c=s?.substring(0,7)||Date.now().toString();return i?`pr-${i}-${c}`:`${o}-${c}`}generatePreviewName(n,i){let s=n.replace(/[^a-z0-9-]/gi,"-").toLowerCase();return i?`pr-${i}`:s}createPreviewConfig(n,i){return{...n,project:{...n.project,name:`${n.project.name} Preview (${i})`,slug:`${n.project.slug}-preview-${i}`}}}}var By=new bl;function xy(n={}){let{workflowName:i="Preview Environment",trigger:s="pull_request",branches:o=["main","develop"],awsRegion:c="us-east-1",awsRole:u,configFile:d="cloud.config.ts",ttl:p=24}=n;return`name: ${i}
2478
2478
 
2479
2479
  on:
2480
2480
  ${s}:
@@ -2608,7 +2608,7 @@ jobs:
2608
2608
  run: |
2609
2609
  # Clean up environments older than TTL
2610
2610
  bun run cloud env:cleanup --max-age=\${{ env.TTL_HOURS }}
2611
- `}function xy(n={}){let{schedule:i="0 0 * * *",maxAge:s=48,keepCount:o=10}=n;return`name: Cleanup Stale Preview Environments
2611
+ `}function Oy(n={}){let{schedule:i="0 0 * * *",maxAge:s=48,keepCount:o=10}=n;return`name: Cleanup Stale Preview Environments
2612
2612
 
2613
2613
  on:
2614
2614
  schedule:
@@ -2653,7 +2653,7 @@ jobs:
2653
2653
  - name: Report cleanup results
2654
2654
  run: |
2655
2655
  bun run cloud env:list --status=destroyed
2656
- `}function Oy(n={}){let{schedule:i="0 8 * * 1",webhookUrl:s}=n;return`name: Preview Environment Cost Report
2656
+ `}function _y(n={}){let{schedule:i="0 8 * * 1",webhookUrl:s}=n;return`name: Preview Environment Cost Report
2657
2657
 
2658
2658
  on:
2659
2659
  schedule:
@@ -2702,15 +2702,15 @@ jobs:
2702
2702
  curl -X POST -H 'Content-type: application/json' \\
2703
2703
  --data '{"text":"Preview Environment Cost Report\\n\${{ steps.cost.outputs.cost_json }}"}' \\
2704
2704
  $SLACK_WEBHOOK_URL`:'run: |\n echo "${{ steps.cost.outputs.cost_json }}"'}
2705
- `}class Cl{channels=[];addChannel(n){this.channels.push(n)}removeChannel(n){this.channels=this.channels.filter((i)=>i.type!==n)}async notify(n){let i=this.channels.map((s)=>this.sendToChannel(s,n));await Promise.allSettled(i)}async sendToChannel(n,i){switch(n.type){case"slack":await this.sendToSlack(n.config,i);break;case"discord":await this.sendToDiscord(n.config,i);break;case"email":await this.sendToEmail(n.config,i);break;case"webhook":await this.sendToWebhook(n.config,i);break}}async sendToSlack(n,i){let s=this.formatSlackMessage(i,n),o=await fetch(n.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok)throw Error(`Failed to send Slack notification: ${o.statusText}`)}formatSlackMessage(n,i){let{environment:s,type:o}=n,c={created:":rocket:",updated:":arrows_counterclockwise:",destroyed:":wastebasket:",failed:":x:",expired:":hourglass_flowing_sand:"}[o],u={created:"#36a64f",updated:"#2196F3",destroyed:"#808080",failed:"#f44336",expired:"#ff9800"}[o],d={created:"Preview Environment Created",updated:"Preview Environment Updated",destroyed:"Preview Environment Destroyed",failed:"Preview Environment Failed",expired:"Preview Environment Expired"}[o];return{username:i.username||"ts-cloud",icon_emoji:i.iconEmoji||":cloud:",channel:i.channel,attachments:[{color:u,title:`${c} ${d}`,fields:[{title:"Environment",value:s.name,short:!0},{title:"Branch",value:s.branch,short:!0},...s.pr?[{title:"PR",value:`#${s.pr}`,short:!0}]:[],{title:"Commit",value:s.commitSha.substring(0,7),short:!0},...s.url?[{title:"URL",value:s.url,short:!1}]:[],...o==="created"?[{title:"Expires",value:s.expiresAt.toLocaleString(),short:!0}]:[]],footer:"ts-cloud Preview Environments",ts:Math.floor(n.timestamp.getTime()/1000)}]}}async sendToDiscord(n,i){let s=this.formatDiscordMessage(i,n),o=await fetch(n.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok)throw Error(`Failed to send Discord notification: ${o.statusText}`)}formatDiscordMessage(n,i){let{environment:s,type:o}=n,c={created:":rocket:",updated:":arrows_counterclockwise:",destroyed:":wastebasket:",failed:":x:",expired:":hourglass:"}[o],u={created:3581519,updated:2201331,destroyed:8421504,failed:16007990,expired:16750592}[o],d={created:"Preview Environment Created",updated:"Preview Environment Updated",destroyed:"Preview Environment Destroyed",failed:"Preview Environment Failed",expired:"Preview Environment Expired"}[o];return{username:i.username||"ts-cloud",avatar_url:i.avatarUrl,embeds:[{title:`${c} ${d}`,color:u,fields:[{name:"Environment",value:s.name,inline:!0},{name:"Branch",value:s.branch,inline:!0},...s.pr?[{name:"PR",value:`#${s.pr}`,inline:!0}]:[],{name:"Commit",value:`\`${s.commitSha.substring(0,7)}\``,inline:!0},...s.url?[{name:"URL",value:s.url,inline:!1}]:[]],timestamp:n.timestamp.toISOString(),footer:{text:"ts-cloud Preview Environments"}}]}}async sendToEmail(n,i){console.log(`Email notification would be sent to ${n.to.join(", ")}`)}async sendToWebhook(n,i){let s=await fetch(n.url,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:JSON.stringify({event:i.type,environment:i.environment,timestamp:i.timestamp.toISOString(),metadata:i.metadata})});if(!s.ok)throw Error(`Failed to send webhook notification: ${s.statusText}`)}}var _y=new Cl;function Zb(n){let{columns:i,data:s,border:o=!0,header:c=!0,compact:u=!1,maxWidth:d}=n;if(s.length===0)return"No data to display";let p=i.map((h)=>{let b=h.label.length,v=Math.max(...s.map((T)=>(h.formatter?h.formatter(T[h.key]):String(T[h.key]||"")).length)),A=h.width||Math.max(b,v);if(d&&A>d)A=d;return A}),y=[];if(o)y.push(Ft(p,"top",u));if(c){if(y.push(Un(i.map((h)=>h.label),p,i.map((h)=>h.align||"left"),o)),o)y.push(Ft(p,"middle",u))}for(let h of s){let b=i.map((v)=>{let A=v.formatter?v.formatter(h[v.key]):String(h[v.key]||"");return Ei(A,p[i.indexOf(v)])});y.push(Un(b,p,i.map((v)=>v.align||"left"),o))}if(o)y.push(Ft(p,"bottom",u));return y.join(`
2706
- `)}function Un(n,i,s,o){let c=n.map((u,d)=>{let p=i[d],y=s[d];return Pi(u,p,y)});if(o)return`│ ${c.join(" │ ")} │`;return c.join(" ")}function Ft(n,i,s){let o=i==="top"?"┌":i==="middle"?"├":"└",c=i==="top"?"┐":i==="middle"?"┤":"┘",u=i==="top"?"┬":i==="middle"?"┼":"┴",d="─";if(s)return o+n.map((p)=>"─".repeat(p+2)).join(u)+c;return o+n.map((p)=>"─".repeat(p+2)).join(u)+c}function Pi(n,i,s){let o=Hn(n).length;if(o>=i)return n;let c=i-o;switch(s){case"right":return" ".repeat(c)+n;case"center":{let u=Math.floor(c/2),d=c-u;return" ".repeat(u)+n+" ".repeat(d)}default:return n+" ".repeat(c)}}function Ei(n,i){if(Hn(n).length<=i)return n;return n.substring(0,i-1)+"…"}function Hn(n){return n.replace(/\x1B\[[0-9;]*m/g,"")}function eC(n,i={}){let{indent:s=" ",showMetadata:o=!1}=i,c=[];function u(d,p,y){let b=p+(y?"└─ ":"├─ ")+d.label;if(c.push(b),o&&d.metadata){let v=p+(y?" ":"│ ");for(let[A,T]of Object.entries(d.metadata))c.push(`${v}${A}: ${T}`)}if(d.children&&d.children.length>0){let v=p+(y?" ":"│ ");d.children.forEach((A,T)=>{u(A,v,T===d.children.length-1)})}}return n.forEach((d,p)=>{u(d,"",p===n.length-1)}),c.join(`
2707
- `)}function tC(n){let{total:i,current:s,width:o=40,format:c=":bar :percent :current/:total",complete:u="█",incomplete:d="░"}=n,p=Math.min(100,Math.max(0,s/i*100)),y=Math.floor(o*s/i),h=o-y,b=u.repeat(y)+d.repeat(h);return c.replace(":bar",b).replace(":percent",`${p.toFixed(0)}%`).replace(":current",String(s)).replace(":total",String(i))}function rC(n,i=2){if(n===0)return"0 Bytes";let s=1024,o=i<0?0:i,c=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],u=Math.floor(Math.log(n)/Math.log(s));return`${Number.parseFloat((n/Math.pow(s,u)).toFixed(o))} ${c[u]}`}function nC(n){if(n<1000)return`${n}ms`;let i=Math.floor(n/1000);if(i<60)return`${i}s`;let s=Math.floor(i/60),o=i%60;if(s<60)return o>0?`${s}m ${o}s`:`${s}m`;let c=Math.floor(s/60),u=s%60;if(c<24)return u>0?`${c}h ${u}m`:`${c}h`;let d=Math.floor(c/24),p=c%24;return p>0?`${d}d ${p}h`:`${d}d`}function iC(n,i="•"){return n.map((s)=>`${i} ${s}`).join(`
2708
- `)}function sC(n,i={}){let{indent:s="",separator:o=": "}=i,c=Math.max(...Object.keys(n).map((u)=>u.length));return Object.entries(n).map(([u,d])=>{let p=u.padEnd(c);return`${s}${p}${o}${d}`}).join(`
2709
- `)}class Ly{total;current=0;width;format;message;showETA;showPercentage;showCounter;startTime=Date.now();lastUpdate=0;constructor(n){this.total=n.total,this.current=n.current||0,this.width=n.width||40,this.format=n.format||":message :bar :percent :eta",this.message=n.message||"Progress",this.showETA=n.showETA!==!1,this.showPercentage=n.showPercentage!==!1,this.showCounter=n.showCounter!==!1}tick(n=1){this.current=Math.min(this.total,this.current+n),this.lastUpdate=Date.now()}update(n){this.current=Math.min(this.total,Math.max(0,n)),this.lastUpdate=Date.now()}setMessage(n){this.message=n}getPercentage(){return Math.min(100,this.current/this.total*100)}getETA(){if(this.current===0)return 0;let n=Date.now()-this.startTime,i=this.current/n,s=this.total-this.current;return Math.round(s/i)}getETAFormatted(){if(this.current===0)return"calculating...";if(this.current===this.total)return"complete";let n=this.getETA();if(n<1000)return"< 1s";if(n<60000)return`${Math.round(n/1000)}s`;let i=Math.floor(n/60000);if(i<60)return`${i}m`;let s=Math.floor(i/60),o=i%60;if(s<24)return o>0?`${s}h ${o}m`:`${s}h`;let c=Math.floor(s/24),u=s%24;return u>0?`${c}d ${u}h`:`${c}d`}render(){let n=this.getPercentage(),i=Math.floor(this.width*this.current/this.total),s=this.width-i,o="█".repeat(i)+"░".repeat(s),c=`${n.toFixed(1)}%`,u=`${this.current}/${this.total}`,d=this.showETA?`ETA: ${this.getETAFormatted()}`:"",p=this.format.replace(":message",this.message).replace(":bar",o).replace(":percent",this.showPercentage?c:"").replace(":counter",this.showCounter?u:"").replace(":eta",d).replace(":current",String(this.current)).replace(":total",String(this.total));return p=p.replace(/\s+/g," ").trim(),p}isComplete(){return this.current>=this.total}}class $y{steps;currentStepIndex=0;constructor(n){this.steps=n.map((i)=>({name:i,status:"pending"}))}startStep(n,i){if(n>=0&&n<this.steps.length)this.steps[n].status="active",this.steps[n].message=i,this.currentStepIndex=n}completeStep(n){if(this.currentStepIndex>=0&&this.currentStepIndex<this.steps.length)this.steps[this.currentStepIndex].status="completed",this.steps[this.currentStepIndex].message=n,this.currentStepIndex++}failStep(n){if(this.currentStepIndex>=0&&this.currentStepIndex<this.steps.length)this.steps[this.currentStepIndex].status="failed",this.steps[this.currentStepIndex].error=n}skipStep(n){if(this.currentStepIndex>=0&&this.currentStepIndex<this.steps.length)this.steps[this.currentStepIndex].status="skipped",this.steps[this.currentStepIndex].message=n,this.currentStepIndex++}getStep(n){return this.steps[n]}getSteps(){return this.steps}render(){let n=[];for(let i of this.steps){let o=`${this.getStatusIcon(i.status)} ${i.name}`;if(i.message)o+=` - ${i.message}`;if(i.error)o+=`
2705
+ `}class Cl{channels=[];addChannel(n){this.channels.push(n)}removeChannel(n){this.channels=this.channels.filter((i)=>i.type!==n)}async notify(n){let i=this.channels.map((s)=>this.sendToChannel(s,n));await Promise.allSettled(i)}async sendToChannel(n,i){switch(n.type){case"slack":await this.sendToSlack(n.config,i);break;case"discord":await this.sendToDiscord(n.config,i);break;case"email":await this.sendToEmail(n.config,i);break;case"webhook":await this.sendToWebhook(n.config,i);break}}async sendToSlack(n,i){let s=this.formatSlackMessage(i,n),o=await fetch(n.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok)throw Error(`Failed to send Slack notification: ${o.statusText}`)}formatSlackMessage(n,i){let{environment:s,type:o}=n,c={created:":rocket:",updated:":arrows_counterclockwise:",destroyed:":wastebasket:",failed:":x:",expired:":hourglass_flowing_sand:"}[o],u={created:"#36a64f",updated:"#2196F3",destroyed:"#808080",failed:"#f44336",expired:"#ff9800"}[o],d={created:"Preview Environment Created",updated:"Preview Environment Updated",destroyed:"Preview Environment Destroyed",failed:"Preview Environment Failed",expired:"Preview Environment Expired"}[o];return{username:i.username||"ts-cloud",icon_emoji:i.iconEmoji||":cloud:",channel:i.channel,attachments:[{color:u,title:`${c} ${d}`,fields:[{title:"Environment",value:s.name,short:!0},{title:"Branch",value:s.branch,short:!0},...s.pr?[{title:"PR",value:`#${s.pr}`,short:!0}]:[],{title:"Commit",value:s.commitSha.substring(0,7),short:!0},...s.url?[{title:"URL",value:s.url,short:!1}]:[],...o==="created"?[{title:"Expires",value:s.expiresAt.toLocaleString(),short:!0}]:[]],footer:"ts-cloud Preview Environments",ts:Math.floor(n.timestamp.getTime()/1000)}]}}async sendToDiscord(n,i){let s=this.formatDiscordMessage(i,n),o=await fetch(n.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok)throw Error(`Failed to send Discord notification: ${o.statusText}`)}formatDiscordMessage(n,i){let{environment:s,type:o}=n,c={created:":rocket:",updated:":arrows_counterclockwise:",destroyed:":wastebasket:",failed:":x:",expired:":hourglass:"}[o],u={created:3581519,updated:2201331,destroyed:8421504,failed:16007990,expired:16750592}[o],d={created:"Preview Environment Created",updated:"Preview Environment Updated",destroyed:"Preview Environment Destroyed",failed:"Preview Environment Failed",expired:"Preview Environment Expired"}[o];return{username:i.username||"ts-cloud",avatar_url:i.avatarUrl,embeds:[{title:`${c} ${d}`,color:u,fields:[{name:"Environment",value:s.name,inline:!0},{name:"Branch",value:s.branch,inline:!0},...s.pr?[{name:"PR",value:`#${s.pr}`,inline:!0}]:[],{name:"Commit",value:`\`${s.commitSha.substring(0,7)}\``,inline:!0},...s.url?[{name:"URL",value:s.url,inline:!1}]:[]],timestamp:n.timestamp.toISOString(),footer:{text:"ts-cloud Preview Environments"}}]}}async sendToEmail(n,i){console.log(`Email notification would be sent to ${n.to.join(", ")}`)}async sendToWebhook(n,i){let s=await fetch(n.url,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:JSON.stringify({event:i.type,environment:i.environment,timestamp:i.timestamp.toISOString(),metadata:i.metadata})});if(!s.ok)throw Error(`Failed to send webhook notification: ${s.statusText}`)}}var Ly=new Cl;function eC(n){let{columns:i,data:s,border:o=!0,header:c=!0,compact:u=!1,maxWidth:d}=n;if(s.length===0)return"No data to display";let p=i.map((h)=>{let b=h.label.length,v=Math.max(...s.map((T)=>(h.formatter?h.formatter(T[h.key]):String(T[h.key]||"")).length)),A=h.width||Math.max(b,v);if(d&&A>d)A=d;return A}),y=[];if(o)y.push(Ft(p,"top",u));if(c){if(y.push(Un(i.map((h)=>h.label),p,i.map((h)=>h.align||"left"),o)),o)y.push(Ft(p,"middle",u))}for(let h of s){let b=i.map((v)=>{let A=v.formatter?v.formatter(h[v.key]):String(h[v.key]||"");return Ei(A,p[i.indexOf(v)])});y.push(Un(b,p,i.map((v)=>v.align||"left"),o))}if(o)y.push(Ft(p,"bottom",u));return y.join(`
2706
+ `)}function Un(n,i,s,o){let c=n.map((u,d)=>{let p=i[d],y=s[d];return Pi(u,p,y)});if(o)return`│ ${c.join(" │ ")} │`;return c.join(" ")}function Ft(n,i,s){let o=i==="top"?"┌":i==="middle"?"├":"└",c=i==="top"?"┐":i==="middle"?"┤":"┘",u=i==="top"?"┬":i==="middle"?"┼":"┴",d="─";if(s)return o+n.map((p)=>"─".repeat(p+2)).join(u)+c;return o+n.map((p)=>"─".repeat(p+2)).join(u)+c}function Pi(n,i,s){let o=Hn(n).length;if(o>=i)return n;let c=i-o;switch(s){case"right":return" ".repeat(c)+n;case"center":{let u=Math.floor(c/2),d=c-u;return" ".repeat(u)+n+" ".repeat(d)}default:return n+" ".repeat(c)}}function Ei(n,i){if(Hn(n).length<=i)return n;return n.substring(0,i-1)+"…"}function Hn(n){return n.replace(/\x1B\[[0-9;]*m/g,"")}function tC(n,i={}){let{indent:s=" ",showMetadata:o=!1}=i,c=[];function u(d,p,y){let b=p+(y?"└─ ":"├─ ")+d.label;if(c.push(b),o&&d.metadata){let v=p+(y?" ":"│ ");for(let[A,T]of Object.entries(d.metadata))c.push(`${v}${A}: ${T}`)}if(d.children&&d.children.length>0){let v=p+(y?" ":"│ ");d.children.forEach((A,T)=>{u(A,v,T===d.children.length-1)})}}return n.forEach((d,p)=>{u(d,"",p===n.length-1)}),c.join(`
2707
+ `)}function rC(n){let{total:i,current:s,width:o=40,format:c=":bar :percent :current/:total",complete:u="█",incomplete:d="░"}=n,p=Math.min(100,Math.max(0,s/i*100)),y=Math.floor(o*s/i),h=o-y,b=u.repeat(y)+d.repeat(h);return c.replace(":bar",b).replace(":percent",`${p.toFixed(0)}%`).replace(":current",String(s)).replace(":total",String(i))}function nC(n,i=2){if(n===0)return"0 Bytes";let s=1024,o=i<0?0:i,c=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],u=Math.floor(Math.log(n)/Math.log(s));return`${Number.parseFloat((n/Math.pow(s,u)).toFixed(o))} ${c[u]}`}function iC(n){if(n<1000)return`${n}ms`;let i=Math.floor(n/1000);if(i<60)return`${i}s`;let s=Math.floor(i/60),o=i%60;if(s<60)return o>0?`${s}m ${o}s`:`${s}m`;let c=Math.floor(s/60),u=s%60;if(c<24)return u>0?`${c}h ${u}m`:`${c}h`;let d=Math.floor(c/24),p=c%24;return p>0?`${d}d ${p}h`:`${d}d`}function sC(n,i="•"){return n.map((s)=>`${i} ${s}`).join(`
2708
+ `)}function oC(n,i={}){let{indent:s="",separator:o=": "}=i,c=Math.max(...Object.keys(n).map((u)=>u.length));return Object.entries(n).map(([u,d])=>{let p=u.padEnd(c);return`${s}${p}${o}${d}`}).join(`
2709
+ `)}class $y{total;current=0;width;format;message;showETA;showPercentage;showCounter;startTime=Date.now();lastUpdate=0;constructor(n){this.total=n.total,this.current=n.current||0,this.width=n.width||40,this.format=n.format||":message :bar :percent :eta",this.message=n.message||"Progress",this.showETA=n.showETA!==!1,this.showPercentage=n.showPercentage!==!1,this.showCounter=n.showCounter!==!1}tick(n=1){this.current=Math.min(this.total,this.current+n),this.lastUpdate=Date.now()}update(n){this.current=Math.min(this.total,Math.max(0,n)),this.lastUpdate=Date.now()}setMessage(n){this.message=n}getPercentage(){return Math.min(100,this.current/this.total*100)}getETA(){if(this.current===0)return 0;let n=Date.now()-this.startTime,i=this.current/n,s=this.total-this.current;return Math.round(s/i)}getETAFormatted(){if(this.current===0)return"calculating...";if(this.current===this.total)return"complete";let n=this.getETA();if(n<1000)return"< 1s";if(n<60000)return`${Math.round(n/1000)}s`;let i=Math.floor(n/60000);if(i<60)return`${i}m`;let s=Math.floor(i/60),o=i%60;if(s<24)return o>0?`${s}h ${o}m`:`${s}h`;let c=Math.floor(s/24),u=s%24;return u>0?`${c}d ${u}h`:`${c}d`}render(){let n=this.getPercentage(),i=Math.floor(this.width*this.current/this.total),s=this.width-i,o="█".repeat(i)+"░".repeat(s),c=`${n.toFixed(1)}%`,u=`${this.current}/${this.total}`,d=this.showETA?`ETA: ${this.getETAFormatted()}`:"",p=this.format.replace(":message",this.message).replace(":bar",o).replace(":percent",this.showPercentage?c:"").replace(":counter",this.showCounter?u:"").replace(":eta",d).replace(":current",String(this.current)).replace(":total",String(this.total));return p=p.replace(/\s+/g," ").trim(),p}isComplete(){return this.current>=this.total}}class My{steps;currentStepIndex=0;constructor(n){this.steps=n.map((i)=>({name:i,status:"pending"}))}startStep(n,i){if(n>=0&&n<this.steps.length)this.steps[n].status="active",this.steps[n].message=i,this.currentStepIndex=n}completeStep(n){if(this.currentStepIndex>=0&&this.currentStepIndex<this.steps.length)this.steps[this.currentStepIndex].status="completed",this.steps[this.currentStepIndex].message=n,this.currentStepIndex++}failStep(n){if(this.currentStepIndex>=0&&this.currentStepIndex<this.steps.length)this.steps[this.currentStepIndex].status="failed",this.steps[this.currentStepIndex].error=n}skipStep(n){if(this.currentStepIndex>=0&&this.currentStepIndex<this.steps.length)this.steps[this.currentStepIndex].status="skipped",this.steps[this.currentStepIndex].message=n,this.currentStepIndex++}getStep(n){return this.steps[n]}getSteps(){return this.steps}render(){let n=[];for(let i of this.steps){let o=`${this.getStatusIcon(i.status)} ${i.name}`;if(i.message)o+=` - ${i.message}`;if(i.error)o+=`
2710
2710
  Error: ${i.error}`;n.push(o)}return n.join(`
2711
- `)}getStatusIcon(n){switch(n){case"pending":return"○";case"active":return"◐";case"completed":return"✓";case"failed":return"✗";case"skipped":return"⊘";default:return"○"}}isComplete(){return this.steps.every((n)=>n.status==="completed"||n.status==="skipped")}hasFailed(){return this.steps.some((n)=>n.status==="failed")}}class My{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];currentFrame=0;message;interval=null;constructor(n="Loading..."){this.message=n}start(){if(this.interval)return;this.interval=setInterval(()=>{this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}stop(){if(this.interval)clearInterval(this.interval),this.interval=null}setMessage(n){this.message=n}render(){return`${this.frames[this.currentFrame]} ${this.message}`}succeed(n){return this.stop(),`✓ ${n||this.message}`}fail(n){return this.stop(),`✗ ${n||this.message}`}warn(n){return this.stop(),`⚠ ${n||this.message}`}info(n){return this.stop(),`ℹ ${n||this.message}`}}class Fy{tasks=[];add(n){return this.tasks.push({title:n,status:"pending"}),this.tasks.length-1}start(n){if(n>=0&&n<this.tasks.length)this.tasks[n].status="running"}complete(n,i){if(n>=0&&n<this.tasks.length)this.tasks[n].status="completed",this.tasks[n].output=i}fail(n,i){if(n>=0&&n<this.tasks.length)this.tasks[n].status="failed",this.tasks[n].output=i}render(){let n=[];for(let i of this.tasks){let o=`${this.getStatusIcon(i.status)} ${i.title}`;if(i.output)o+=`
2711
+ `)}getStatusIcon(n){switch(n){case"pending":return"○";case"active":return"◐";case"completed":return"✓";case"failed":return"✗";case"skipped":return"⊘";default:return"○"}}isComplete(){return this.steps.every((n)=>n.status==="completed"||n.status==="skipped")}hasFailed(){return this.steps.some((n)=>n.status==="failed")}}class Fy{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];currentFrame=0;message;interval=null;constructor(n="Loading..."){this.message=n}start(){if(this.interval)return;this.interval=setInterval(()=>{this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}stop(){if(this.interval)clearInterval(this.interval),this.interval=null}setMessage(n){this.message=n}render(){return`${this.frames[this.currentFrame]} ${this.message}`}succeed(n){return this.stop(),`✓ ${n||this.message}`}fail(n){return this.stop(),`✗ ${n||this.message}`}warn(n){return this.stop(),`⚠ ${n||this.message}`}info(n){return this.stop(),`ℹ ${n||this.message}`}}class Uy{tasks=[];add(n){return this.tasks.push({title:n,status:"pending"}),this.tasks.length-1}start(n){if(n>=0&&n<this.tasks.length)this.tasks[n].status="running"}complete(n,i){if(n>=0&&n<this.tasks.length)this.tasks[n].status="completed",this.tasks[n].output=i}fail(n,i){if(n>=0&&n<this.tasks.length)this.tasks[n].status="failed",this.tasks[n].output=i}render(){let n=[];for(let i of this.tasks){let o=`${this.getStatusIcon(i.status)} ${i.title}`;if(i.output)o+=`
2712
2712
  ${i.output}`;n.push(o)}return n.join(`
2713
- `)}getStatusIcon(n){switch(n){case"pending":return"○";case"running":return"◐";case"completed":return"✓";case"failed":return"✗";default:return"○"}}}function wi(n,i){let s=[];for(let o=0;o<=i.length;o++)s[o]=[o];for(let o=0;o<=n.length;o++)s[0][o]=o;for(let o=1;o<=i.length;o++)for(let c=1;c<=n.length;c++)if(i.charAt(o-1)===n.charAt(c-1))s[o][c]=s[o-1][c-1];else s[o][c]=Math.min(s[o-1][c-1]+1,s[o][c-1]+1,s[o-1][c]+1);return s[i.length][n.length]}function Ii(n,i){let s=wi(n.toLowerCase(),i.toLowerCase()),o=Math.max(n.length,i.length);if(o===0)return 1;return 1-s/o}function Vm(n,i,s=0.5){return i.map((c)=>({command:c,score:Ii(n,c)})).filter((c)=>c.score>=s).sort((c,u)=>u.score-c.score).map((c)=>c.command).slice(0,5)}function oC(n,i){if(i.length===0)return`Unknown command: '${n}'
2713
+ `)}getStatusIcon(n){switch(n){case"pending":return"○";case"running":return"◐";case"completed":return"✓";case"failed":return"✗";default:return"○"}}}function wi(n,i){let s=[];for(let o=0;o<=i.length;o++)s[o]=[o];for(let o=0;o<=n.length;o++)s[0][o]=o;for(let o=1;o<=i.length;o++)for(let c=1;c<=n.length;c++)if(i.charAt(o-1)===n.charAt(c-1))s[o][c]=s[o-1][c-1];else s[o][c]=Math.min(s[o-1][c-1]+1,s[o][c-1]+1,s[o-1][c]+1);return s[i.length][n.length]}function Ii(n,i){let s=wi(n.toLowerCase(),i.toLowerCase()),o=Math.max(n.length,i.length);if(o===0)return 1;return 1-s/o}function qm(n,i,s=0.5){return i.map((c)=>({command:c,score:Ii(n,c)})).filter((c)=>c.score>=s).sort((c,u)=>u.score-c.score).map((c)=>c.command).slice(0,5)}function aC(n,i){if(i.length===0)return`Unknown command: '${n}'
2714
2714
 
2715
2715
  Run 'ts-cloud --help' to see available commands.`;if(i.length===1)return`Unknown command: '${n}'
2716
2716
 
@@ -2718,17 +2718,17 @@ Did you mean: ${i[0]}?`;return`Unknown command: '${n}'
2718
2718
 
2719
2719
  Did you mean one of these?
2720
2720
  ${i.map((s)=>` • ${s}`).join(`
2721
- `)}`}function aC(n,i){return Vm(n,i,0.7).length>0}function cC(n,i){let s=i.find((u)=>u.commands.some((d)=>d.name===n||d.aliases?.includes(n)));if(!s)return"No contextual help available.";let o=[];o.push(`${s.name}`),o.push("─".repeat(s.name.length)),o.push(s.description),o.push(""),o.push("Related commands:");for(let u of s.commands)if(o.push(` ${u.name.padEnd(20)} ${u.description}`),u.aliases&&u.aliases.length>0)o.push(` Aliases: ${u.aliases.join(", ")}`);let c=s.commands.find((u)=>u.name===n||u.aliases?.includes(n));if(c?.examples&&c.examples.length>0){o.push(""),o.push("Examples:");for(let u of c.examples)o.push(` ${u}`)}return o.join(`
2722
- `)}function dC(n,i){let s=[],o=n.toLowerCase();for(let c of i)for(let u of c.commands){let d=u.name.toLowerCase().includes(o),p=u.description.toLowerCase().includes(o),y=u.aliases?.some((h)=>h.toLowerCase().includes(o));if(d||p||y)s.push({command:u,category:c.name})}return s}function lC(n,i,s=10){let o=n.toLowerCase(),c=i.filter((d)=>d.toLowerCase().startsWith(o)),u=i.filter((d)=>d.toLowerCase().includes(o)&&!d.toLowerCase().startsWith(o));return[...c,...u].slice(0,s)}function uC(n,i){let s=n.toLowerCase();return i.filter((o)=>{let c=o.name.toLowerCase().includes(s),u=o.alias?.toLowerCase().includes(s);return c||u})}function gC(n){if(n.length===0)return"No matching flags found.";let i=[];for(let s of n){let o=` --${s.name}`;if(s.alias)o+=`, -${s.alias}`;if(o=o.padEnd(30),o+=s.description,s.required)o+=" (required)";i.push(o)}return i.join(`
2723
- `)}function pC(n){let i=[];if(i.push(`Usage: ts-cloud ${n.name}`),i.push(""),i.push(n.description),n.aliases&&n.aliases.length>0)i.push(""),i.push(`Aliases: ${n.aliases.join(", ")}`);if(n.examples&&n.examples.length>0){i.push(""),i.push("Examples:");for(let s of n.examples)i.push(` ${s}`)}return i.join(`
2724
- `)}function mC(n,i,s=[]){let o={valid:!0,errors:[],warnings:[],suggestions:[]},[c,...u]=n.split(" ");if(!i.includes(c)){o.valid=!1,o.errors.push(`Unknown command: ${c}`);let d=Vm(c,i);if(d.length>0)o.suggestions.push(...d)}for(let d of s)if(!u.some((p)=>p===`--${d}`||p.startsWith(`--${d}=`)))o.valid=!1,o.errors.push(`Missing required flag: --${d}`);return o}class Uy{options;running=!1;history={commands:[],maxSize:1000};historyIndex=-1;constructor(n){this.options={prompt:n.prompt||"> ",welcome:n.welcome||'Welcome to ts-cloud interactive mode. Type "help" for available commands.',...n}}async start(){if(this.running=!0,this.options.welcome)console.log(this.options.welcome),console.log("");if(this.options.historyFile)await this.loadHistory();while(this.running)try{let n=await this.readInput();if(!n.trim())continue;this.addToHistory(n),await this.executeCommand(n)}catch(n){if(n instanceof Error)console.error(`Error: ${n.message}`)}if(this.options.historyFile)await this.saveHistory()}stop(){this.running=!1}async readInput(){return new Promise((n)=>{process.stdout.write(this.options.prompt||"> "),n("")})}async executeCommand(n){let[i,...s]=this.parseCommand(n);if(i==="exit"||i==="quit"){this.stop();return}if(i==="help"){this.showHelp();return}if(i==="history"){this.showHistory();return}if(i==="clear"){console.clear();return}let o=this.findCommand(i);if(!o){console.error(`Unknown command: ${i}`),console.log('Type "help" to see available commands.');return}try{await o.handler(s)}catch(c){if(c instanceof Error)console.error(`Command failed: ${c.message}`)}}parseCommand(n){return n.trim().split(/\s+/)}findCommand(n){for(let[i,s]of this.options.commands)if(s.name===n||s.aliases?.includes(n))return s;return}showHelp(){console.log("Available commands:"),console.log("");let n=Array.from(this.options.commands.values());console.log(" help Show this help message"),console.log(" history Show command history"),console.log(" clear Clear screen"),console.log(" exit, quit Exit interactive mode"),console.log("");for(let i of n){let s=` ${i.name.padEnd(20)} ${i.description}`;if(i.aliases&&i.aliases.length>0)s+=` (aliases: ${i.aliases.join(", ")})`;console.log(s)}}showHistory(){if(this.history.commands.length===0){console.log("No command history");return}console.log("Command history:"),this.history.commands.forEach((n,i)=>{console.log(` ${(i+1).toString().padStart(4)} ${n}`)})}addToHistory(n){if(this.history.commands[this.history.commands.length-1]===n)return;if(this.history.commands.push(n),this.history.commands.length>this.history.maxSize)this.history.commands=this.history.commands.slice(-this.history.maxSize);this.historyIndex=this.history.commands.length}historyBack(){if(this.historyIndex>0)return this.historyIndex--,this.history.commands[this.historyIndex];return}historyForward(){if(this.historyIndex<this.history.commands.length-1)return this.historyIndex++,this.history.commands[this.historyIndex];return this.historyIndex=this.history.commands.length,""}autocomplete(n){let i=[],s=["help","history","clear","exit","quit"];for(let o of s)if(o.startsWith(n))i.push(o);for(let[o,c]of this.options.commands){if(c.name.startsWith(n))i.push(c.name);if(c.aliases){for(let u of c.aliases)if(u.startsWith(n))i.push(u)}}return i}async loadHistory(){if(!this.options.historyFile)return;try{let n=await import("node:fs/promises"),i=await n.readFile(this.options.historyFile,"utf-8");this.history.commands=i.split(`
2721
+ `)}`}function cC(n,i){return qm(n,i,0.7).length>0}function dC(n,i){let s=i.find((u)=>u.commands.some((d)=>d.name===n||d.aliases?.includes(n)));if(!s)return"No contextual help available.";let o=[];o.push(`${s.name}`),o.push("─".repeat(s.name.length)),o.push(s.description),o.push(""),o.push("Related commands:");for(let u of s.commands)if(o.push(` ${u.name.padEnd(20)} ${u.description}`),u.aliases&&u.aliases.length>0)o.push(` Aliases: ${u.aliases.join(", ")}`);let c=s.commands.find((u)=>u.name===n||u.aliases?.includes(n));if(c?.examples&&c.examples.length>0){o.push(""),o.push("Examples:");for(let u of c.examples)o.push(` ${u}`)}return o.join(`
2722
+ `)}function lC(n,i){let s=[],o=n.toLowerCase();for(let c of i)for(let u of c.commands){let d=u.name.toLowerCase().includes(o),p=u.description.toLowerCase().includes(o),y=u.aliases?.some((h)=>h.toLowerCase().includes(o));if(d||p||y)s.push({command:u,category:c.name})}return s}function uC(n,i,s=10){let o=n.toLowerCase(),c=i.filter((d)=>d.toLowerCase().startsWith(o)),u=i.filter((d)=>d.toLowerCase().includes(o)&&!d.toLowerCase().startsWith(o));return[...c,...u].slice(0,s)}function gC(n,i){let s=n.toLowerCase();return i.filter((o)=>{let c=o.name.toLowerCase().includes(s),u=o.alias?.toLowerCase().includes(s);return c||u})}function pC(n){if(n.length===0)return"No matching flags found.";let i=[];for(let s of n){let o=` --${s.name}`;if(s.alias)o+=`, -${s.alias}`;if(o=o.padEnd(30),o+=s.description,s.required)o+=" (required)";i.push(o)}return i.join(`
2723
+ `)}function mC(n){let i=[];if(i.push(`Usage: ts-cloud ${n.name}`),i.push(""),i.push(n.description),n.aliases&&n.aliases.length>0)i.push(""),i.push(`Aliases: ${n.aliases.join(", ")}`);if(n.examples&&n.examples.length>0){i.push(""),i.push("Examples:");for(let s of n.examples)i.push(` ${s}`)}return i.join(`
2724
+ `)}function fC(n,i,s=[]){let o={valid:!0,errors:[],warnings:[],suggestions:[]},[c,...u]=n.split(" ");if(!i.includes(c)){o.valid=!1,o.errors.push(`Unknown command: ${c}`);let d=qm(c,i);if(d.length>0)o.suggestions.push(...d)}for(let d of s)if(!u.some((p)=>p===`--${d}`||p.startsWith(`--${d}=`)))o.valid=!1,o.errors.push(`Missing required flag: --${d}`);return o}class Qy{options;running=!1;history={commands:[],maxSize:1000};historyIndex=-1;constructor(n){this.options={prompt:n.prompt||"> ",welcome:n.welcome||'Welcome to ts-cloud interactive mode. Type "help" for available commands.',...n}}async start(){if(this.running=!0,this.options.welcome)console.log(this.options.welcome),console.log("");if(this.options.historyFile)await this.loadHistory();while(this.running)try{let n=await this.readInput();if(!n.trim())continue;this.addToHistory(n),await this.executeCommand(n)}catch(n){if(n instanceof Error)console.error(`Error: ${n.message}`)}if(this.options.historyFile)await this.saveHistory()}stop(){this.running=!1}async readInput(){return new Promise((n)=>{process.stdout.write(this.options.prompt||"> "),n("")})}async executeCommand(n){let[i,...s]=this.parseCommand(n);if(i==="exit"||i==="quit"){this.stop();return}if(i==="help"){this.showHelp();return}if(i==="history"){this.showHistory();return}if(i==="clear"){console.clear();return}let o=this.findCommand(i);if(!o){console.error(`Unknown command: ${i}`),console.log('Type "help" to see available commands.');return}try{await o.handler(s)}catch(c){if(c instanceof Error)console.error(`Command failed: ${c.message}`)}}parseCommand(n){return n.trim().split(/\s+/)}findCommand(n){for(let[i,s]of this.options.commands)if(s.name===n||s.aliases?.includes(n))return s;return}showHelp(){console.log("Available commands:"),console.log("");let n=Array.from(this.options.commands.values());console.log(" help Show this help message"),console.log(" history Show command history"),console.log(" clear Clear screen"),console.log(" exit, quit Exit interactive mode"),console.log("");for(let i of n){let s=` ${i.name.padEnd(20)} ${i.description}`;if(i.aliases&&i.aliases.length>0)s+=` (aliases: ${i.aliases.join(", ")})`;console.log(s)}}showHistory(){if(this.history.commands.length===0){console.log("No command history");return}console.log("Command history:"),this.history.commands.forEach((n,i)=>{console.log(` ${(i+1).toString().padStart(4)} ${n}`)})}addToHistory(n){if(this.history.commands[this.history.commands.length-1]===n)return;if(this.history.commands.push(n),this.history.commands.length>this.history.maxSize)this.history.commands=this.history.commands.slice(-this.history.maxSize);this.historyIndex=this.history.commands.length}historyBack(){if(this.historyIndex>0)return this.historyIndex--,this.history.commands[this.historyIndex];return}historyForward(){if(this.historyIndex<this.history.commands.length-1)return this.historyIndex++,this.history.commands[this.historyIndex];return this.historyIndex=this.history.commands.length,""}autocomplete(n){let i=[],s=["help","history","clear","exit","quit"];for(let o of s)if(o.startsWith(n))i.push(o);for(let[o,c]of this.options.commands){if(c.name.startsWith(n))i.push(c.name);if(c.aliases){for(let u of c.aliases)if(u.startsWith(n))i.push(u)}}return i}async loadHistory(){if(!this.options.historyFile)return;try{let n=await import("node:fs/promises"),i=await n.readFile(this.options.historyFile,"utf-8");this.history.commands=i.split(`
2725
2725
  `).filter((s)=>s.trim()),this.historyIndex=this.history.commands.length}catch{}}async saveHistory(){if(!this.options.historyFile)return;try{let n=await import("node:fs/promises");await n.writeFile(this.options.historyFile,this.history.commands.join(`
2726
- `))}catch(n){console.error(`Failed to save history: ${n}`)}}searchHistory(n){return this.history.commands.filter((i)=>i.includes(n))}clearHistory(){this.history.commands=[],this.historyIndex=0}}class Qy{variables=new Map;workingDirectory=process.cwd();set(n,i){this.variables.set(n,i)}get(n){return this.variables.get(n)}has(n){return this.variables.has(n)}delete(n){this.variables.delete(n)}getAll(){return Object.fromEntries(this.variables)}clear(){this.variables.clear()}setWorkingDirectory(n){this.workingDirectory=n}getWorkingDirectory(){return this.workingDirectory}}class Hy{command={};name(n){return this.command.name=n,this}description(n){return this.command.description=n,this}aliases(...n){return this.command.aliases=n,this}handler(n){return this.command.handler=n,this}autocomplete(n){return this.command.autocomplete=n,this}build(){if(!this.command.name||!this.command.description||!this.command.handler)throw Error("Command must have name, description, and handler");return this.command}}class Gy{entries=[];maxSize;persistFile;trackOutput;constructor(n={}){this.maxSize=n.maxSize||1000,this.persistFile=n.persistFile,this.trackOutput=n.trackOutput||!1}add(n){if(this.entries.push({...n,timestamp:new Date}),this.entries.length>this.maxSize)this.entries=this.entries.slice(-this.maxSize)}getAll(){return[...this.entries]}getRecent(n=10){return this.entries.slice(-n)}search(n){let i=n.toLowerCase();return this.entries.filter((s)=>s.command.toLowerCase().includes(i))}searchByDate(n,i){return this.entries.filter((s)=>s.timestamp>=n&&s.timestamp<=i)}getSuccessful(){return this.entries.filter((n)=>n.success)}getFailed(){return this.entries.filter((n)=>!n.success)}getMostUsed(n=10){let i=new Map;for(let s of this.entries){let o=s.command.split(" ")[0];i.set(o,(i.get(o)||0)+1)}return Array.from(i.entries()).map(([s,o])=>({command:s,count:o})).sort((s,o)=>o.count-s.count).slice(0,n)}getStats(){let n=this.entries.length,i=this.entries.filter((p)=>p.success).length,s=this.entries.filter((p)=>!p.success).length,o=this.entries.filter((p)=>p.duration!==void 0),c=o.length>0?o.reduce((p,y)=>p+(y.duration||0),0)/o.length:0,u=this.getMostUsed(1),d=u.length>0?u[0].command:"N/A";return{total:n,successful:i,failed:s,averageDuration:c,mostUsed:d}}clear(){this.entries=[]}getByIndex(n){if(n<0||n>=this.entries.length)return;return this.entries[n]}removeByIndex(n){if(n>=0&&n<this.entries.length)this.entries.splice(n,1)}async save(){if(!this.persistFile)return;try{let n=await import("node:fs/promises"),i=JSON.stringify(this.entries,null,2);await n.writeFile(this.persistFile,i,"utf-8")}catch(n){throw Error(`Failed to save history: ${n}`)}}async load(){if(!this.persistFile)return;try{let n=await import("node:fs/promises"),i=await n.readFile(this.persistFile,"utf-8"),s=JSON.parse(i);this.entries=s.map((o)=>({...o,timestamp:new Date(o.timestamp)}))}catch{this.entries=[]}}exportJSON(){return JSON.stringify(this.entries,null,2)}exportCSV(){return["Timestamp,Command,Success,Duration",...this.entries.map((s)=>[s.timestamp.toISOString(),`"${s.command.replace(/"/g,'""')}"`,s.success,s.duration||""].join(","))].join(`
2727
- `)}importJSON(n){let s=JSON.parse(n).map((o)=>({...o,timestamp:new Date(o.timestamp)}));if(this.entries.push(...s),this.entries.length>this.maxSize)this.entries=this.entries.slice(-this.maxSize)}groupByDate(){let n=new Map;for(let i of this.entries){let s=i.timestamp.toISOString().split("T")[0];if(!n.has(s))n.set(s,[]);n.get(s).push(i)}return n}groupByCommand(){let n=new Map;for(let i of this.entries){let s=i.command.split(" ")[0];if(!n.has(s))n.set(s,[]);n.get(s).push(i)}return n}replay(n){return this.getByIndex(n)?.command}getSuggestions(n,i=5){let s=n.toLowerCase(),o=this.entries.filter((c)=>c.command.toLowerCase().startsWith(s)).map((c)=>c.command);return[...new Set(o)].slice(0,i)}analyzePatterns(){let n=new Map,i=new Map;for(let o of this.entries){let c=o.timestamp.getHours(),u=o.timestamp.getDay();n.set(c,(n.get(c)||0)+1),i.set(u,(i.get(u)||0)+1)}let s=this.entries.length>0?this.getSuccessful().length/this.entries.length:0;return{timeOfDay:n,dayOfWeek:i,successRate:s}}}function fC(n,i={}){let{maxWidth:s=100}=i;if(n.length===0)return"No command history";let o=[];for(let c=0;c<n.length;c++){let u=n[c],d=(c+1).toString().padStart(4),p=u.timestamp.toLocaleString(),y=u.success?"✓":"✗",h=u.command;if(h.length>s-30)h=h.substring(0,s-33)+"...";let b=`${d} ${p} ${y} ${h}`;if(u.duration)b+=` (${u.duration}ms)`;o.push(b)}return o.join(`
2728
- `)}function hC(n){let i=[];return i.push("Command History Statistics"),i.push("─".repeat(30)),i.push(`Total commands: ${n.total}`),i.push(`Successful: ${n.successful}`),i.push(`Failed: ${n.failed}`),i.push(`Success rate: ${(n.successful/n.total*100).toFixed(1)}%`),i.push(`Average duration: ${n.averageDuration.toFixed(0)}ms`),i.push(`Most used: ${n.mostUsed}`),i.join(`
2729
- `)}class qm{deployments=new Map;async deploy(n,i){let s=this.generateDeploymentId(),o={id:s,regions:i.regions.map((c)=>({region:c.code,stackName:this.getStackName(n,c.code),status:"pending"})),status:"deploying",startTime:new Date};this.deployments.set(s,o);try{let c=i.regions.find((d)=>d.isPrimary)||i.regions[0];await this.deployToRegion(n,c,o);let u=i.regions.filter((d)=>d.code!==c.code);if(await Promise.all(u.map((d)=>this.deployToRegion(n,d,o))),i.globalResources)await this.deployGlobalResources(o,i);if(i.replication)await this.setupReplication(o,i);if(i.failover?.enabled)await this.setupFailover(o,i);return o.status="deployed",o.endTime=new Date,o}catch(c){throw o.status="failed",o.endTime=new Date,c}}async deployToRegion(n,i,s){let o=s.regions.find((c)=>c.region===i.code);if(!o)throw Error(`Region deployment not found: ${i.code}`);o.status="deploying",o.startTime=new Date;try{let c=this.createRegionConfig(n,i);await this.deployStack(o.stackName,c,i.code),o.status="deployed",o.endTime=new Date,o.outputs={stackId:`arn:aws:cloudformation:${i.code}:123456789012:stack/${o.stackName}/guid`,endpoint:`https://${o.stackName}.${i.code}.example.com`}}catch(c){throw o.status="failed",o.endTime=new Date,o.error=c instanceof Error?c.message:String(c),c}}async deployGlobalResources(n,i){let s={};if(i.globalResources?.route53)s.route53=await this.deployRoute53(n,i);if(i.globalResources?.cloudfront)s.cloudfront=await this.deployCloudFront(n,i);if(i.globalResources?.waf)s.waf=await this.deployWAF(n);n.globalResources=s}async deployRoute53(n,i){let s=[],o=[];for(let c of n.regions){if(c.status!=="deployed")continue;let u={id:`health-${c.region}`,endpoint:c.outputs?.endpoint,path:i.failover?.healthCheckPath||"/health",region:c.region};s.push(u);let d={name:"example.com",type:"A",region:c.region,setIdentifier:c.region,healthCheckId:u.id,resourceRecords:[c.outputs?.endpoint]};o.push(d)}return{healthChecks:s,recordSets:o,hostedZoneId:"Z1234567890ABC"}}async deployCloudFront(n,i){return{distributionId:"E1234567890ABC",domainName:"d1234567890abc.cloudfront.net",origins:n.regions.filter((o)=>o.status==="deployed").map((o,c)=>{let u=i.regions[c];return{id:`origin-${o.region}`,domainName:o.outputs?.endpoint,weight:u?.weight||100}}),status:"Deployed"}}async deployWAF(n){return{webAclId:"arn:aws:wafv2:us-east-1:123456789012:global/webacl/test/a1234567-b890-c123-d456-e789012345f6",webAclArn:"arn:aws:wafv2:us-east-1:123456789012:global/webacl/test/a1234567-b890-c123-d456-e789012345f6"}}async setupReplication(n,i){if(i.replication?.s3)await this.setupS3Replication(n);if(i.replication?.dynamodb)await this.setupDynamoDBReplication(n);if(i.replication?.secrets)await this.setupSecretsReplication(n)}async setupS3Replication(n){let i=n.regions.filter((s)=>s.status==="deployed");for(let s=0;s<i.length-1;s++){let o=i[s],c=i[s+1];console.log(`Setting up S3 replication: ${o.region} -> ${c.region}`)}}async setupDynamoDBReplication(n){let i=n.regions.filter((s)=>s.status==="deployed").map((s)=>s.region);console.log(`Setting up DynamoDB global table in regions: ${i.join(", ")}`)}async setupSecretsReplication(n){let i=n.regions.filter((s)=>s.status==="deployed").map((s)=>s.region);console.log(`Setting up Secrets Manager replication in regions: ${i.join(", ")}`)}async setupFailover(n,i){let s=n.regions.find((c,u)=>i.regions[u]?.isPrimary)||n.regions[0],o=n.regions.filter((c)=>c.region!==s.region);console.log(`Setting up failover: primary=${s.region}, secondary=${o.map((c)=>c.region).join(", ")}`)}async destroy(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);i.status="rolling-back";try{if(i.globalResources)await this.destroyGlobalResources(i.globalResources);await Promise.all(i.regions.map((s)=>this.destroyRegionStack(s))),this.deployments.delete(n)}catch(s){throw i.status="failed",s}}async destroyGlobalResources(n){if(n.waf)console.log("Destroying WAF resources");if(n.cloudfront)console.log("Destroying CloudFront distribution");if(n.route53)console.log("Destroying Route53 resources")}async destroyRegionStack(n){if(n.status!=="deployed")return;n.status="rolling-back";try{console.log(`Destroying stack ${n.stackName} in ${n.region}`),n.status="pending"}catch(i){throw n.status="failed",n.error=i instanceof Error?i.message:String(i),i}}getDeployment(n){return this.deployments.get(n)}listDeployments(){return Array.from(this.deployments.values())}getStackName(n,i){return`${n.project.slug}-${i}`}createRegionConfig(n,i){return{...n,infrastructure:{...n.infrastructure}}}async deployStack(n,i,s){console.log(`Deploying stack ${n} to ${s}`)}generateDeploymentId(){return`deploy-${Date.now()}-${Math.random().toString(36).substring(7)}`}}var AC=new qm;class jm{references=[];exports=new Map;addExport(n){let i=`${n.region}:${n.exportName}`;if(!this.exports.has(n.region))this.exports.set(n.region,[]);this.exports.get(n.region).push(n)}getExport(n,i){let s=this.exports.get(n);if(!s)return;return s.find((c)=>c.exportName===i)?.value}createReference(n,i,s,o){let c=`/cross-region/${n}/${s}/${o}`;return this.references.push({sourceRegion:n,targetRegion:i,resourceType:s,resourceId:o,value:c}),c}async resolveReference(n,i){let s=this.references.find((o)=>o.targetRegion===n&&o.value===i);if(!s)throw Error(`Reference not found: ${i}`);return`arn:aws:resource:${s.sourceRegion}:123456789012:${s.resourceType}/${s.resourceId}`}getReferencesForRegion(n){return this.references.filter((i)=>i.sourceRegion===n||i.targetRegion===n)}clear(){this.references=[],this.exports.clear()}}class zm{resources=new Map;register(n){this.resources.set(n.id,n)}get(n){return this.resources.get(n)}getByType(n){return Array.from(this.resources.values()).filter((i)=>i.type===n)}getCloudFrontDistributions(){return this.getByType("cloudfront")}getRoute53HostedZones(){return this.getByType("route53")}getWAFWebACLs(){return this.getByType("waf")}remove(n){this.resources.delete(n)}clear(){this.resources.clear()}}class Km{pairs=[];addPair(n){this.pairs.push(n)}getPairedRegion(n){let i=this.pairs.find((s)=>s.primary===n||s.secondary===n);if(!i)return;return i.primary===n?i.secondary:i.primary}getAllPairs(){return[...this.pairs]}getReplicatedPairs(){return this.pairs.filter((n)=>n.replicationConfig)}getFailoverPairs(){return this.pairs.filter((n)=>n.failoverConfig?.automatic)}arePaired(n,i){return this.pairs.some((s)=>s.primary===n&&s.secondary===i||s.primary===i&&s.secondary===n)}clear(){this.pairs=[]}}class Wm{dependencies=[];addDependency(n){this.dependencies.push(n)}getDependencies(n,i){return this.dependencies.filter((s)=>s.dependentStack===n&&s.dependentRegion===i)}getDependents(n,i){return this.dependencies.filter((s)=>s.dependsOnStack===n&&s.dependsOnRegion===i)}hasDependencies(n,i){return this.getDependencies(n,i).length>0}getDeploymentOrder(n){let i=new Set,s=[],o=(c)=>{let u=`${c.name}:${c.region}`;if(i.has(u))return;i.add(u);let d=this.getDependencies(c.name,c.region);for(let p of d)o({name:p.dependsOnStack,region:p.dependsOnRegion});s.push(c)};for(let c of n)o(c);return s}detectCircularDependencies(){let n=new Set,i=new Set,s=(o,c)=>{let u=`${o}:${c}`;if(i.has(u))return!0;if(n.has(u))return!1;n.add(u),i.add(u);let d=this.getDependencies(o,c);for(let p of d)if(s(p.dependsOnStack,p.dependsOnRegion))return!0;return i.delete(u),!1};for(let o of this.dependencies)if(s(o.dependentStack,o.dependentRegion))return!0;return!1}clear(){this.dependencies=[]}}var yC=new jm,SC=new zm,IC=new Km,bC=new Wm;var _e=[{code:"us-east-1",name:"US East (N. Virginia)",location:"Virginia, USA",launchYear:2006,availabilityZones:6,localZones:16,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1},compliance:["PCI-DSS","HIPAA","SOC","ISO","FedRAMP"]},{code:"us-east-2",name:"US East (Ohio)",location:"Ohio, USA",launchYear:2016,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1},compliance:["PCI-DSS","HIPAA","SOC","ISO"]},{code:"us-west-1",name:"US West (N. California)",location:"California, USA",launchYear:2009,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.1},compliance:["PCI-DSS","HIPAA","SOC","ISO"]},{code:"us-west-2",name:"US West (Oregon)",location:"Oregon, USA",launchYear:2011,availabilityZones:4,localZones:2,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1},compliance:["PCI-DSS","HIPAA","SOC","ISO"]},{code:"eu-west-1",name:"Europe (Ireland)",location:"Dublin, Ireland",launchYear:2007,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1.05},compliance:["PCI-DSS","GDPR","SOC","ISO"]},{code:"eu-central-1",name:"Europe (Frankfurt)",location:"Frankfurt, Germany",launchYear:2014,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.1},compliance:["PCI-DSS","GDPR","SOC","ISO"]},{code:"ap-southeast-1",name:"Asia Pacific (Singapore)",location:"Singapore",launchYear:2010,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.12},compliance:["PCI-DSS","SOC","ISO","MTCS"]},{code:"ap-northeast-1",name:"Asia Pacific (Tokyo)",location:"Tokyo, Japan",launchYear:2011,availabilityZones:4,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.15},compliance:["PCI-DSS","SOC","ISO"]}];function ts(n){return _e.find((i)=>i.code===n)}function CC(){return _e}function EC(n){let i=n.toLowerCase();return _e.filter((s)=>s.location.toLowerCase().includes(i))}function vC(n){return _e.filter((i)=>i.compliance.includes(n))}function TC(n){return _e.filter((i)=>i.pricing.tier===n)}function wC(n){return _e.some((i)=>i.code===n)}function RC(n){if(n.continent==="North America")return ts("us-east-1");if(n.continent==="Europe")return ts("eu-west-1");if(n.continent==="Asia")return ts("ap-southeast-1");return ts("us-east-1")}function DC(n){let i=[..._e];if(n.compliance)i=i.filter((s)=>n.compliance.every((o)=>s.compliance.includes(o)));if(n.requiredServices)i=i.filter((s)=>n.requiredServices.every((o)=>s.services[o]));if(n.pricingSensitive)i.sort((s,o)=>s.pricing.multiplier-o.pricing.multiplier);return i.slice(0,5)}function PC(n){let i=ts(n);if(!i)throw Error(`Invalid region: ${n}`);let s=[];for(let o of _e){if(o.code===n)continue;let c=Di(i,o),u=Ni(i,o);s.push({primary:i,secondary:o,distance:c,sameContinent:u})}return s.sort((o,c)=>{if(o.sameContinent!==c.sameContinent)return o.sameContinent?1:-1;return o.distance-c.distance}),s.slice(0,3)}function Di(n,i){let s={"North America":0,"South America":1,Europe:2,Asia:3,Africa:4,Oceania:5},o=Je(n.location),c=Je(i.location);return Math.abs((s[o]||0)-(s[c]||0))}function Ni(n,i){return Je(n.location)===Je(i.location)}function Je(n){if(n.includes("USA")||n.includes("Canada"))return"North America";if(n.includes("Europe")||n.includes("Ireland")||n.includes("Germany"))return"Europe";if(n.includes("Asia")||n.includes("Singapore")||n.includes("Japan"))return"Asia";if(n.includes("Brazil"))return"South America";if(n.includes("Australia"))return"Oceania";return"Unknown"}function Vy(n){return`${n.name} (${n.code})`}function kC(n){return n.map((i)=>Vy(i)).join(`
2730
- `)}function NC(){let n={total:_e.length,byContinent:{},byPricingTier:{}};for(let i of _e){let s=Je(i.location);n.byContinent[s]=(n.byContinent[s]||0)+1,n.byPricingTier[i.pricing.tier]=(n.byPricingTier[i.pricing.tier]||0)+1}return n}class Jm{accounts=new Map;crossAccountRoles=[];accountMappings=[];registerAccount(n){this.accounts.set(n.id,n)}getAccount(n){return this.accounts.get(n)}getAccountByAlias(n){return Array.from(this.accounts.values()).find((i)=>i.alias===n)}listAccounts(){return Array.from(this.accounts.values())}getAccountsByRole(n){return Array.from(this.accounts.values()).filter((i)=>i.role===n)}createCrossAccountRole(n,i,s,o,c){let u={roleArn:`arn:aws:iam::${i}:role/${s}`,roleName:s,sourceAccountId:n,targetAccountId:i,permissions:o,externalId:c?.externalId,sessionDuration:c?.sessionDuration||3600};return this.crossAccountRoles.push(u),u}getAssumeRolePolicyDocument(n,i){let s={Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:`arn:aws:iam::${n}:root`},Action:"sts:AssumeRole"}]};if(i)s.Statement[0].Condition={StringEquals:{"sts:ExternalId":i}};return s}generateCrossAccountPolicy(n){return{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:n,Resource:"*"}]}}mapEnvironmentToAccount(n,i,s){this.accountMappings.push({environment:n,accountId:i,region:s})}getAccountForEnvironment(n){return this.accountMappings.find((i)=>i.environment===n)}async assumeRole(n,i,s){return console.log(`Assuming role: ${n} with session: ${i}`),{accessKeyId:"AKIAIOSFODNN7EXAMPLE",secretAccessKey:"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",sessionToken:"token",expiration:new Date(Date.now()+3600000)}}async getCredentialsForAccount(n){let i=this.accounts.get(n);if(!i)throw Error(`Account not found: ${n}`);if(i.assumeRoleArn){let s=await this.assumeRole(i.assumeRoleArn,`ts-cloud-${Date.now()}`);return{accessKeyId:s.accessKeyId,secretAccessKey:s.secretAccessKey,sessionToken:s.sessionToken}}throw Error("No credentials available for account")}listCrossAccountRoles(){return[...this.crossAccountRoles]}getCrossAccountRolesForAccount(n){return this.crossAccountRoles.filter((i)=>i.sourceAccountId===n||i.targetAccountId===n)}async validateAccountAccess(n){try{let i=await this.getCredentialsForAccount(n);return console.log(`Validating access to account: ${n}`),!0}catch{return!1}}async getConsolidatedBilling(){let n={};for(let s of this.accounts.values())n[s.id]=Math.random()*1000;return{totalCost:Object.values(n).reduce((s,o)=>s+o,0),byAccount:n}}clear(){this.accounts.clear(),this.crossAccountRoles=[],this.accountMappings=[]}}class Xm{organizationId;organizationalUnits=new Map;getOrganizationId(){return this.organizationId}setOrganizationId(n){this.organizationId=n}createOrganizationalUnit(n,i){let s={id:`ou-${Date.now()}`,name:n,parentId:i,accounts:[]};return this.organizationalUnits.set(s.id,s),s}getOrganizationalUnit(n){return this.organizationalUnits.get(n)}listOrganizationalUnits(){return Array.from(this.organizationalUnits.values())}addAccountToOU(n,i){let s=this.organizationalUnits.get(n);if(!s)throw Error(`Organizational unit not found: ${n}`);if(!s.accounts.includes(i))s.accounts.push(i)}removeAccountFromOU(n,i){let s=this.organizationalUnits.get(n);if(!s)throw Error(`Organizational unit not found: ${n}`);s.accounts=s.accounts.filter((o)=>o!==i)}getAccountsInOU(n){let i=this.organizationalUnits.get(n);if(!i)return[];return[...i.accounts]}applyServiceControlPolicy(n,i){return{id:`scp-${Date.now()}`,name:"Custom SCP",targetId:n,policyDocument:i}}clear(){this.organizationId=void 0,this.organizationalUnits.clear()}}var BC=new Jm,xC=new Xm;var qy={basic:{name:"Basic (3 Accounts)",description:"Simple structure for small teams",accounts:[{alias:"management",email:"aws+management@example.com",role:"management",ou:"root",description:"Management account for AWS Organizations"},{alias:"production",email:"aws+production@example.com",role:"production",ou:"workloads",description:"Production workloads"},{alias:"development",email:"aws+development@example.com",role:"development",ou:"workloads",description:"Development and testing"}],organizationalUnits:[{name:"root"},{name:"workloads",parent:"root"}]},standard:{name:"Standard (5 Accounts)",description:"Recommended for most organizations",accounts:[{alias:"management",email:"aws+management@example.com",role:"management",ou:"root",description:"Management account"},{alias:"security",email:"aws+security@example.com",role:"security",ou:"security",description:"Security tooling and audit logs"},{alias:"shared-services",email:"aws+shared@example.com",role:"shared-services",ou:"infrastructure",description:"Shared services (CI/CD, monitoring)"},{alias:"production",email:"aws+production@example.com",role:"production",ou:"workloads",description:"Production environment"},{alias:"staging",email:"aws+staging@example.com",role:"staging",ou:"workloads",description:"Staging environment"},{alias:"development",email:"aws+development@example.com",role:"development",ou:"workloads",description:"Development environment"}],organizationalUnits:[{name:"root"},{name:"security",parent:"root"},{name:"infrastructure",parent:"root"},{name:"workloads",parent:"root"}]},enterprise:{name:"Enterprise (7+ Accounts)",description:"For large organizations with strict compliance requirements",accounts:[{alias:"management",email:"aws+management@example.com",role:"management",ou:"root",description:"Management account"},{alias:"audit",email:"aws+audit@example.com",role:"security",ou:"security",description:"Audit and compliance"},{alias:"log-archive",email:"aws+logs@example.com",role:"security",ou:"security",description:"Centralized log storage"},{alias:"shared-services",email:"aws+shared@example.com",role:"shared-services",ou:"infrastructure",description:"Shared infrastructure"},{alias:"network",email:"aws+network@example.com",role:"shared-services",ou:"infrastructure",description:"Network infrastructure (Transit Gateway)"},{alias:"production",email:"aws+production@example.com",role:"production",ou:"production-ou",description:"Production workloads"},{alias:"staging",email:"aws+staging@example.com",role:"staging",ou:"non-production-ou",description:"Staging environment"},{alias:"development",email:"aws+development@example.com",role:"development",ou:"non-production-ou",description:"Development environment"}],organizationalUnits:[{name:"root"},{name:"security",parent:"root",policies:["deny-root-access"]},{name:"infrastructure",parent:"root"},{name:"production-ou",parent:"root",policies:["require-mfa"]},{name:"non-production-ou",parent:"root"}]}},OC={denyRootAccess:{name:"Deny Root User Access",description:"Prevent root user from performing any actions",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"DenyRootUser",Effect:"Deny",Action:"*",Resource:"*",Condition:{StringLike:{"aws:PrincipalArn":"arn:aws:iam::*:root"}}}]}},requireMFA:{name:"Require MFA for All Actions",description:"Require MFA for console and API access",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"RequireMFA",Effect:"Deny",Action:"*",Resource:"*",Condition:{BoolIfExists:{"aws:MultiFactorAuthPresent":"false"}}}]}},denyRegions:{name:"Deny Access to Non-Approved Regions",description:"Restrict operations to specific regions",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"DenyNonApprovedRegions",Effect:"Deny",NotAction:["iam:*","organizations:*","route53:*","cloudfront:*","support:*","s3:*"],Resource:"*",Condition:{StringNotEquals:{"aws:RequestedRegion":["us-east-1","us-west-2"]}}}]}},preventLeaving:{name:"Prevent Leaving Organization",description:"Prevent accounts from leaving the organization",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"PreventLeaving",Effect:"Deny",Action:"organizations:LeaveOrganization",Resource:"*"}]}},denyS3Unencrypted:{name:"Deny Unencrypted S3 Uploads",description:"Require encryption for all S3 uploads",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"DenyUnencryptedS3Uploads",Effect:"Deny",Action:"s3:PutObject",Resource:"*",Condition:{StringNotEquals:{"s3:x-amz-server-side-encryption":["AES256","aws:kms"]}}}]}}},_C={deploymentRole:{name:"CrossAccountDeploymentRole",description:"Role for deploying infrastructure from CI/CD",permissions:["cloudformation:*","s3:*","ec2:*","ecs:*","lambda:*","iam:GetRole","iam:PassRole","logs:*","events:*"]},readOnlyRole:{name:"CrossAccountReadOnlyRole",description:"Read-only access for monitoring and auditing",permissions:["cloudformation:Describe*","cloudformation:List*","ec2:Describe*","ecs:Describe*","lambda:Get*","lambda:List*","s3:Get*","s3:List*","logs:Get*","logs:Describe*"]},securityAuditRole:{name:"CrossAccountSecurityAuditRole",description:"Security audit and compliance checks",permissions:["iam:Get*","iam:List*","iam:Generate*","access-analyzer:*","guardduty:Get*","guardduty:List*","securityhub:Get*","securityhub:List*","config:Describe*","config:Get*","config:List*"]},breakGlassRole:{name:"CrossAccountBreakGlassRole",description:"Emergency access role (use with caution)",permissions:["*"]}};function LC(n){return qy[n]}function $C(n,i){return{Type:"AWS::IAM::Role",Properties:{RoleName:n.roleName,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:`arn:aws:iam::${n.sourceAccountId}:root`},Action:"sts:AssumeRole",...n.externalId&&{Condition:{StringEquals:{"sts:ExternalId":n.externalId}}}}]},Policies:[{PolicyName:`${n.roleName}Policy`,PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:n.permissions,Resource:"*"}]}}],...i&&{ManagedPolicyArns:i},MaxSessionDuration:n.sessionDuration||3600,Tags:[{Key:"ManagedBy",Value:"TS-Cloud"},{Key:"SourceAccount",Value:n.sourceAccountId}]}}}function MC(n){let i=[],s=[],o=n.accounts.filter((y)=>y.role==="management");if(o.length===0)i.push("No management account defined");if(o.length>1)i.push("Multiple management accounts defined");let c=n.accounts.map((y)=>y.email),u=c.filter((y,h)=>c.indexOf(y)!==h);if(u.length>0)i.push(`Duplicate email addresses: ${u.join(", ")}`);let d=n.accounts.map((y)=>y.alias),p=d.filter((y,h)=>d.indexOf(y)!==h);if(p.length>0)i.push(`Duplicate aliases: ${p.join(", ")}`);if(!n.accounts.some((y)=>y.role==="security"))s.push("No dedicated security account - consider adding one for audit logs");if(n.accounts.length<3)s.push("Less than 3 accounts - consider separating environments");if(!n.accounts.some((y)=>y.role==="production"))s.push("No production account defined");return{valid:i.length===0,errors:i,warnings:s}}function FC(n){let i=[];if(i.push(`${n.name}`),i.push("─".repeat(n.name.length)),i.push(n.description),i.push(""),n.organizationalUnits){i.push("Organizational Units:");for(let s of n.organizationalUnits){let o=s.parent?" └─ ":" ";i.push(`${o}${s.name}`)}i.push("")}i.push("Accounts:");for(let s of n.accounts)i.push(` ${s.alias.padEnd(20)} ${s.role.padEnd(15)} ${s.email}`),i.push(` ${"".padEnd(20)} ${s.description}`),i.push("");return i.join(`
2731
- `)}function UC(n={}){let{workflowName:i="Deploy",trigger:s="push",branches:o=["main"],environments:c=["production"],awsRegion:u="us-east-1",awsRole:d,bunVersion:p="latest",deployCommand:y="bun run cloud deploy",testCommand:h="bun test",buildCommand:b="bun run build"}=n,v=!!d;return`name: ${i}
2726
+ `))}catch(n){console.error(`Failed to save history: ${n}`)}}searchHistory(n){return this.history.commands.filter((i)=>i.includes(n))}clearHistory(){this.history.commands=[],this.historyIndex=0}}class Hy{variables=new Map;workingDirectory=process.cwd();set(n,i){this.variables.set(n,i)}get(n){return this.variables.get(n)}has(n){return this.variables.has(n)}delete(n){this.variables.delete(n)}getAll(){return Object.fromEntries(this.variables)}clear(){this.variables.clear()}setWorkingDirectory(n){this.workingDirectory=n}getWorkingDirectory(){return this.workingDirectory}}class Gy{command={};name(n){return this.command.name=n,this}description(n){return this.command.description=n,this}aliases(...n){return this.command.aliases=n,this}handler(n){return this.command.handler=n,this}autocomplete(n){return this.command.autocomplete=n,this}build(){if(!this.command.name||!this.command.description||!this.command.handler)throw Error("Command must have name, description, and handler");return this.command}}class Vy{entries=[];maxSize;persistFile;trackOutput;constructor(n={}){this.maxSize=n.maxSize||1000,this.persistFile=n.persistFile,this.trackOutput=n.trackOutput||!1}add(n){if(this.entries.push({...n,timestamp:new Date}),this.entries.length>this.maxSize)this.entries=this.entries.slice(-this.maxSize)}getAll(){return[...this.entries]}getRecent(n=10){return this.entries.slice(-n)}search(n){let i=n.toLowerCase();return this.entries.filter((s)=>s.command.toLowerCase().includes(i))}searchByDate(n,i){return this.entries.filter((s)=>s.timestamp>=n&&s.timestamp<=i)}getSuccessful(){return this.entries.filter((n)=>n.success)}getFailed(){return this.entries.filter((n)=>!n.success)}getMostUsed(n=10){let i=new Map;for(let s of this.entries){let o=s.command.split(" ")[0];i.set(o,(i.get(o)||0)+1)}return Array.from(i.entries()).map(([s,o])=>({command:s,count:o})).sort((s,o)=>o.count-s.count).slice(0,n)}getStats(){let n=this.entries.length,i=this.entries.filter((p)=>p.success).length,s=this.entries.filter((p)=>!p.success).length,o=this.entries.filter((p)=>p.duration!==void 0),c=o.length>0?o.reduce((p,y)=>p+(y.duration||0),0)/o.length:0,u=this.getMostUsed(1),d=u.length>0?u[0].command:"N/A";return{total:n,successful:i,failed:s,averageDuration:c,mostUsed:d}}clear(){this.entries=[]}getByIndex(n){if(n<0||n>=this.entries.length)return;return this.entries[n]}removeByIndex(n){if(n>=0&&n<this.entries.length)this.entries.splice(n,1)}async save(){if(!this.persistFile)return;try{let n=await import("node:fs/promises"),i=JSON.stringify(this.entries,null,2);await n.writeFile(this.persistFile,i,"utf-8")}catch(n){throw Error(`Failed to save history: ${n}`)}}async load(){if(!this.persistFile)return;try{let n=await import("node:fs/promises"),i=await n.readFile(this.persistFile,"utf-8"),s=JSON.parse(i);this.entries=s.map((o)=>({...o,timestamp:new Date(o.timestamp)}))}catch{this.entries=[]}}exportJSON(){return JSON.stringify(this.entries,null,2)}exportCSV(){return["Timestamp,Command,Success,Duration",...this.entries.map((s)=>[s.timestamp.toISOString(),`"${s.command.replace(/"/g,'""')}"`,s.success,s.duration||""].join(","))].join(`
2727
+ `)}importJSON(n){let s=JSON.parse(n).map((o)=>({...o,timestamp:new Date(o.timestamp)}));if(this.entries.push(...s),this.entries.length>this.maxSize)this.entries=this.entries.slice(-this.maxSize)}groupByDate(){let n=new Map;for(let i of this.entries){let s=i.timestamp.toISOString().split("T")[0];if(!n.has(s))n.set(s,[]);n.get(s).push(i)}return n}groupByCommand(){let n=new Map;for(let i of this.entries){let s=i.command.split(" ")[0];if(!n.has(s))n.set(s,[]);n.get(s).push(i)}return n}replay(n){return this.getByIndex(n)?.command}getSuggestions(n,i=5){let s=n.toLowerCase(),o=this.entries.filter((c)=>c.command.toLowerCase().startsWith(s)).map((c)=>c.command);return[...new Set(o)].slice(0,i)}analyzePatterns(){let n=new Map,i=new Map;for(let o of this.entries){let c=o.timestamp.getHours(),u=o.timestamp.getDay();n.set(c,(n.get(c)||0)+1),i.set(u,(i.get(u)||0)+1)}let s=this.entries.length>0?this.getSuccessful().length/this.entries.length:0;return{timeOfDay:n,dayOfWeek:i,successRate:s}}}function hC(n,i={}){let{maxWidth:s=100}=i;if(n.length===0)return"No command history";let o=[];for(let c=0;c<n.length;c++){let u=n[c],d=(c+1).toString().padStart(4),p=u.timestamp.toLocaleString(),y=u.success?"✓":"✗",h=u.command;if(h.length>s-30)h=h.substring(0,s-33)+"...";let b=`${d} ${p} ${y} ${h}`;if(u.duration)b+=` (${u.duration}ms)`;o.push(b)}return o.join(`
2728
+ `)}function AC(n){let i=[];return i.push("Command History Statistics"),i.push("─".repeat(30)),i.push(`Total commands: ${n.total}`),i.push(`Successful: ${n.successful}`),i.push(`Failed: ${n.failed}`),i.push(`Success rate: ${(n.successful/n.total*100).toFixed(1)}%`),i.push(`Average duration: ${n.averageDuration.toFixed(0)}ms`),i.push(`Most used: ${n.mostUsed}`),i.join(`
2729
+ `)}class jm{deployments=new Map;async deploy(n,i){let s=this.generateDeploymentId(),o={id:s,regions:i.regions.map((c)=>({region:c.code,stackName:this.getStackName(n,c.code),status:"pending"})),status:"deploying",startTime:new Date};this.deployments.set(s,o);try{let c=i.regions.find((d)=>d.isPrimary)||i.regions[0];await this.deployToRegion(n,c,o);let u=i.regions.filter((d)=>d.code!==c.code);if(await Promise.all(u.map((d)=>this.deployToRegion(n,d,o))),i.globalResources)await this.deployGlobalResources(o,i);if(i.replication)await this.setupReplication(o,i);if(i.failover?.enabled)await this.setupFailover(o,i);return o.status="deployed",o.endTime=new Date,o}catch(c){throw o.status="failed",o.endTime=new Date,c}}async deployToRegion(n,i,s){let o=s.regions.find((c)=>c.region===i.code);if(!o)throw Error(`Region deployment not found: ${i.code}`);o.status="deploying",o.startTime=new Date;try{let c=this.createRegionConfig(n,i);await this.deployStack(o.stackName,c,i.code),o.status="deployed",o.endTime=new Date,o.outputs={stackId:`arn:aws:cloudformation:${i.code}:123456789012:stack/${o.stackName}/guid`,endpoint:`https://${o.stackName}.${i.code}.example.com`}}catch(c){throw o.status="failed",o.endTime=new Date,o.error=c instanceof Error?c.message:String(c),c}}async deployGlobalResources(n,i){let s={};if(i.globalResources?.route53)s.route53=await this.deployRoute53(n,i);if(i.globalResources?.cloudfront)s.cloudfront=await this.deployCloudFront(n,i);if(i.globalResources?.waf)s.waf=await this.deployWAF(n);n.globalResources=s}async deployRoute53(n,i){let s=[],o=[];for(let c of n.regions){if(c.status!=="deployed")continue;let u={id:`health-${c.region}`,endpoint:c.outputs?.endpoint,path:i.failover?.healthCheckPath||"/health",region:c.region};s.push(u);let d={name:"example.com",type:"A",region:c.region,setIdentifier:c.region,healthCheckId:u.id,resourceRecords:[c.outputs?.endpoint]};o.push(d)}return{healthChecks:s,recordSets:o,hostedZoneId:"Z1234567890ABC"}}async deployCloudFront(n,i){return{distributionId:"E1234567890ABC",domainName:"d1234567890abc.cloudfront.net",origins:n.regions.filter((o)=>o.status==="deployed").map((o,c)=>{let u=i.regions[c];return{id:`origin-${o.region}`,domainName:o.outputs?.endpoint,weight:u?.weight||100}}),status:"Deployed"}}async deployWAF(n){return{webAclId:"arn:aws:wafv2:us-east-1:123456789012:global/webacl/test/a1234567-b890-c123-d456-e789012345f6",webAclArn:"arn:aws:wafv2:us-east-1:123456789012:global/webacl/test/a1234567-b890-c123-d456-e789012345f6"}}async setupReplication(n,i){if(i.replication?.s3)await this.setupS3Replication(n);if(i.replication?.dynamodb)await this.setupDynamoDBReplication(n);if(i.replication?.secrets)await this.setupSecretsReplication(n)}async setupS3Replication(n){let i=n.regions.filter((s)=>s.status==="deployed");for(let s=0;s<i.length-1;s++){let o=i[s],c=i[s+1];console.log(`Setting up S3 replication: ${o.region} -> ${c.region}`)}}async setupDynamoDBReplication(n){let i=n.regions.filter((s)=>s.status==="deployed").map((s)=>s.region);console.log(`Setting up DynamoDB global table in regions: ${i.join(", ")}`)}async setupSecretsReplication(n){let i=n.regions.filter((s)=>s.status==="deployed").map((s)=>s.region);console.log(`Setting up Secrets Manager replication in regions: ${i.join(", ")}`)}async setupFailover(n,i){let s=n.regions.find((c,u)=>i.regions[u]?.isPrimary)||n.regions[0],o=n.regions.filter((c)=>c.region!==s.region);console.log(`Setting up failover: primary=${s.region}, secondary=${o.map((c)=>c.region).join(", ")}`)}async destroy(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);i.status="rolling-back";try{if(i.globalResources)await this.destroyGlobalResources(i.globalResources);await Promise.all(i.regions.map((s)=>this.destroyRegionStack(s))),this.deployments.delete(n)}catch(s){throw i.status="failed",s}}async destroyGlobalResources(n){if(n.waf)console.log("Destroying WAF resources");if(n.cloudfront)console.log("Destroying CloudFront distribution");if(n.route53)console.log("Destroying Route53 resources")}async destroyRegionStack(n){if(n.status!=="deployed")return;n.status="rolling-back";try{console.log(`Destroying stack ${n.stackName} in ${n.region}`),n.status="pending"}catch(i){throw n.status="failed",n.error=i instanceof Error?i.message:String(i),i}}getDeployment(n){return this.deployments.get(n)}listDeployments(){return Array.from(this.deployments.values())}getStackName(n,i){return`${n.project.slug}-${i}`}createRegionConfig(n,i){return{...n,infrastructure:{...n.infrastructure}}}async deployStack(n,i,s){console.log(`Deploying stack ${n} to ${s}`)}generateDeploymentId(){return`deploy-${Date.now()}-${Math.random().toString(36).substring(7)}`}}var yC=new jm;class zm{references=[];exports=new Map;addExport(n){let i=`${n.region}:${n.exportName}`;if(!this.exports.has(n.region))this.exports.set(n.region,[]);this.exports.get(n.region).push(n)}getExport(n,i){let s=this.exports.get(n);if(!s)return;return s.find((c)=>c.exportName===i)?.value}createReference(n,i,s,o){let c=`/cross-region/${n}/${s}/${o}`;return this.references.push({sourceRegion:n,targetRegion:i,resourceType:s,resourceId:o,value:c}),c}async resolveReference(n,i){let s=this.references.find((o)=>o.targetRegion===n&&o.value===i);if(!s)throw Error(`Reference not found: ${i}`);return`arn:aws:resource:${s.sourceRegion}:123456789012:${s.resourceType}/${s.resourceId}`}getReferencesForRegion(n){return this.references.filter((i)=>i.sourceRegion===n||i.targetRegion===n)}clear(){this.references=[],this.exports.clear()}}class Km{resources=new Map;register(n){this.resources.set(n.id,n)}get(n){return this.resources.get(n)}getByType(n){return Array.from(this.resources.values()).filter((i)=>i.type===n)}getCloudFrontDistributions(){return this.getByType("cloudfront")}getRoute53HostedZones(){return this.getByType("route53")}getWAFWebACLs(){return this.getByType("waf")}remove(n){this.resources.delete(n)}clear(){this.resources.clear()}}class Wm{pairs=[];addPair(n){this.pairs.push(n)}getPairedRegion(n){let i=this.pairs.find((s)=>s.primary===n||s.secondary===n);if(!i)return;return i.primary===n?i.secondary:i.primary}getAllPairs(){return[...this.pairs]}getReplicatedPairs(){return this.pairs.filter((n)=>n.replicationConfig)}getFailoverPairs(){return this.pairs.filter((n)=>n.failoverConfig?.automatic)}arePaired(n,i){return this.pairs.some((s)=>s.primary===n&&s.secondary===i||s.primary===i&&s.secondary===n)}clear(){this.pairs=[]}}class Jm{dependencies=[];addDependency(n){this.dependencies.push(n)}getDependencies(n,i){return this.dependencies.filter((s)=>s.dependentStack===n&&s.dependentRegion===i)}getDependents(n,i){return this.dependencies.filter((s)=>s.dependsOnStack===n&&s.dependsOnRegion===i)}hasDependencies(n,i){return this.getDependencies(n,i).length>0}getDeploymentOrder(n){let i=new Set,s=[],o=(c)=>{let u=`${c.name}:${c.region}`;if(i.has(u))return;i.add(u);let d=this.getDependencies(c.name,c.region);for(let p of d)o({name:p.dependsOnStack,region:p.dependsOnRegion});s.push(c)};for(let c of n)o(c);return s}detectCircularDependencies(){let n=new Set,i=new Set,s=(o,c)=>{let u=`${o}:${c}`;if(i.has(u))return!0;if(n.has(u))return!1;n.add(u),i.add(u);let d=this.getDependencies(o,c);for(let p of d)if(s(p.dependsOnStack,p.dependsOnRegion))return!0;return i.delete(u),!1};for(let o of this.dependencies)if(s(o.dependentStack,o.dependentRegion))return!0;return!1}clear(){this.dependencies=[]}}var SC=new zm,IC=new Km,bC=new Wm,CC=new Jm;var _e=[{code:"us-east-1",name:"US East (N. Virginia)",location:"Virginia, USA",launchYear:2006,availabilityZones:6,localZones:16,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1},compliance:["PCI-DSS","HIPAA","SOC","ISO","FedRAMP"]},{code:"us-east-2",name:"US East (Ohio)",location:"Ohio, USA",launchYear:2016,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1},compliance:["PCI-DSS","HIPAA","SOC","ISO"]},{code:"us-west-1",name:"US West (N. California)",location:"California, USA",launchYear:2009,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.1},compliance:["PCI-DSS","HIPAA","SOC","ISO"]},{code:"us-west-2",name:"US West (Oregon)",location:"Oregon, USA",launchYear:2011,availabilityZones:4,localZones:2,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1},compliance:["PCI-DSS","HIPAA","SOC","ISO"]},{code:"eu-west-1",name:"Europe (Ireland)",location:"Dublin, Ireland",launchYear:2007,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"standard",multiplier:1.05},compliance:["PCI-DSS","GDPR","SOC","ISO"]},{code:"eu-central-1",name:"Europe (Frankfurt)",location:"Frankfurt, Germany",launchYear:2014,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.1},compliance:["PCI-DSS","GDPR","SOC","ISO"]},{code:"ap-southeast-1",name:"Asia Pacific (Singapore)",location:"Singapore",launchYear:2010,availabilityZones:3,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.12},compliance:["PCI-DSS","SOC","ISO","MTCS"]},{code:"ap-northeast-1",name:"Asia Pacific (Tokyo)",location:"Tokyo, Japan",launchYear:2011,availabilityZones:4,services:{compute:!0,storage:!0,database:!0,networking:!0,ml:!0,analytics:!0},pricing:{tier:"premium",multiplier:1.15},compliance:["PCI-DSS","SOC","ISO"]}];function ts(n){return _e.find((i)=>i.code===n)}function EC(){return _e}function vC(n){let i=n.toLowerCase();return _e.filter((s)=>s.location.toLowerCase().includes(i))}function TC(n){return _e.filter((i)=>i.compliance.includes(n))}function wC(n){return _e.filter((i)=>i.pricing.tier===n)}function RC(n){return _e.some((i)=>i.code===n)}function DC(n){if(n.continent==="North America")return ts("us-east-1");if(n.continent==="Europe")return ts("eu-west-1");if(n.continent==="Asia")return ts("ap-southeast-1");return ts("us-east-1")}function PC(n){let i=[..._e];if(n.compliance)i=i.filter((s)=>n.compliance.every((o)=>s.compliance.includes(o)));if(n.requiredServices)i=i.filter((s)=>n.requiredServices.every((o)=>s.services[o]));if(n.pricingSensitive)i.sort((s,o)=>s.pricing.multiplier-o.pricing.multiplier);return i.slice(0,5)}function kC(n){let i=ts(n);if(!i)throw Error(`Invalid region: ${n}`);let s=[];for(let o of _e){if(o.code===n)continue;let c=Di(i,o),u=Ni(i,o);s.push({primary:i,secondary:o,distance:c,sameContinent:u})}return s.sort((o,c)=>{if(o.sameContinent!==c.sameContinent)return o.sameContinent?1:-1;return o.distance-c.distance}),s.slice(0,3)}function Di(n,i){let s={"North America":0,"South America":1,Europe:2,Asia:3,Africa:4,Oceania:5},o=Je(n.location),c=Je(i.location);return Math.abs((s[o]||0)-(s[c]||0))}function Ni(n,i){return Je(n.location)===Je(i.location)}function Je(n){if(n.includes("USA")||n.includes("Canada"))return"North America";if(n.includes("Europe")||n.includes("Ireland")||n.includes("Germany"))return"Europe";if(n.includes("Asia")||n.includes("Singapore")||n.includes("Japan"))return"Asia";if(n.includes("Brazil"))return"South America";if(n.includes("Australia"))return"Oceania";return"Unknown"}function qy(n){return`${n.name} (${n.code})`}function NC(n){return n.map((i)=>qy(i)).join(`
2730
+ `)}function BC(){let n={total:_e.length,byContinent:{},byPricingTier:{}};for(let i of _e){let s=Je(i.location);n.byContinent[s]=(n.byContinent[s]||0)+1,n.byPricingTier[i.pricing.tier]=(n.byPricingTier[i.pricing.tier]||0)+1}return n}class Xm{accounts=new Map;crossAccountRoles=[];accountMappings=[];registerAccount(n){this.accounts.set(n.id,n)}getAccount(n){return this.accounts.get(n)}getAccountByAlias(n){return Array.from(this.accounts.values()).find((i)=>i.alias===n)}listAccounts(){return Array.from(this.accounts.values())}getAccountsByRole(n){return Array.from(this.accounts.values()).filter((i)=>i.role===n)}createCrossAccountRole(n,i,s,o,c){let u={roleArn:`arn:aws:iam::${i}:role/${s}`,roleName:s,sourceAccountId:n,targetAccountId:i,permissions:o,externalId:c?.externalId,sessionDuration:c?.sessionDuration||3600};return this.crossAccountRoles.push(u),u}getAssumeRolePolicyDocument(n,i){let s={Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:`arn:aws:iam::${n}:root`},Action:"sts:AssumeRole"}]};if(i)s.Statement[0].Condition={StringEquals:{"sts:ExternalId":i}};return s}generateCrossAccountPolicy(n){return{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:n,Resource:"*"}]}}mapEnvironmentToAccount(n,i,s){this.accountMappings.push({environment:n,accountId:i,region:s})}getAccountForEnvironment(n){return this.accountMappings.find((i)=>i.environment===n)}async assumeRole(n,i,s){return console.log(`Assuming role: ${n} with session: ${i}`),{accessKeyId:"AKIAIOSFODNN7EXAMPLE",secretAccessKey:"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",sessionToken:"token",expiration:new Date(Date.now()+3600000)}}async getCredentialsForAccount(n){let i=this.accounts.get(n);if(!i)throw Error(`Account not found: ${n}`);if(i.assumeRoleArn){let s=await this.assumeRole(i.assumeRoleArn,`ts-cloud-${Date.now()}`);return{accessKeyId:s.accessKeyId,secretAccessKey:s.secretAccessKey,sessionToken:s.sessionToken}}throw Error("No credentials available for account")}listCrossAccountRoles(){return[...this.crossAccountRoles]}getCrossAccountRolesForAccount(n){return this.crossAccountRoles.filter((i)=>i.sourceAccountId===n||i.targetAccountId===n)}async validateAccountAccess(n){try{let i=await this.getCredentialsForAccount(n);return console.log(`Validating access to account: ${n}`),!0}catch{return!1}}async getConsolidatedBilling(){let n={};for(let s of this.accounts.values())n[s.id]=Math.random()*1000;return{totalCost:Object.values(n).reduce((s,o)=>s+o,0),byAccount:n}}clear(){this.accounts.clear(),this.crossAccountRoles=[],this.accountMappings=[]}}class Ym{organizationId;organizationalUnits=new Map;getOrganizationId(){return this.organizationId}setOrganizationId(n){this.organizationId=n}createOrganizationalUnit(n,i){let s={id:`ou-${Date.now()}`,name:n,parentId:i,accounts:[]};return this.organizationalUnits.set(s.id,s),s}getOrganizationalUnit(n){return this.organizationalUnits.get(n)}listOrganizationalUnits(){return Array.from(this.organizationalUnits.values())}addAccountToOU(n,i){let s=this.organizationalUnits.get(n);if(!s)throw Error(`Organizational unit not found: ${n}`);if(!s.accounts.includes(i))s.accounts.push(i)}removeAccountFromOU(n,i){let s=this.organizationalUnits.get(n);if(!s)throw Error(`Organizational unit not found: ${n}`);s.accounts=s.accounts.filter((o)=>o!==i)}getAccountsInOU(n){let i=this.organizationalUnits.get(n);if(!i)return[];return[...i.accounts]}applyServiceControlPolicy(n,i){return{id:`scp-${Date.now()}`,name:"Custom SCP",targetId:n,policyDocument:i}}clear(){this.organizationId=void 0,this.organizationalUnits.clear()}}var xC=new Xm,OC=new Ym;var jy={basic:{name:"Basic (3 Accounts)",description:"Simple structure for small teams",accounts:[{alias:"management",email:"aws+management@example.com",role:"management",ou:"root",description:"Management account for AWS Organizations"},{alias:"production",email:"aws+production@example.com",role:"production",ou:"workloads",description:"Production workloads"},{alias:"development",email:"aws+development@example.com",role:"development",ou:"workloads",description:"Development and testing"}],organizationalUnits:[{name:"root"},{name:"workloads",parent:"root"}]},standard:{name:"Standard (5 Accounts)",description:"Recommended for most organizations",accounts:[{alias:"management",email:"aws+management@example.com",role:"management",ou:"root",description:"Management account"},{alias:"security",email:"aws+security@example.com",role:"security",ou:"security",description:"Security tooling and audit logs"},{alias:"shared-services",email:"aws+shared@example.com",role:"shared-services",ou:"infrastructure",description:"Shared services (CI/CD, monitoring)"},{alias:"production",email:"aws+production@example.com",role:"production",ou:"workloads",description:"Production environment"},{alias:"staging",email:"aws+staging@example.com",role:"staging",ou:"workloads",description:"Staging environment"},{alias:"development",email:"aws+development@example.com",role:"development",ou:"workloads",description:"Development environment"}],organizationalUnits:[{name:"root"},{name:"security",parent:"root"},{name:"infrastructure",parent:"root"},{name:"workloads",parent:"root"}]},enterprise:{name:"Enterprise (7+ Accounts)",description:"For large organizations with strict compliance requirements",accounts:[{alias:"management",email:"aws+management@example.com",role:"management",ou:"root",description:"Management account"},{alias:"audit",email:"aws+audit@example.com",role:"security",ou:"security",description:"Audit and compliance"},{alias:"log-archive",email:"aws+logs@example.com",role:"security",ou:"security",description:"Centralized log storage"},{alias:"shared-services",email:"aws+shared@example.com",role:"shared-services",ou:"infrastructure",description:"Shared infrastructure"},{alias:"network",email:"aws+network@example.com",role:"shared-services",ou:"infrastructure",description:"Network infrastructure (Transit Gateway)"},{alias:"production",email:"aws+production@example.com",role:"production",ou:"production-ou",description:"Production workloads"},{alias:"staging",email:"aws+staging@example.com",role:"staging",ou:"non-production-ou",description:"Staging environment"},{alias:"development",email:"aws+development@example.com",role:"development",ou:"non-production-ou",description:"Development environment"}],organizationalUnits:[{name:"root"},{name:"security",parent:"root",policies:["deny-root-access"]},{name:"infrastructure",parent:"root"},{name:"production-ou",parent:"root",policies:["require-mfa"]},{name:"non-production-ou",parent:"root"}]}},_C={denyRootAccess:{name:"Deny Root User Access",description:"Prevent root user from performing any actions",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"DenyRootUser",Effect:"Deny",Action:"*",Resource:"*",Condition:{StringLike:{"aws:PrincipalArn":"arn:aws:iam::*:root"}}}]}},requireMFA:{name:"Require MFA for All Actions",description:"Require MFA for console and API access",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"RequireMFA",Effect:"Deny",Action:"*",Resource:"*",Condition:{BoolIfExists:{"aws:MultiFactorAuthPresent":"false"}}}]}},denyRegions:{name:"Deny Access to Non-Approved Regions",description:"Restrict operations to specific regions",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"DenyNonApprovedRegions",Effect:"Deny",NotAction:["iam:*","organizations:*","route53:*","cloudfront:*","support:*","s3:*"],Resource:"*",Condition:{StringNotEquals:{"aws:RequestedRegion":["us-east-1","us-west-2"]}}}]}},preventLeaving:{name:"Prevent Leaving Organization",description:"Prevent accounts from leaving the organization",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"PreventLeaving",Effect:"Deny",Action:"organizations:LeaveOrganization",Resource:"*"}]}},denyS3Unencrypted:{name:"Deny Unencrypted S3 Uploads",description:"Require encryption for all S3 uploads",policyDocument:{Version:"2012-10-17",Statement:[{Sid:"DenyUnencryptedS3Uploads",Effect:"Deny",Action:"s3:PutObject",Resource:"*",Condition:{StringNotEquals:{"s3:x-amz-server-side-encryption":["AES256","aws:kms"]}}}]}}},LC={deploymentRole:{name:"CrossAccountDeploymentRole",description:"Role for deploying infrastructure from CI/CD",permissions:["cloudformation:*","s3:*","ec2:*","ecs:*","lambda:*","iam:GetRole","iam:PassRole","logs:*","events:*"]},readOnlyRole:{name:"CrossAccountReadOnlyRole",description:"Read-only access for monitoring and auditing",permissions:["cloudformation:Describe*","cloudformation:List*","ec2:Describe*","ecs:Describe*","lambda:Get*","lambda:List*","s3:Get*","s3:List*","logs:Get*","logs:Describe*"]},securityAuditRole:{name:"CrossAccountSecurityAuditRole",description:"Security audit and compliance checks",permissions:["iam:Get*","iam:List*","iam:Generate*","access-analyzer:*","guardduty:Get*","guardduty:List*","securityhub:Get*","securityhub:List*","config:Describe*","config:Get*","config:List*"]},breakGlassRole:{name:"CrossAccountBreakGlassRole",description:"Emergency access role (use with caution)",permissions:["*"]}};function $C(n){return jy[n]}function MC(n,i){return{Type:"AWS::IAM::Role",Properties:{RoleName:n.roleName,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:`arn:aws:iam::${n.sourceAccountId}:root`},Action:"sts:AssumeRole",...n.externalId&&{Condition:{StringEquals:{"sts:ExternalId":n.externalId}}}}]},Policies:[{PolicyName:`${n.roleName}Policy`,PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:n.permissions,Resource:"*"}]}}],...i&&{ManagedPolicyArns:i},MaxSessionDuration:n.sessionDuration||3600,Tags:[{Key:"ManagedBy",Value:"TS-Cloud"},{Key:"SourceAccount",Value:n.sourceAccountId}]}}}function FC(n){let i=[],s=[],o=n.accounts.filter((y)=>y.role==="management");if(o.length===0)i.push("No management account defined");if(o.length>1)i.push("Multiple management accounts defined");let c=n.accounts.map((y)=>y.email),u=c.filter((y,h)=>c.indexOf(y)!==h);if(u.length>0)i.push(`Duplicate email addresses: ${u.join(", ")}`);let d=n.accounts.map((y)=>y.alias),p=d.filter((y,h)=>d.indexOf(y)!==h);if(p.length>0)i.push(`Duplicate aliases: ${p.join(", ")}`);if(!n.accounts.some((y)=>y.role==="security"))s.push("No dedicated security account - consider adding one for audit logs");if(n.accounts.length<3)s.push("Less than 3 accounts - consider separating environments");if(!n.accounts.some((y)=>y.role==="production"))s.push("No production account defined");return{valid:i.length===0,errors:i,warnings:s}}function UC(n){let i=[];if(i.push(`${n.name}`),i.push("─".repeat(n.name.length)),i.push(n.description),i.push(""),n.organizationalUnits){i.push("Organizational Units:");for(let s of n.organizationalUnits){let o=s.parent?" └─ ":" ";i.push(`${o}${s.name}`)}i.push("")}i.push("Accounts:");for(let s of n.accounts)i.push(` ${s.alias.padEnd(20)} ${s.role.padEnd(15)} ${s.email}`),i.push(` ${"".padEnd(20)} ${s.description}`),i.push("");return i.join(`
2731
+ `)}function QC(n={}){let{workflowName:i="Deploy",trigger:s="push",branches:o=["main"],environments:c=["production"],awsRegion:u="us-east-1",awsRole:d,bunVersion:p="latest",deployCommand:y="bun run cloud deploy",testCommand:h="bun test",buildCommand:b="bun run build"}=n,v=!!d;return`name: ${i}
2732
2732
 
2733
2733
  on:
2734
2734
  ${s}:
@@ -2797,7 +2797,7 @@ jobs:
2797
2797
 
2798
2798
  - name: Post-deployment tests
2799
2799
  run: bun run cloud test:smoke
2800
- `}function QC(n){let{environments:i,awsRegion:s="us-east-1",awsRole:o}=n,c=!!o;return`name: Multi-Environment Deploy
2800
+ `}function HC(n){let{environments:i,awsRegion:s="us-east-1",awsRole:o}=n,c=!!o;return`name: Multi-Environment Deploy
2801
2801
 
2802
2802
  on:
2803
2803
  push:
@@ -2853,7 +2853,7 @@ ${i.map((u,d)=>` ${d>0?"elif":"if"} [[ "\${{ github.ref }}" == "refs/he
2853
2853
 
2854
2854
  - name: Deploy
2855
2855
  run: bun run cloud deploy --env=\${{ needs.determine-environment.outputs.environment }}
2856
- `}function HC(n={}){let{awsRegion:i="us-east-1",awsRole:s,ttl:o=24}=n,c=!!s;return`name: PR Preview Environment
2856
+ `}function GC(n={}){let{awsRegion:i="us-east-1",awsRole:s,ttl:o=24}=n,c=!!s;return`name: PR Preview Environment
2857
2857
 
2858
2858
  on:
2859
2859
  pull_request:
@@ -2958,7 +2958,7 @@ jobs:
2958
2958
  bun run cloud env:preview --destroy \\
2959
2959
  --branch=\${{ github.head_ref }} \\
2960
2960
  --pr=\${{ github.event.pull_request.number }}
2961
- `}function GC(n){let{schedule:i,environment:s,awsRegion:o="us-east-1",awsRole:c}=n;return`name: Scheduled Deployment
2961
+ `}function VC(n){let{schedule:i,environment:s,awsRegion:o="us-east-1",awsRole:c}=n;return`name: Scheduled Deployment
2962
2962
 
2963
2963
  on:
2964
2964
  schedule:
@@ -3000,7 +3000,7 @@ jobs:
3000
3000
 
3001
3001
  - name: Deploy
3002
3002
  run: bun run cloud deploy --env=\${{ env.ENVIRONMENT }}
3003
- `}function VC(n){let{matrix:i,awsRole:s}=n,o=!!s;return`name: Matrix Deployment
3003
+ `}function qC(n){let{matrix:i,awsRole:s}=n,o=!!s;return`name: Matrix Deployment
3004
3004
 
3005
3005
  on:
3006
3006
  workflow_dispatch:
@@ -3047,7 +3047,7 @@ ${i.map((c)=>` - environment: ${c.environment}
3047
3047
 
3048
3048
  - name: Deploy to \${{ matrix.environment }} (\${{ matrix.region }})
3049
3049
  run: bun run cloud deploy --env=\${{ matrix.environment }} --region=\${{ matrix.region }}
3050
- `}function qC(n={}){let{stages:i=["test","build","deploy"],environments:s=["production"],awsRegion:o="us-east-1",dockerImage:c="oven/bun:latest",deployCommand:u="bun run cloud deploy",testCommand:d="bun test",buildCommand:p="bun run build"}=n;return`stages:
3050
+ `}function jC(n={}){let{stages:i=["test","build","deploy"],environments:s=["production"],awsRegion:o="us-east-1",dockerImage:c="oven/bun:latest",deployCommand:u="bun run cloud deploy",testCommand:d="bun test",buildCommand:p="bun run build"}=n;return`stages:
3051
3051
  ${i.map((y)=>` - ${y}`).join(`
3052
3052
  `)}
3053
3053
 
@@ -3095,7 +3095,7 @@ deploy:
3095
3095
  only:
3096
3096
  - main
3097
3097
  when: manual
3098
- `}function jC(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((c)=>`
3098
+ `}function zC(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((c)=>`
3099
3099
  deploy:${c.name}:
3100
3100
  stage: deploy
3101
3101
  script:
@@ -3136,7 +3136,7 @@ build:
3136
3136
  paths:
3137
3137
  - dist/
3138
3138
  ${o}
3139
- `}function zC(n={}){let{awsRegion:i="us-east-1",ttl:s=24}=n;return`stages:
3139
+ `}function KC(n={}){let{awsRegion:i="us-east-1",ttl:s=24}=n;return`stages:
3140
3140
  - build
3141
3141
  - deploy
3142
3142
  - cleanup
@@ -3181,7 +3181,7 @@ cleanup:preview:
3181
3181
  when: manual
3182
3182
  only:
3183
3183
  - merge_requests
3184
- `}function KC(n){let{environment:i,awsRegion:s="us-east-1"}=n;return`stages:
3184
+ `}function WC(n){let{environment:i,awsRegion:s="us-east-1"}=n;return`stages:
3185
3185
  - deploy
3186
3186
 
3187
3187
  variables:
@@ -3200,7 +3200,7 @@ deploy:scheduled:
3200
3200
  name: \${ENVIRONMENT}
3201
3201
  only:
3202
3202
  - schedules
3203
- `}function WC(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((c)=>`
3203
+ `}function JC(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((c)=>`
3204
3204
  deploy:${c}:
3205
3205
  stage: deploy
3206
3206
  script:
@@ -3221,7 +3221,7 @@ variables:
3221
3221
  default:
3222
3222
  image: oven/bun:latest
3223
3223
  ${o}
3224
- `}function JC(n={}){let{awsRegion:i="us-east-1",dockerImage:s="oven/bun:latest",deployCommand:o="bun run cloud deploy",testCommand:c="bun test",buildCommand:u="bun run build",workflows:d=!0}=n;return`version: 2.1
3224
+ `}function XC(n={}){let{awsRegion:i="us-east-1",dockerImage:s="oven/bun:latest",deployCommand:o="bun run cloud deploy",testCommand:c="bun test",buildCommand:u="bun run build",workflows:d=!0}=n;return`version: 2.1
3225
3225
 
3226
3226
  orbs:
3227
3227
  aws-cli: circleci/aws-cli@4.0
@@ -3304,7 +3304,7 @@ ${d?`workflows:
3304
3304
  branches:
3305
3305
  only: main
3306
3306
  `:""}
3307
- `}function XC(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((u)=>`
3307
+ `}function YC(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((u)=>`
3308
3308
  deploy-${u.name}:
3309
3309
  executor: bun-executor
3310
3310
  steps:
@@ -3380,7 +3380,7 @@ workflows:
3380
3380
  requires:
3381
3381
  - test
3382
3382
  ${c}
3383
- `}function YC(n){let{schedule:i,environment:s,awsRegion:o="us-east-1"}=n;return`version: 2.1
3383
+ `}function ZC(n){let{schedule:i,environment:s,awsRegion:o="us-east-1"}=n;return`version: 2.1
3384
3384
 
3385
3385
  orbs:
3386
3386
  aws-cli: circleci/aws-cli@4.0
@@ -3417,7 +3417,7 @@ workflows:
3417
3417
  only: main
3418
3418
  jobs:
3419
3419
  - deploy
3420
- `}function ZC(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((u)=>`
3420
+ `}function eE(n){let{environments:i,awsRegion:s="us-east-1"}=n,o=i.map((u)=>`
3421
3421
  deploy-${u}:
3422
3422
  executor: bun-executor
3423
3423
  steps:
@@ -3493,7 +3493,7 @@ workflows:
3493
3493
  requires:
3494
3494
  - test
3495
3495
  ${c}
3496
- `}function eE(n){let{regions:i,environment:s}=n,o=i.map((u)=>`
3496
+ `}function tE(n){let{regions:i,environment:s}=n,o=i.map((u)=>`
3497
3497
  deploy-${u.replace(/-/g,"_")}:
3498
3498
  executor: bun-executor
3499
3499
  environment:
@@ -3562,7 +3562,7 @@ workflows:
3562
3562
  requires:
3563
3563
  - test
3564
3564
  ${c}
3565
- `}class El{backupPlans=new Map;backupVaults=new Map;restoreJobs=new Map;continuousBackups=new Map;planCounter=0;restoreCounter=0;continuousBackupCounter=0;createVault(n){this.backupVaults.set(n.name,n)}getVault(n){return this.backupVaults.get(n)}createBackupPlan(n){let i=`backup-plan-${Date.now()}-${this.planCounter++}`,s={id:i,...n};return this.backupPlans.set(i,s),s}getBackupPlan(n){return this.backupPlans.get(n)}listBackupPlans(){return Array.from(this.backupPlans.values())}createRDSBackupPlan(n){let{dbInstanceArn:i,schedule:s="0 2 * * *",retentionDays:o=7,vaultName:c="default-vault"}=n;return this.createBackupPlan({name:"RDS Daily Backup",schedule:s,retentionDays:o,vaultName:c,resources:[{resourceArn:i,resourceType:"rds",region:"us-east-1"}],lifecycle:{moveTocoldStorageAfterDays:30,deleteAfterDays:o}})}createDynamoDBBackupPlan(n){let{tableArn:i,schedule:s="0 3 * * *",retentionDays:o=35,crossRegionCopy:c}=n;return this.createBackupPlan({name:"DynamoDB Daily Backup",schedule:s,retentionDays:o,vaultName:"dynamodb-vault",resources:[{resourceArn:i,resourceType:"dynamodb",region:"us-east-1"}],lifecycle:{deleteAfterDays:o},tags:c?{CrossRegionCopy:c.join(",")}:void 0})}createEFSBackupPlan(n){let{fileSystemArn:i,schedule:s="0 1 * * *",retentionDays:o=30}=n;return this.createBackupPlan({name:"EFS Daily Backup",schedule:s,retentionDays:o,vaultName:"efs-vault",resources:[{resourceArn:i,resourceType:"efs",region:"us-east-1"}],lifecycle:{deleteAfterDays:o}})}enableContinuousBackup(n,i=35){let s=`continuous-backup-${Date.now()}-${this.continuousBackupCounter++}`,o={id:s,resourceId:n,enabled:!0,retentionDays:i};return this.continuousBackups.set(s,o),o}getContinuousBackup(n){return this.continuousBackups.get(n)}enablePointInTimeRecovery(n,i){return{enabled:!0,earliestRestorableTime:new Date(Date.now()-604800000),latestRestorableTime:new Date}}async restoreFromBackup(n){let{backupId:i,resourceType:s,targetRegion:o}=n,c={id:`restore-${Date.now()}-${this.restoreCounter++}`,backupId:i,resourceType:s,status:"pending",startTime:new Date,targetRegion:o};return this.restoreJobs.set(c.id,c),setTimeout(()=>{c.status="running"},100),setTimeout(()=>{c.status="completed",c.endTime=new Date},1000),c}async restoreToPointInTime(n){let{sourceResourceArn:i,targetResourceName:s,restoreTime:o,resourceType:c}=n,u={id:`pitr-${Date.now()}-${this.restoreCounter++}`,backupId:`pitr-${o.getTime()}`,resourceType:c,status:"pending",startTime:new Date};return this.restoreJobs.set(u.id,u),console.log(`Restoring ${c} from ${i} to ${s} at ${o.toISOString()}`),setTimeout(()=>{u.status="completed",u.endTime=new Date},2000),u}getRestoreJob(n){return this.restoreJobs.get(n)}listRestoreJobs(){return Array.from(this.restoreJobs.values())}setupCrossRegionReplication(n){let{sourceVault:i,sourceRegion:s,targetRegions:o}=n;console.log("Setting up cross-region replication:"),console.log(` Source: ${i} in ${s}`),console.log(` Targets: ${o.join(", ")}`)}generateBackupVaultCF(n){return{Type:"AWS::Backup::BackupVault",Properties:{BackupVaultName:n.name,...n.encryptionKeyArn&&{EncryptionKeyArn:n.encryptionKeyArn},...n.accessPolicy&&{AccessPolicy:n.accessPolicy}}}}generateBackupPlanCF(n){return{Type:"AWS::Backup::BackupPlan",Properties:{BackupPlan:{BackupPlanName:n.name,BackupPlanRule:[{RuleName:"DailyBackup",TargetBackupVault:n.vaultName,ScheduleExpression:`cron(${n.schedule})`,StartWindowMinutes:60,CompletionWindowMinutes:120,Lifecycle:n.lifecycle?{...n.lifecycle.moveTocoldStorageAfterDays&&{MoveToColdStorageAfterDays:n.lifecycle.moveTocoldStorageAfterDays},...n.lifecycle.deleteAfterDays&&{DeleteAfterDays:n.lifecycle.deleteAfterDays}}:void 0}]},...n.tags&&{BackupPlanTags:n.tags}}}}generateBackupSelectionCF(n){return{Type:"AWS::Backup::BackupSelection",Properties:{BackupPlanId:{Ref:`BackupPlan${n.id}`},BackupSelection:{SelectionName:`${n.name}Selection`,IamRoleArn:"arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole",Resources:n.resources.map((i)=>i.resourceArn)}}}}clear(){this.backupPlans.clear(),this.backupVaults.clear(),this.restoreJobs.clear(),this.continuousBackups.clear(),this.planCounter=0,this.restoreCounter=0,this.continuousBackupCounter=0}}var jy=new El;class vl{drPlans=new Map;failoverTests=new Map;planCounter=0;testCounter=0;createDRPlan(n){let i=`dr-plan-${Date.now()}-${this.planCounter++}`,s={id:i,...n};return this.drPlans.set(i,s),s}createRDSDRPlan(n){let{primaryDbArn:i,secondaryDbArn:s,primaryRegion:o,secondaryRegion:c,rto:u=60,rpo:d=5}=n;return this.createDRPlan({name:"RDS Multi-Region DR",primaryRegion:o,secondaryRegion:c,rto:u,rpo:d,resources:[{resourceId:"primary-db",resourceType:"rds",primaryArn:i,secondaryArn:s,replicationEnabled:!0}],runbook:this.generateRDSRunbook(o,c),testSchedule:"0 0 1 * *"})}createDynamoDBDRPlan(n){let{tableArn:i,regions:s,rto:o=15,rpo:c=1}=n;return this.createDRPlan({name:"DynamoDB Global Tables DR",primaryRegion:s[0],secondaryRegion:s[1],rto:o,rpo:c,resources:[{resourceId:"dynamodb-table",resourceType:"dynamodb",primaryArn:i,replicationEnabled:!0}],runbook:this.generateDynamoDBRunbook(s)})}generateRDSRunbook(n,i){return{estimatedDuration:60,requiredApprovals:["cto","engineering-lead"],steps:[{order:1,name:"Verify Primary Database Failure",description:"Confirm that the primary database is truly unavailable and not experiencing temporary issues",action:"aws rds describe-db-instances --region "+n,automatable:!0,estimatedDuration:2,rollbackable:!1},{order:2,name:"Check Replication Lag",description:"Verify that the read replica is up to date",action:"Check ReplicaLag metric in CloudWatch",automatable:!0,estimatedDuration:1,rollbackable:!1},{order:3,name:"Promote Read Replica",description:"Promote the read replica in the secondary region to be the new primary",action:"aws rds promote-read-replica --db-instance-identifier replica --region "+i,automatable:!0,estimatedDuration:10,rollbackable:!1},{order:4,name:"Update DNS Records",description:"Update Route53 records to point to the new primary database",action:"Update Route53 failover record set",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:5,name:"Update Application Configuration",description:"Update application connection strings if needed",action:"Deploy configuration update to ECS/Lambda",automatable:!0,estimatedDuration:10,rollbackable:!0},{order:6,name:"Verify Application Connectivity",description:"Test that applications can connect to the new primary",action:"Run smoke tests",automatable:!0,estimatedDuration:5,rollbackable:!1},{order:7,name:"Monitor for Issues",description:"Monitor CloudWatch metrics and application logs",action:"Monitor for 30 minutes",automatable:!1,estimatedDuration:30,rollbackable:!1}]}}generateDynamoDBRunbook(n){return{estimatedDuration:15,steps:[{order:1,name:"Verify Primary Region Failure",description:"Confirm that the primary region is experiencing an outage",action:"Check AWS Health Dashboard",automatable:!0,estimatedDuration:2,rollbackable:!1},{order:2,name:"Update Route53 Failover",description:"Update Route53 to direct traffic to secondary region",action:"Update Route53 health check and failover records",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:3,name:"Update Application Endpoints",description:"Update Lambda/ECS to use secondary region DynamoDB endpoint",action:"Deploy configuration update",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:4,name:"Verify Data Consistency",description:"Verify that data is consistent in secondary region",action:"Run data validation queries",automatable:!0,estimatedDuration:3,rollbackable:!1}]}}async executeFailover(n,i=!1){let s=this.drPlans.get(n);if(!s)throw Error(`DR plan not found: ${n}`);let o=Date.now(),c=0;console.log(`${i?"[DRY RUN] ":""}Executing failover for plan: ${s.name}`),console.log(`Primary: ${s.primaryRegion} -> Secondary: ${s.secondaryRegion}`),console.log(`RTO: ${s.rto} minutes, RPO: ${s.rpo} minutes`),console.log("");for(let d of s.runbook.steps){if(console.log(`Step ${d.order}: ${d.name}`),console.log(` ${d.description}`),console.log(` Action: ${d.action}`),console.log(` Estimated: ${d.estimatedDuration} minutes`),i)console.log(" [SKIPPED - DRY RUN]");else if(d.automatable)console.log(" [AUTOMATED]");else console.log(" [MANUAL - WAITING]");c++,console.log("")}return{success:!0,duration:(Date.now()-o)/1000/60,completedSteps:c}}scheduleFailoverTest(n,i){let s={id:`failover-test-${Date.now()}-${this.testCounter++}`,planId:n,status:"scheduled",startTime:i};return this.failoverTests.set(s.id,s),s}async runFailoverTest(n){let i=this.drPlans.get(n);if(!i)throw Error(`DR plan not found: ${n}`);let s={id:`failover-test-${Date.now()}-${this.testCounter++}`,planId:n,status:"running",startTime:new Date,results:[]};this.failoverTests.set(s.id,s),console.log(`Running failover test for plan: ${i.name}`),console.log("This is a non-destructive test using test resources"),console.log("");for(let o of i.runbook.steps){let c=Date.now();console.log(`Testing step ${o.order}: ${o.name}`);let u={step:o.name,status:"success",duration:(Date.now()-c)/1000,message:`Successfully validated step ${o.order}`};s.results.push(u)}return s.status="completed",s.endTime=new Date,s}getDRPlan(n){return this.drPlans.get(n)}listDRPlans(){return Array.from(this.drPlans.values())}getFailoverTest(n){return this.failoverTests.get(n)}listFailoverTests(){return Array.from(this.failoverTests.values())}validateDRPlan(n){let i=[],s=[];if(n.rto<n.rpo)s.push("RTO cannot be less than RPO");if(n.rto>240)i.push("RTO exceeds 4 hours - consider improving recovery time");if(n.rpo>60)i.push("RPO exceeds 1 hour - consider more frequent backups");if(n.resources.length===0)s.push("No resources defined in DR plan");for(let u of n.resources){if(!u.replicationEnabled)i.push(`Resource ${u.resourceId} does not have replication enabled`);if(!u.secondaryArn&&u.resourceType!=="dynamodb")i.push(`Resource ${u.resourceId} does not have secondary resource defined`)}if(n.runbook.steps.length===0)s.push("No recovery steps defined in runbook");let o=n.runbook.steps.reduce((u,d)=>u+d.estimatedDuration,0);if(o>n.rto)i.push(`Estimated recovery duration (${o}m) exceeds RTO (${n.rto}m)`);let c=n.runbook.steps.filter((u)=>!u.automatable);if(c.length>0)i.push(`${c.length} manual steps in runbook - consider automation`);return{valid:s.length===0,warnings:i,errors:s}}clear(){this.drPlans.clear(),this.failoverTests.clear(),this.planCounter=0,this.testCounter=0}}var zy=new vl;class Tl{configRules=new Map;configRecorders=new Map;deliveryChannels=new Map;ruleCounter=0;createConfigRecorder(n){return this.configRecorders.set(n.name,n),n}createDeliveryChannel(n){return this.deliveryChannels.set(n.name,n),n}createConfigRule(n){let i=`config-rule-${Date.now()}-${this.ruleCounter++}`,s={id:i,...n};return this.configRules.set(i,s),s}createS3EncryptionRule(){return this.createConfigRule({name:"s3-bucket-server-side-encryption-enabled",description:"Checks that S3 buckets have server-side encryption enabled",source:"AWS_MANAGED",identifier:"S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createS3PublicAccessBlockRule(){return this.createConfigRule({name:"s3-bucket-public-read-prohibited",description:"Checks that S3 buckets do not allow public read access",source:"AWS_MANAGED",identifier:"S3_BUCKET_PUBLIC_READ_PROHIBITED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createS3VersioningRule(){return this.createConfigRule({name:"s3-bucket-versioning-enabled",description:"Checks whether versioning is enabled for S3 buckets",source:"AWS_MANAGED",identifier:"S3_BUCKET_VERSIONING_ENABLED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createRdsEncryptionRule(){return this.createConfigRule({name:"rds-storage-encrypted",description:"Checks whether storage encryption is enabled for RDS DB instances",source:"AWS_MANAGED",identifier:"RDS_STORAGE_ENCRYPTED",scope:{complianceResourceTypes:["AWS::RDS::DBInstance"]}})}createRdsSnapshotEncryptionRule(){return this.createConfigRule({name:"rds-snapshots-public-prohibited",description:"Checks if RDS snapshots are public",source:"AWS_MANAGED",identifier:"RDS_SNAPSHOTS_PUBLIC_PROHIBITED",scope:{complianceResourceTypes:["AWS::RDS::DBSnapshot","AWS::RDS::DBClusterSnapshot"]}})}createRdsBackupRule(n=7){return this.createConfigRule({name:"db-backup-enabled",description:"Checks whether RDS DB instances have backups enabled",source:"AWS_MANAGED",identifier:"DB_BACKUP_ENABLED",inputParameters:{backupRetentionPeriod:n},scope:{complianceResourceTypes:["AWS::RDS::DBInstance"]}})}createEc2InstanceProfileRule(){return this.createConfigRule({name:"ec2-instance-managed-by-systems-manager",description:"Checks if EC2 instances are managed by Systems Manager",source:"AWS_MANAGED",identifier:"EC2_INSTANCE_MANAGED_BY_SSM",scope:{complianceResourceTypes:["AWS::EC2::Instance"]}})}createEbsEncryptionRule(){return this.createConfigRule({name:"encrypted-volumes",description:"Checks whether EBS volumes are encrypted",source:"AWS_MANAGED",identifier:"ENCRYPTED_VOLUMES",scope:{complianceResourceTypes:["AWS::EC2::Volume"]}})}createIamPasswordPolicyRule(){return this.createConfigRule({name:"iam-password-policy",description:"Checks whether the IAM password policy meets specified requirements",source:"AWS_MANAGED",identifier:"IAM_PASSWORD_POLICY",inputParameters:{RequireUppercaseCharacters:!0,RequireLowercaseCharacters:!0,RequireSymbols:!0,RequireNumbers:!0,MinimumPasswordLength:14,PasswordReusePrevention:24,MaxPasswordAge:90}})}createIamMfaRule(){return this.createConfigRule({name:"iam-user-mfa-enabled",description:"Checks whether IAM users have MFA enabled",source:"AWS_MANAGED",identifier:"IAM_USER_MFA_ENABLED"})}createRootAccountMfaRule(){return this.createConfigRule({name:"root-account-mfa-enabled",description:"Checks whether the root account has MFA enabled",source:"AWS_MANAGED",identifier:"ROOT_ACCOUNT_MFA_ENABLED"})}createVpcFlowLogsRule(){return this.createConfigRule({name:"vpc-flow-logs-enabled",description:"Checks whether VPC Flow Logs is enabled",source:"AWS_MANAGED",identifier:"VPC_FLOW_LOGS_ENABLED",scope:{complianceResourceTypes:["AWS::EC2::VPC"]}})}createCloudTrailEnabledRule(){return this.createConfigRule({name:"cloudtrail-enabled",description:"Checks whether CloudTrail is enabled",source:"AWS_MANAGED",identifier:"CLOUD_TRAIL_ENABLED",maxExecutionFrequency:"TwentyFour_Hours"})}createCloudWatchAlarmRule(){return this.createConfigRule({name:"cloudwatch-alarm-action-check",description:"Checks whether CloudWatch alarms have actions configured",source:"AWS_MANAGED",identifier:"CLOUDWATCH_ALARM_ACTION_CHECK",inputParameters:{alarmActionRequired:!0,insufficientDataActionRequired:!1,okActionRequired:!1},scope:{complianceResourceTypes:["AWS::CloudWatch::Alarm"]}})}createCustomLambdaRule(n){return this.createConfigRule({name:n.name,description:n.description,source:"CUSTOM_LAMBDA",lambdaFunctionArn:n.lambdaFunctionArn,scope:n.resourceTypes?{complianceResourceTypes:n.resourceTypes}:void 0,maxExecutionFrequency:n.maxExecutionFrequency,inputParameters:n.inputParameters})}createCompliancePreset(n){let i=[];switch(n){case"hipaa":i.push(this.createS3EncryptionRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamPasswordPolicyRule(),this.createRdsBackupRule(7),this.createVpcFlowLogsRule());break;case"pci-dss":i.push(this.createS3EncryptionRule(),this.createS3PublicAccessBlockRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamPasswordPolicyRule(),this.createIamMfaRule(),this.createRootAccountMfaRule(),this.createVpcFlowLogsRule());break;case"sox":i.push(this.createS3VersioningRule(),this.createCloudTrailEnabledRule(),this.createRdsBackupRule(30),this.createIamPasswordPolicyRule());break;case"gdpr":i.push(this.createS3EncryptionRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createRdsSnapshotEncryptionRule());break;case"basic":i.push(this.createS3EncryptionRule(),this.createS3PublicAccessBlockRule(),this.createRdsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamMfaRule(),this.createRootAccountMfaRule());break}return i}getConfigRule(n){return this.configRules.get(n)}listConfigRules(){return Array.from(this.configRules.values())}getConfigRecorder(n){return this.configRecorders.get(n)}listConfigRecorders(){return Array.from(this.configRecorders.values())}getDeliveryChannel(n){return this.deliveryChannels.get(n)}listDeliveryChannels(){return Array.from(this.deliveryChannels.values())}generateConfigRuleCF(n){let i={Type:"AWS::Config::ConfigRule",Properties:{ConfigRuleName:n.name,Description:n.description,Source:{Owner:n.source==="AWS_MANAGED"?"AWS":"CUSTOM_LAMBDA"}}};if(n.source==="AWS_MANAGED"&&n.identifier)i.Properties.Source.SourceIdentifier=n.identifier;if(n.source==="CUSTOM_LAMBDA"&&n.lambdaFunctionArn)i.Properties.Source.SourceIdentifier=n.lambdaFunctionArn,i.Properties.Source.SourceDetails=[{EventSource:"aws.config",MessageType:"ConfigurationItemChangeNotification"}];if(n.inputParameters)i.Properties.InputParameters=JSON.stringify(n.inputParameters);if(n.scope){if(i.Properties.Scope={},n.scope.complianceResourceTypes)i.Properties.Scope.ComplianceResourceTypes=n.scope.complianceResourceTypes;if(n.scope.tagKey)i.Properties.Scope.TagKey=n.scope.tagKey;if(n.scope.tagValue)i.Properties.Scope.TagValue=n.scope.tagValue}if(n.maxExecutionFrequency)i.Properties.MaximumExecutionFrequency=n.maxExecutionFrequency;return i}generateConfigRecorderCF(n){return{Type:"AWS::Config::ConfigurationRecorder",Properties:{Name:n.name,RoleArn:n.roleArn,RecordingGroup:n.recordingGroup||{AllSupported:!0,IncludeGlobalResourceTypes:!0}}}}generateDeliveryChannelCF(n){return{Type:"AWS::Config::DeliveryChannel",Properties:{Name:n.name,S3BucketName:n.s3BucketName,...n.s3KeyPrefix&&{S3KeyPrefix:n.s3KeyPrefix},...n.snsTopicArn&&{SnsTopicARN:n.snsTopicArn},...n.configSnapshotDeliveryProperties&&{ConfigSnapshotDeliveryProperties:n.configSnapshotDeliveryProperties}}}}clear(){this.configRules.clear(),this.configRecorders.clear(),this.deliveryChannels.clear(),this.ruleCounter=0}}var Ky=new Tl;class wl{trails=new Map;trailCounter=0;createTrail(n){let i=`trail-${Date.now()}-${this.trailCounter++}`,s={id:i,...n};return this.trails.set(i,s),s}createOrganizationTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,s3KeyPrefix:"organization-trail",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,kmsKeyId:n.kmsKeyId,cloudWatchLogsLogGroupArn:n.cloudWatchLogsLogGroupArn,cloudWatchLogsRoleArn:n.cloudWatchLogsRoleArn})}createSecurityAuditTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,s3KeyPrefix:"security-audit",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,kmsKeyId:n.kmsKeyId,cloudWatchLogsLogGroupArn:n.cloudWatchLogsLogGroupArn,cloudWatchLogsRoleArn:n.cloudWatchLogsRoleArn,eventSelectors:[{readWriteType:"All",includeManagementEvents:!0,excludeManagementEventSources:[]}],insightSelectors:[{insightType:"ApiCallRateInsight"},{insightType:"ApiErrorRateInsight"}]})}createDataEventsTrail(n){let i=[];if(n.s3DataBuckets&&n.s3DataBuckets.length>0)i.push({type:"AWS::S3::Object",values:n.s3DataBuckets.map((s)=>`arn:aws:s3:::${s}/*`)});if(n.lambdaFunctions&&n.lambdaFunctions.length>0)i.push({type:"AWS::Lambda::Function",values:n.lambdaFunctions});return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,s3KeyPrefix:"data-events",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"All",includeManagementEvents:!1,dataResources:i}]})}createAdvancedTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,advancedEventSelectors:n.selectors})}createReadOnlyTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"ReadOnly",includeManagementEvents:!0}]})}createWriteOnlyTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"WriteOnly",includeManagementEvents:!0}]})}getTrail(n){return this.trails.get(n)}listTrails(){return Array.from(this.trails.values())}generateTrailCF(n){let i={Type:"AWS::CloudTrail::Trail",Properties:{TrailName:n.name,S3BucketName:n.s3BucketName,IsLogging:!0,IncludeGlobalServiceEvents:n.includeGlobalServiceEvents??!0,IsMultiRegionTrail:n.isMultiRegionTrail??!0,EnableLogFileValidation:n.enableLogFileValidation??!0}};if(n.s3KeyPrefix)i.Properties.S3KeyPrefix=n.s3KeyPrefix;if(n.cloudWatchLogsLogGroupArn)i.Properties.CloudWatchLogsLogGroupArn=n.cloudWatchLogsLogGroupArn;if(n.cloudWatchLogsRoleArn)i.Properties.CloudWatchLogsRoleArn=n.cloudWatchLogsRoleArn;if(n.snsTopicName)i.Properties.SnsTopicName=n.snsTopicName;if(n.kmsKeyId)i.Properties.KMSKeyId=n.kmsKeyId;if(n.eventSelectors)i.Properties.EventSelectors=n.eventSelectors.map((s)=>({ReadWriteType:s.readWriteType,IncludeManagementEvents:s.includeManagementEvents??!0,...s.dataResources&&{DataResources:s.dataResources.map((o)=>({Type:o.type,Values:o.values}))},...s.excludeManagementEventSources&&{ExcludeManagementEventSources:s.excludeManagementEventSources}}));if(n.insightSelectors)i.Properties.InsightSelectors=n.insightSelectors.map((s)=>({InsightType:s.insightType}));if(n.advancedEventSelectors)i.Properties.AdvancedEventSelectors=n.advancedEventSelectors.map((s)=>({Name:s.name,FieldSelectors:s.fieldSelectors.map((o)=>({Field:o.field,...o.equals&&{Equals:o.equals},...o.startsWith&&{StartsWith:o.startsWith},...o.endsWith&&{EndsWith:o.endsWith},...o.notEquals&&{NotEquals:o.notEquals},...o.notStartsWith&&{NotStartsWith:o.notStartsWith},...o.notEndsWith&&{NotEndsWith:o.notEndsWith}}))}));return i}generateBucketPolicy(n,i){return{Version:"2012-10-17",Statement:[{Sid:"AWSCloudTrailAclCheck",Effect:"Allow",Principal:{Service:"cloudtrail.amazonaws.com"},Action:"s3:GetBucketAcl",Resource:`arn:aws:s3:::${n}`},{Sid:"AWSCloudTrailWrite",Effect:"Allow",Principal:{Service:"cloudtrail.amazonaws.com"},Action:"s3:PutObject",Resource:i.map((s)=>`arn:aws:s3:::${n}/AWSLogs/${s}/*`),Condition:{StringEquals:{"s3:x-amz-acl":"bucket-owner-full-control"}}}]}}clear(){this.trails.clear(),this.trailCounter=0}}var Wy=new wl;class Rl{detectors=new Map;threatIntelSets=new Map;ipSets=new Map;filters=new Map;detectorCounter=0;threatIntelCounter=0;ipSetCounter=0;filterCounter=0;createDetector(n){let i=`detector-${Date.now()}-${this.detectorCounter++}`,s={id:i,...n};return this.detectors.set(i,s),s}createComprehensiveDetector(){return this.createDetector({enable:!0,findingPublishingFrequency:"FIFTEEN_MINUTES",dataSources:{s3Logs:{enable:!0},kubernetes:{auditLogs:{enable:!0}},malwareProtection:{scanEc2InstanceWithFindings:{ebsVolumes:{enable:!0}}}},features:[{name:"S3_DATA_EVENTS",status:"ENABLED"},{name:"EKS_AUDIT_LOGS",status:"ENABLED"},{name:"EBS_MALWARE_PROTECTION",status:"ENABLED"},{name:"RDS_LOGIN_EVENTS",status:"ENABLED"},{name:"LAMBDA_NETWORK_LOGS",status:"ENABLED"}]})}createBasicDetector(){return this.createDetector({enable:!0,findingPublishingFrequency:"SIX_HOURS"})}createThreatIntelSet(n){let i=`threat-intel-${Date.now()}-${this.threatIntelCounter++}`,s={id:i,...n};return this.threatIntelSets.set(i,s),s}createIPSet(n){let i=`ip-set-${Date.now()}-${this.ipSetCounter++}`,s={id:i,...n};return this.ipSets.set(i,s),s}createFindingFilter(n){let i=`filter-${Date.now()}-${this.filterCounter++}`,s={id:i,...n};return this.filters.set(i,s),s}createLowSeverityArchiveFilter(n){return this.createFindingFilter({detectorId:n,name:"archive-low-severity",description:"Automatically archive low severity findings",action:"ARCHIVE",rank:1,findingCriteria:{criterion:{severity:{lt:4}}}})}createFindingTypeFilter(n,i,s){return this.createFindingFilter({detectorId:n,name:`filter-finding-types-${s.toLowerCase()}`,description:`${s==="ARCHIVE"?"Archive":"Keep"} specific finding types`,action:s,rank:2,findingCriteria:{criterion:{type:{eq:i}}}})}createTrustedIPFilter(n,i){return this.createFindingFilter({detectorId:n,name:"trusted-ip-addresses",description:"Archive findings from trusted IP addresses",action:"ARCHIVE",rank:3,findingCriteria:{criterion:{"resource.instanceDetails.networkInterfaces.privateIpAddress":{eq:i}}}})}getDetector(n){return this.detectors.get(n)}listDetectors(){return Array.from(this.detectors.values())}getThreatIntelSet(n){return this.threatIntelSets.get(n)}listThreatIntelSets(){return Array.from(this.threatIntelSets.values())}getIPSet(n){return this.ipSets.get(n)}listIPSets(){return Array.from(this.ipSets.values())}getFindingFilter(n){return this.filters.get(n)}listFindingFilters(){return Array.from(this.filters.values())}generateDetectorCF(n){let i={Type:"AWS::GuardDuty::Detector",Properties:{Enable:n.enable}};if(n.findingPublishingFrequency)i.Properties.FindingPublishingFrequency=n.findingPublishingFrequency;if(n.dataSources){if(i.Properties.DataSources={},n.dataSources.s3Logs)i.Properties.DataSources.S3Logs={Enable:n.dataSources.s3Logs.enable};if(n.dataSources.kubernetes)i.Properties.DataSources.Kubernetes={AuditLogs:{Enable:n.dataSources.kubernetes.auditLogs.enable}};if(n.dataSources.malwareProtection)i.Properties.DataSources.MalwareProtection={ScanEc2InstanceWithFindings:{EbsVolumes:{Enable:n.dataSources.malwareProtection.scanEc2InstanceWithFindings.ebsVolumes.enable}}}}if(n.features)i.Properties.Features=n.features.map((s)=>({Name:s.name,Status:s.status,...s.additionalConfiguration&&{AdditionalConfiguration:s.additionalConfiguration}}));return i}generateThreatIntelSetCF(n){return{Type:"AWS::GuardDuty::ThreatIntelSet",Properties:{DetectorId:n.detectorId,Name:n.name,Format:n.format,Location:n.location,Activate:n.activate}}}generateIPSetCF(n){return{Type:"AWS::GuardDuty::IPSet",Properties:{DetectorId:n.detectorId,Name:n.name,Format:n.format,Location:n.location,Activate:n.activate}}}generateFilterCF(n){return{Type:"AWS::GuardDuty::Filter",Properties:{DetectorId:n.detectorId,Name:n.name,Description:n.description,Action:n.action,Rank:n.rank,FindingCriteria:{Criterion:n.findingCriteria.criterion}}}}clear(){this.detectors.clear(),this.threatIntelSets.clear(),this.ipSets.clear(),this.filters.clear(),this.detectorCounter=0,this.threatIntelCounter=0,this.ipSetCounter=0,this.filterCounter=0}}var Jy=new Rl;class mr{hubs=new Map;hubCounter=0;ruleCounter=0;static Standards={AWS_FOUNDATIONAL_SECURITY:{arn:"arn:aws:securityhub:::ruleset/aws-foundational-security-best-practices/v/1.0.0",name:"AWS Foundational Security Best Practices",description:"AWS recommended security best practices"},CIS_AWS_FOUNDATIONS_1_2:{arn:"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0",name:"CIS AWS Foundations Benchmark v1.2.0",description:"CIS AWS Foundations Benchmark v1.2.0"},CIS_AWS_FOUNDATIONS_1_4:{arn:"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.4.0",name:"CIS AWS Foundations Benchmark v1.4.0",description:"CIS AWS Foundations Benchmark v1.4.0"},PCI_DSS:{arn:"arn:aws:securityhub:us-east-1::standards/pci-dss/v/3.2.1",name:"PCI DSS v3.2.1",description:"Payment Card Industry Data Security Standard"},NIST_800_53:{arn:"arn:aws:securityhub:us-east-1::standards/nist-800-53/v/5.0.0",name:"NIST SP 800-53 Rev. 5",description:"NIST Special Publication 800-53 Revision 5"}};createHub(n){let i=`hub-${Date.now()}-${this.hubCounter++}`,s={id:i,...n};return this.hubs.set(i,s),s}createComprehensiveHub(){return this.createHub({enable:!0,controlFindingGenerator:"SECURITY_CONTROL",enableDefaultStandards:!0,standards:[{id:"aws-foundational",...mr.Standards.AWS_FOUNDATIONAL_SECURITY,enabled:!0},{id:"cis-1-4",...mr.Standards.CIS_AWS_FOUNDATIONS_1_4,enabled:!0},{id:"pci-dss",...mr.Standards.PCI_DSS,enabled:!0}]})}createBasicHub(){return this.createHub({enable:!0,controlFindingGenerator:"STANDARD_CONTROL",enableDefaultStandards:!0,standards:[{id:"aws-foundational",...mr.Standards.AWS_FOUNDATIONAL_SECURITY,enabled:!0}]})}createLowSeveritySuppressionRule(){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Suppress Low Severity Informational Findings",description:"Automatically suppress informational findings",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"SUPPRESSED"},note:{text:"Automatically suppressed low severity finding",updatedBy:"SecurityHub Automation"}}}],criteria:{severityLabel:[{value:"INFORMATIONAL",comparison:"EQUALS"}],recordState:[{value:"ACTIVE",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:1}}createResourceTypeNotificationRule(n){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Notify on Critical Resource Findings",description:"Set findings for critical resources to NOTIFIED status",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"NOTIFIED"},note:{text:"Critical resource finding requires attention",updatedBy:"SecurityHub Automation"}}}],criteria:{resourceType:n.map((i)=>({value:i,comparison:"EQUALS"})),severityLabel:[{value:"HIGH",comparison:"EQUALS"},{value:"CRITICAL",comparison:"EQUALS"}],workflowStatus:[{value:"NEW",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:2}}createComplianceFailureRule(){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Flag Compliance Failures",description:"Increase severity for compliance failures",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{severity:{label:"HIGH"},workflow:{status:"NOTIFIED"},note:{text:"Compliance failure detected - requires immediate attention",updatedBy:"SecurityHub Automation"}}}],criteria:{complianceStatus:[{value:"FAILED",comparison:"EQUALS"}],recordState:[{value:"ACTIVE",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:3}}createFalsePositiveSuppressionRule(n,i){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:`Suppress False Positives - ${n}`,description:`Automatically suppress known false positives from ${n}`,actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"SUPPRESSED"},note:{text:"Known false positive - automatically suppressed",updatedBy:"SecurityHub Automation"}}}],criteria:{productName:[{value:n,comparison:"EQUALS"}],title:i.map((s)=>({value:s,comparison:"PREFIX"}))},ruleStatus:"ENABLED",ruleOrder:10}}getHub(n){return this.hubs.get(n)}listHubs(){return Array.from(this.hubs.values())}generateHubCF(n){let i={Type:"AWS::SecurityHub::Hub",Properties:{}};if(n.controlFindingGenerator)i.Properties.ControlFindingGenerator=n.controlFindingGenerator;if(n.enableDefaultStandards!==void 0)i.Properties.EnableDefaultStandards=n.enableDefaultStandards;return i}generateStandardCF(n){let i={Type:"AWS::SecurityHub::Standard",Properties:{StandardsArn:n.arn}};if(n.disabledControls&&n.disabledControls.length>0)i.Properties.DisabledStandardsControls=n.disabledControls.map((s)=>({StandardsControlArn:s,Reason:"Disabled by configuration"}));return i}generateAutomationRuleCF(n){return{Type:"AWS::SecurityHub::AutomationRule",Properties:{RuleName:n.ruleName,Description:n.description,Actions:n.actions.map((i)=>({Type:i.type,FindingFieldsUpdate:i.findingFieldsUpdate})),Criteria:n.criteria,RuleStatus:n.ruleStatus,RuleOrder:n.ruleOrder}}}clear(){this.hubs.clear(),this.hubCounter=0,this.ruleCounter=0}}var Xy=new mr;class Dl{deployments=new Map;deploymentHistory=new Map;deploymentCounter=0;resultCounter=0;createDeployment(n){let i=`bg-deployment-${Date.now()}-${this.deploymentCounter++}`,s={id:i,...n};return this.deployments.set(i,s),s}createALBDeployment(n){return this.createDeployment({name:n.name,blueEnvironment:{name:"blue",targetGroupArn:n.blueTargetGroupArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:n.greenTargetGroupArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"alb",listenerArn:n.listenerArn,switchoverTimeSeconds:0},autoPromote:n.autoPromote,healthCheckConfig:n.healthCheckConfig})}createRoute53Deployment(n){return this.createDeployment({name:n.name,blueEnvironment:{name:"blue",targetGroupArn:n.blueTargetGroupArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:n.greenTargetGroupArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"route53",hostedZoneId:n.hostedZoneId,switchoverTimeSeconds:n.switchoverTimeSeconds||60}})}createECSDeployment(n){return this.createDeployment({name:n.name,blueEnvironment:{name:"blue",targetGroupArn:n.blueTargetGroupArn,taskDefinitionArn:n.blueTaskDefinitionArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:n.greenTargetGroupArn,taskDefinitionArn:n.greenTaskDefinitionArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"alb",listenerArn:n.listenerArn},autoRollback:n.autoRollback??!0})}async executeDeployment(n,i=!1){let s=this.deployments.get(n);if(!s)throw Error(`Deployment not found: ${n}`);let o={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,healthChecksPassed:!1,errors:[]};console.log(`${i?"[DRY RUN] ":""}Starting blue/green deployment: ${s.name}`),console.log(` Active environment: ${s.activeEnvironment}`),console.log(` Routing type: ${s.routingConfig.type}`);let c=s.activeEnvironment==="blue"?"green":"blue";if(console.log(` Switching to: ${c}`),console.log(`\\n1. Deploying to ${c} environment`),!i)await new Promise((u)=>setTimeout(u,100));if(console.log(`\\n2. Running health checks on ${c} environment`),s.healthCheckConfig){let u=await this.runHealthChecks(s,c,i);if(o.healthChecksPassed=u,!u){if(o.errors?.push("Health checks failed"),o.endTime=new Date,s.autoRollback)console.log(" Auto-rollback enabled - keeping current environment active"),o.rolledBackAt=new Date;return this.recordDeployment(n,o),o}}else o.healthChecksPassed=!0;if(console.log(`\\n3. Switching traffic to ${c} environment`),!i)s.activeEnvironment=c,o.switchedAt=new Date;if(console.log(`\\n4. Monitoring ${c} environment`),!i)await new Promise((u)=>setTimeout(u,100));return o.success=!0,o.endTime=new Date,console.log("\\n✓ Deployment completed successfully"),this.recordDeployment(n,o),o}async rollback(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);let s={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,healthChecksPassed:!0,errors:[]};console.log(`Rolling back deployment: ${i.name}`);let o=i.activeEnvironment==="blue"?"green":"blue";return i.activeEnvironment=o,s.success=!0,s.rolledBackAt=new Date,s.endTime=new Date,console.log(` Switched back to: ${o}`),this.recordDeployment(n,s),s}async runHealthChecks(n,i,s){let o=n.healthCheckConfig;if(console.log(` Health check path: ${o.path||"/"}`),console.log(` Healthy threshold: ${o.healthyThreshold}`),console.log(` Interval: ${o.interval}s`),s)return console.log(" [SKIPPED - DRY RUN]"),!0;let c=0,u=o.healthyThreshold+2;for(let d=0;d<u;d++)if(await new Promise((y)=>setTimeout(y,50)),Math.random()>0.1){if(c++,console.log(` Check ${d+1}: ✓ Healthy (${c}/${o.healthyThreshold})`),c>=o.healthyThreshold)return!0}else c=0,console.log(` Check ${d+1}: ✗ Unhealthy`);return!1}recordDeployment(n,i){if(!this.deploymentHistory.has(n))this.deploymentHistory.set(n,[]);this.deploymentHistory.get(n).push(i)}getDeployment(n){return this.deployments.get(n)}listDeployments(){return Array.from(this.deployments.values())}getDeploymentHistory(n){return this.deploymentHistory.get(n)||[]}generateALBListenerCF(n){let i=n.activeEnvironment==="blue"?n.blueEnvironment:n.greenEnvironment;return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:n.routingConfig.listenerArn,Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",TargetGroupArn:i.targetGroupArn}]}}}generateRoute53RecordSetCF(n,i){return[{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.routingConfig.hostedZoneId,Name:i,Type:"A",SetIdentifier:"blue",Weight:n.activeEnvironment==="blue"?100:0,AliasTarget:{HostedZoneId:n.routingConfig.hostedZoneId,DNSName:n.blueEnvironment.targetGroupArn,EvaluateTargetHealth:!0}}},{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.routingConfig.hostedZoneId,Name:i,Type:"A",SetIdentifier:"green",Weight:n.activeEnvironment==="green"?100:0,AliasTarget:{HostedZoneId:n.routingConfig.hostedZoneId,DNSName:n.greenEnvironment.targetGroupArn,EvaluateTargetHealth:!0}}}]}clear(){this.deployments.clear(),this.deploymentHistory.clear(),this.deploymentCounter=0,this.resultCounter=0}}var Yy=new Dl;class rs{deployments=new Map;deploymentHistory=new Map;deploymentCounter=0;resultCounter=0;static Strategies={CONSERVATIVE:[{name:"Initial Canary",trafficPercentage:10,durationMinutes:10},{name:"Quarter Traffic",trafficPercentage:25,durationMinutes:10},{name:"Half Traffic",trafficPercentage:50,durationMinutes:15},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],BALANCED:[{name:"Initial Canary",trafficPercentage:20,durationMinutes:5},{name:"Half Traffic",trafficPercentage:50,durationMinutes:10},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],AGGRESSIVE:[{name:"Half Traffic",trafficPercentage:50,durationMinutes:5},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],LINEAR_10:[{name:"Canary 10%",trafficPercentage:10,durationMinutes:5},{name:"Canary 20%",trafficPercentage:20,durationMinutes:5},{name:"Canary 30%",trafficPercentage:30,durationMinutes:5},{name:"Canary 40%",trafficPercentage:40,durationMinutes:5},{name:"Canary 50%",trafficPercentage:50,durationMinutes:5},{name:"Canary 60%",trafficPercentage:60,durationMinutes:5},{name:"Canary 70%",trafficPercentage:70,durationMinutes:5},{name:"Canary 80%",trafficPercentage:80,durationMinutes:5},{name:"Canary 90%",trafficPercentage:90,durationMinutes:5},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}]};createDeployment(n){let i=`canary-${Date.now()}-${this.deploymentCounter++}`,s={id:i,...n};return this.deployments.set(i,s),s}createLambdaCanaryDeployment(n){let i=n.strategy||"BALANCED",s=rs.Strategies[i].map((o)=>({...o,alarmThresholds:{errorRate:n.errorRateThreshold||1,latencyP99:n.latencyThreshold||1000}}));return this.createDeployment({name:n.name,baselineVersion:{version:"baseline",functionVersionArn:n.baselineVersionArn,weight:100},canaryVersion:{version:"canary",functionVersionArn:n.canaryVersionArn,weight:0},stages:s,currentStage:0,status:"pending",autoPromote:n.autoPromote??!0,autoRollback:!0})}createECSCanaryDeployment(n){let i=n.strategy||"CONSERVATIVE",s=rs.Strategies[i];return this.createDeployment({name:n.name,baselineVersion:{version:"baseline",taskDefinitionArn:n.baselineTaskDefinitionArn,targetGroupArn:n.baselineTargetGroupArn,weight:100},canaryVersion:{version:"canary",taskDefinitionArn:n.canaryTaskDefinitionArn,targetGroupArn:n.canaryTargetGroupArn,weight:0},stages:s,currentStage:0,status:"pending",autoRollback:!0})}async executeDeployment(n,i=!1){let s=this.deployments.get(n);if(!s)throw Error(`Deployment not found: ${n}`);let o={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,completedStages:0,rolledBack:!1};console.log(`${i?"[DRY RUN] ":""}Starting canary deployment: ${s.name}`),console.log(` Strategy: ${s.stages.length} stages`),console.log(` Auto-promote: ${s.autoPromote}`),console.log(` Auto-rollback: ${s.autoRollback}`),console.log(""),s.status="in_progress";for(let c=0;c<s.stages.length;c++){let u=s.stages[c];if(s.currentStage=c,console.log(`Stage ${c+1}/${s.stages.length}: ${u.name}`),console.log(` Traffic: ${u.trafficPercentage}% canary, ${100-u.trafficPercentage}% baseline`),console.log(` Duration: ${u.durationMinutes} minutes`),!i)s.baselineVersion.weight=100-u.trafficPercentage,s.canaryVersion.weight=u.trafficPercentage;if(!await this.monitorStage(s,u,i)){if(console.log(" ✗ Stage failed - metrics exceeded thresholds"),s.autoRollback)console.log("\\n Rolling back deployment..."),await this.rollback(n,i),o.rolledBack=!0,o.reason="Metrics exceeded thresholds";return o.endTime=new Date,s.status="rolled_back",this.recordDeployment(n,o),o}console.log(" ✓ Stage completed successfully"),o.completedStages++,console.log("")}return s.status="completed",o.success=!0,o.endTime=new Date,console.log("✓ Canary deployment completed successfully"),this.recordDeployment(n,o),o}async monitorStage(n,i,s){if(console.log(" Monitoring metrics..."),s)return console.log(" [SKIPPED - DRY RUN]"),!0;await new Promise((c)=>setTimeout(c,100));let o={baselineErrorRate:Math.random()*0.5,canaryErrorRate:Math.random()*0.8,baselineLatencyP99:200+Math.random()*100,canaryLatencyP99:180+Math.random()*150,baselineRequestCount:Math.floor(Math.random()*1000)+500,canaryRequestCount:Math.floor((Math.random()*1000+500)*i.trafficPercentage/100)};if(n.metrics=o,console.log(` Baseline: ${o.baselineErrorRate.toFixed(2)}% errors, ${o.baselineLatencyP99.toFixed(0)}ms P99`),console.log(` Canary: ${o.canaryErrorRate.toFixed(2)}% errors, ${o.canaryLatencyP99.toFixed(0)}ms P99`),i.alarmThresholds){let{errorRate:c,latencyP99:u}=i.alarmThresholds;if(c&&o.canaryErrorRate>c)return console.log(` ⚠ Error rate exceeded threshold: ${o.canaryErrorRate.toFixed(2)}% > ${c}%`),!1;if(u&&o.canaryLatencyP99>u)return console.log(` ⚠ Latency P99 exceeded threshold: ${o.canaryLatencyP99.toFixed(0)}ms > ${u}ms`),!1}return!0}async rollback(n,i=!1){let s=this.deployments.get(n);if(!s)throw Error(`Deployment not found: ${n}`);if(console.log(`${i?"[DRY RUN] ":""}Rolling back canary deployment: ${s.name}`),!i)s.baselineVersion.weight=100,s.canaryVersion.weight=0,s.status="rolled_back";console.log(" Traffic restored to baseline: 100%")}promoteCanary(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);console.log(`Promoting canary to baseline: ${i.name}`);let s=i.baselineVersion;i.baselineVersion=i.canaryVersion,i.canaryVersion=s,i.baselineVersion.weight=100,i.canaryVersion.weight=0,i.status="completed",console.log(" Canary promoted successfully")}recordDeployment(n,i){if(!this.deploymentHistory.has(n))this.deploymentHistory.set(n,[]);this.deploymentHistory.get(n).push(i)}getDeployment(n){return this.deployments.get(n)}listDeployments(){return Array.from(this.deployments.values())}getDeploymentHistory(n){return this.deploymentHistory.get(n)||[]}generateLambdaAliasCF(n,i){return{Type:"AWS::Lambda::Alias",Properties:{FunctionName:{Ref:"LambdaFunction"},Name:i,FunctionVersion:n.canaryVersion.version,RoutingConfig:{AdditionalVersionWeights:[{FunctionVersion:n.baselineVersion.version,FunctionWeight:n.baselineVersion.weight/100}]}}}}generateALBListenerRuleCF(n){return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:{Ref:"LoadBalancerListener"},Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",ForwardConfig:{TargetGroups:[{TargetGroupArn:n.baselineVersion.targetGroupArn,Weight:n.baselineVersion.weight},{TargetGroupArn:n.canaryVersion.targetGroupArn,Weight:n.canaryVersion.weight}],TargetGroupStickinessConfig:{Enabled:!1}}}]}}}clear(){this.deployments.clear(),this.deploymentHistory.clear(),this.deploymentCounter=0,this.resultCounter=0}}var Zy=new rs;class Pl{tests=new Map;testCounter=0;createTest(n){let i=`abtest-${Date.now()}-${this.testCounter++}`,s={id:i,...n};return this.tests.set(i,s),s}createSimpleABTest(n){let i=n.variantTrafficPercentage||50;return this.createTest({name:n.name,description:n.description,variants:[{id:"control",name:"Control",description:"Original version",trafficPercentage:100-i,targetGroupArn:n.controlTargetGroupArn,weight:100-i},{id:"variant-a",name:"Variant A",description:"Test version",trafficPercentage:i,targetGroupArn:n.variantTargetGroupArn,weight:i}],routingStrategy:{type:n.stickySession?"cookie":"random",cookieName:n.stickySession?"ab_variant":void 0,stickySession:n.stickySession??!1,sessionDuration:1440},startTime:new Date,status:"draft"})}createMultivariateTest(n){let i=n.variants.reduce((s,o)=>s+o.trafficPercentage,0);if(i!==100)throw Error(`Traffic percentages must sum to 100, got ${i}`);return this.createTest({name:n.name,description:n.description,variants:n.variants.map((s,o)=>({id:`variant-${o}`,name:s.name,description:s.description,trafficPercentage:s.trafficPercentage,targetGroupArn:s.targetGroupArn,weight:s.trafficPercentage})),routingStrategy:n.routingStrategy||{type:"random",stickySession:!1},startTime:new Date,status:"draft"})}createHeaderBasedTest(n){return this.createTest({name:n.name,description:`Route based on ${n.headerName} header`,variants:[{id:"control",name:"Control",trafficPercentage:50,targetGroupArn:n.controlTargetGroupArn,weight:50},{id:"variant-a",name:"Variant A",trafficPercentage:50,targetGroupArn:n.variantTargetGroupArn,weight:50}],routingStrategy:{type:"header",headerName:n.headerName,stickySession:!1},startTime:new Date,status:"draft"})}createGeoBasedTest(n){return this.createTest({name:n.name,description:"Route based on geographic location",variants:[{id:"control",name:"Control (Rest of World)",trafficPercentage:50,targetGroupArn:n.controlTargetGroupArn,weight:50},{id:"variant-a",name:`Variant A (${n.regions.join(", ")})`,trafficPercentage:50,targetGroupArn:n.variantTargetGroupArn,weight:50}],routingStrategy:{type:"geo",stickySession:!0,sessionDuration:1440},startTime:new Date,status:"draft"})}startTest(n){let i=this.tests.get(n);if(!i)throw Error(`Test not found: ${n}`);if(i.status!=="draft"&&i.status!=="paused")throw Error(`Cannot start test in ${i.status} status`);i.status="active",i.startTime=new Date,console.log(`Started A/B test: ${i.name}`),console.log(` Variants: ${i.variants.length}`),i.variants.forEach((s)=>{console.log(` - ${s.name}: ${s.trafficPercentage}%`)})}pauseTest(n){let i=this.tests.get(n);if(!i)throw Error(`Test not found: ${n}`);i.status="paused",console.log(`Paused A/B test: ${i.name}`)}updateTrafficSplit(n,i,s){let o=this.tests.get(n);if(!o)throw Error(`Test not found: ${n}`);let c=o.variants.find((d)=>d.id===i);if(!c)throw Error(`Variant not found: ${i}`);let u=c.trafficPercentage;c.trafficPercentage=s,c.weight=s,console.log(`Updated ${c.name} traffic: ${u}% → ${s}%`)}analyzeResults(n){let i=this.tests.get(n);if(!i)throw Error(`Test not found: ${n}`);if(!i.metrics)i.metrics=this.collectMetrics(i);let s=i.variants[0],o=0;for(let h of i.variants){let b=i.metrics.variants[h.id];if(b&&b.conversionRate>o)o=b.conversionRate,s=h}let c=i.metrics.variants.control||i.metrics.variants[i.variants[0].id],u=i.metrics.variants[s.id],d=(u.conversionRate-c.conversionRate)/c.conversionRate*100,p=100,y=u.requests>p&&c.requests>p&&Math.abs(d)>10;return{testId:n,winningVariant:s.name,confidence:y?95:75,improvement:d,statisticalSignificance:y,metrics:i.metrics,recommendation:this.generateRecommendation(d,y,s.name)}}declareWinner(n,i){let s=this.tests.get(n);if(!s)throw Error(`Test not found: ${n}`);let o=s.variants.find((c)=>c.id===i);if(!o)throw Error(`Variant not found: ${i}`);s.variants.forEach((c)=>{if(c.id===i)c.trafficPercentage=100,c.weight=100;else c.trafficPercentage=0,c.weight=0}),s.status="completed",s.endTime=new Date,s.winner=i,console.log(`Declared winner: ${o.name}`),console.log(` All traffic now routed to ${o.name}`)}collectMetrics(n){let i={},s=0;for(let o of n.variants){let c=Math.floor(Math.random()*1000)+500,u=Math.floor(c*(Math.random()*0.1+0.05)),d=u/c*100;i[o.id]={requests:c,conversions:u,conversionRate:d,averageLatency:150+Math.random()*100,errorRate:Math.random()*0.5,revenue:u*(Math.random()*50+100)},s+=c}return{variants:i,totalRequests:s,startTime:n.startTime,lastUpdated:new Date}}generateRecommendation(n,i,s){if(!i)return"Continue test - sample size too small or no significant difference detected";if(n>20)return`Strong winner detected - ${s} shows ${n.toFixed(1)}% improvement. Recommend deploying to all traffic.`;if(n>10)return`Moderate improvement - ${s} shows ${n.toFixed(1)}% improvement. Consider deploying.`;if(n>0)return`Minor improvement - ${s} shows ${n.toFixed(1)}% improvement. May not be worth the complexity.`;return"No improvement detected - consider reverting to control variant"}getTest(n){return this.tests.get(n)}listTests(){return Array.from(this.tests.values())}generateALBListenerRuleCF(n){return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:{Ref:"LoadBalancerListener"},Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",ForwardConfig:{TargetGroups:n.variants.map((i)=>({TargetGroupArn:i.targetGroupArn,Weight:i.weight})),TargetGroupStickinessConfig:{Enabled:n.routingStrategy.stickySession||!1,DurationSeconds:n.routingStrategy.sessionDuration?n.routingStrategy.sessionDuration*60:void 0}}}]}}}generateLambdaEdgeFunction(n){return`'use strict';
3565
+ `}class El{backupPlans=new Map;backupVaults=new Map;restoreJobs=new Map;continuousBackups=new Map;planCounter=0;restoreCounter=0;continuousBackupCounter=0;createVault(n){this.backupVaults.set(n.name,n)}getVault(n){return this.backupVaults.get(n)}createBackupPlan(n){let i=`backup-plan-${Date.now()}-${this.planCounter++}`,s={id:i,...n};return this.backupPlans.set(i,s),s}getBackupPlan(n){return this.backupPlans.get(n)}listBackupPlans(){return Array.from(this.backupPlans.values())}createRDSBackupPlan(n){let{dbInstanceArn:i,schedule:s="0 2 * * *",retentionDays:o=7,vaultName:c="default-vault"}=n;return this.createBackupPlan({name:"RDS Daily Backup",schedule:s,retentionDays:o,vaultName:c,resources:[{resourceArn:i,resourceType:"rds",region:"us-east-1"}],lifecycle:{moveTocoldStorageAfterDays:30,deleteAfterDays:o}})}createDynamoDBBackupPlan(n){let{tableArn:i,schedule:s="0 3 * * *",retentionDays:o=35,crossRegionCopy:c}=n;return this.createBackupPlan({name:"DynamoDB Daily Backup",schedule:s,retentionDays:o,vaultName:"dynamodb-vault",resources:[{resourceArn:i,resourceType:"dynamodb",region:"us-east-1"}],lifecycle:{deleteAfterDays:o},tags:c?{CrossRegionCopy:c.join(",")}:void 0})}createEFSBackupPlan(n){let{fileSystemArn:i,schedule:s="0 1 * * *",retentionDays:o=30}=n;return this.createBackupPlan({name:"EFS Daily Backup",schedule:s,retentionDays:o,vaultName:"efs-vault",resources:[{resourceArn:i,resourceType:"efs",region:"us-east-1"}],lifecycle:{deleteAfterDays:o}})}enableContinuousBackup(n,i=35){let s=`continuous-backup-${Date.now()}-${this.continuousBackupCounter++}`,o={id:s,resourceId:n,enabled:!0,retentionDays:i};return this.continuousBackups.set(s,o),o}getContinuousBackup(n){return this.continuousBackups.get(n)}enablePointInTimeRecovery(n,i){return{enabled:!0,earliestRestorableTime:new Date(Date.now()-604800000),latestRestorableTime:new Date}}async restoreFromBackup(n){let{backupId:i,resourceType:s,targetRegion:o}=n,c={id:`restore-${Date.now()}-${this.restoreCounter++}`,backupId:i,resourceType:s,status:"pending",startTime:new Date,targetRegion:o};return this.restoreJobs.set(c.id,c),setTimeout(()=>{c.status="running"},100),setTimeout(()=>{c.status="completed",c.endTime=new Date},1000),c}async restoreToPointInTime(n){let{sourceResourceArn:i,targetResourceName:s,restoreTime:o,resourceType:c}=n,u={id:`pitr-${Date.now()}-${this.restoreCounter++}`,backupId:`pitr-${o.getTime()}`,resourceType:c,status:"pending",startTime:new Date};return this.restoreJobs.set(u.id,u),console.log(`Restoring ${c} from ${i} to ${s} at ${o.toISOString()}`),setTimeout(()=>{u.status="completed",u.endTime=new Date},2000),u}getRestoreJob(n){return this.restoreJobs.get(n)}listRestoreJobs(){return Array.from(this.restoreJobs.values())}setupCrossRegionReplication(n){let{sourceVault:i,sourceRegion:s,targetRegions:o}=n;console.log("Setting up cross-region replication:"),console.log(` Source: ${i} in ${s}`),console.log(` Targets: ${o.join(", ")}`)}generateBackupVaultCF(n){return{Type:"AWS::Backup::BackupVault",Properties:{BackupVaultName:n.name,...n.encryptionKeyArn&&{EncryptionKeyArn:n.encryptionKeyArn},...n.accessPolicy&&{AccessPolicy:n.accessPolicy}}}}generateBackupPlanCF(n){return{Type:"AWS::Backup::BackupPlan",Properties:{BackupPlan:{BackupPlanName:n.name,BackupPlanRule:[{RuleName:"DailyBackup",TargetBackupVault:n.vaultName,ScheduleExpression:`cron(${n.schedule})`,StartWindowMinutes:60,CompletionWindowMinutes:120,Lifecycle:n.lifecycle?{...n.lifecycle.moveTocoldStorageAfterDays&&{MoveToColdStorageAfterDays:n.lifecycle.moveTocoldStorageAfterDays},...n.lifecycle.deleteAfterDays&&{DeleteAfterDays:n.lifecycle.deleteAfterDays}}:void 0}]},...n.tags&&{BackupPlanTags:n.tags}}}}generateBackupSelectionCF(n){return{Type:"AWS::Backup::BackupSelection",Properties:{BackupPlanId:{Ref:`BackupPlan${n.id}`},BackupSelection:{SelectionName:`${n.name}Selection`,IamRoleArn:"arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole",Resources:n.resources.map((i)=>i.resourceArn)}}}}clear(){this.backupPlans.clear(),this.backupVaults.clear(),this.restoreJobs.clear(),this.continuousBackups.clear(),this.planCounter=0,this.restoreCounter=0,this.continuousBackupCounter=0}}var zy=new El;class vl{drPlans=new Map;failoverTests=new Map;planCounter=0;testCounter=0;createDRPlan(n){let i=`dr-plan-${Date.now()}-${this.planCounter++}`,s={id:i,...n};return this.drPlans.set(i,s),s}createRDSDRPlan(n){let{primaryDbArn:i,secondaryDbArn:s,primaryRegion:o,secondaryRegion:c,rto:u=60,rpo:d=5}=n;return this.createDRPlan({name:"RDS Multi-Region DR",primaryRegion:o,secondaryRegion:c,rto:u,rpo:d,resources:[{resourceId:"primary-db",resourceType:"rds",primaryArn:i,secondaryArn:s,replicationEnabled:!0}],runbook:this.generateRDSRunbook(o,c),testSchedule:"0 0 1 * *"})}createDynamoDBDRPlan(n){let{tableArn:i,regions:s,rto:o=15,rpo:c=1}=n;return this.createDRPlan({name:"DynamoDB Global Tables DR",primaryRegion:s[0],secondaryRegion:s[1],rto:o,rpo:c,resources:[{resourceId:"dynamodb-table",resourceType:"dynamodb",primaryArn:i,replicationEnabled:!0}],runbook:this.generateDynamoDBRunbook(s)})}generateRDSRunbook(n,i){return{estimatedDuration:60,requiredApprovals:["cto","engineering-lead"],steps:[{order:1,name:"Verify Primary Database Failure",description:"Confirm that the primary database is truly unavailable and not experiencing temporary issues",action:"aws rds describe-db-instances --region "+n,automatable:!0,estimatedDuration:2,rollbackable:!1},{order:2,name:"Check Replication Lag",description:"Verify that the read replica is up to date",action:"Check ReplicaLag metric in CloudWatch",automatable:!0,estimatedDuration:1,rollbackable:!1},{order:3,name:"Promote Read Replica",description:"Promote the read replica in the secondary region to be the new primary",action:"aws rds promote-read-replica --db-instance-identifier replica --region "+i,automatable:!0,estimatedDuration:10,rollbackable:!1},{order:4,name:"Update DNS Records",description:"Update Route53 records to point to the new primary database",action:"Update Route53 failover record set",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:5,name:"Update Application Configuration",description:"Update application connection strings if needed",action:"Deploy configuration update to ECS/Lambda",automatable:!0,estimatedDuration:10,rollbackable:!0},{order:6,name:"Verify Application Connectivity",description:"Test that applications can connect to the new primary",action:"Run smoke tests",automatable:!0,estimatedDuration:5,rollbackable:!1},{order:7,name:"Monitor for Issues",description:"Monitor CloudWatch metrics and application logs",action:"Monitor for 30 minutes",automatable:!1,estimatedDuration:30,rollbackable:!1}]}}generateDynamoDBRunbook(n){return{estimatedDuration:15,steps:[{order:1,name:"Verify Primary Region Failure",description:"Confirm that the primary region is experiencing an outage",action:"Check AWS Health Dashboard",automatable:!0,estimatedDuration:2,rollbackable:!1},{order:2,name:"Update Route53 Failover",description:"Update Route53 to direct traffic to secondary region",action:"Update Route53 health check and failover records",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:3,name:"Update Application Endpoints",description:"Update Lambda/ECS to use secondary region DynamoDB endpoint",action:"Deploy configuration update",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:4,name:"Verify Data Consistency",description:"Verify that data is consistent in secondary region",action:"Run data validation queries",automatable:!0,estimatedDuration:3,rollbackable:!1}]}}async executeFailover(n,i=!1){let s=this.drPlans.get(n);if(!s)throw Error(`DR plan not found: ${n}`);let o=Date.now(),c=0;console.log(`${i?"[DRY RUN] ":""}Executing failover for plan: ${s.name}`),console.log(`Primary: ${s.primaryRegion} -> Secondary: ${s.secondaryRegion}`),console.log(`RTO: ${s.rto} minutes, RPO: ${s.rpo} minutes`),console.log("");for(let d of s.runbook.steps){if(console.log(`Step ${d.order}: ${d.name}`),console.log(` ${d.description}`),console.log(` Action: ${d.action}`),console.log(` Estimated: ${d.estimatedDuration} minutes`),i)console.log(" [SKIPPED - DRY RUN]");else if(d.automatable)console.log(" [AUTOMATED]");else console.log(" [MANUAL - WAITING]");c++,console.log("")}return{success:!0,duration:(Date.now()-o)/1000/60,completedSteps:c}}scheduleFailoverTest(n,i){let s={id:`failover-test-${Date.now()}-${this.testCounter++}`,planId:n,status:"scheduled",startTime:i};return this.failoverTests.set(s.id,s),s}async runFailoverTest(n){let i=this.drPlans.get(n);if(!i)throw Error(`DR plan not found: ${n}`);let s={id:`failover-test-${Date.now()}-${this.testCounter++}`,planId:n,status:"running",startTime:new Date,results:[]};this.failoverTests.set(s.id,s),console.log(`Running failover test for plan: ${i.name}`),console.log("This is a non-destructive test using test resources"),console.log("");for(let o of i.runbook.steps){let c=Date.now();console.log(`Testing step ${o.order}: ${o.name}`);let u={step:o.name,status:"success",duration:(Date.now()-c)/1000,message:`Successfully validated step ${o.order}`};s.results.push(u)}return s.status="completed",s.endTime=new Date,s}getDRPlan(n){return this.drPlans.get(n)}listDRPlans(){return Array.from(this.drPlans.values())}getFailoverTest(n){return this.failoverTests.get(n)}listFailoverTests(){return Array.from(this.failoverTests.values())}validateDRPlan(n){let i=[],s=[];if(n.rto<n.rpo)s.push("RTO cannot be less than RPO");if(n.rto>240)i.push("RTO exceeds 4 hours - consider improving recovery time");if(n.rpo>60)i.push("RPO exceeds 1 hour - consider more frequent backups");if(n.resources.length===0)s.push("No resources defined in DR plan");for(let u of n.resources){if(!u.replicationEnabled)i.push(`Resource ${u.resourceId} does not have replication enabled`);if(!u.secondaryArn&&u.resourceType!=="dynamodb")i.push(`Resource ${u.resourceId} does not have secondary resource defined`)}if(n.runbook.steps.length===0)s.push("No recovery steps defined in runbook");let o=n.runbook.steps.reduce((u,d)=>u+d.estimatedDuration,0);if(o>n.rto)i.push(`Estimated recovery duration (${o}m) exceeds RTO (${n.rto}m)`);let c=n.runbook.steps.filter((u)=>!u.automatable);if(c.length>0)i.push(`${c.length} manual steps in runbook - consider automation`);return{valid:s.length===0,warnings:i,errors:s}}clear(){this.drPlans.clear(),this.failoverTests.clear(),this.planCounter=0,this.testCounter=0}}var Ky=new vl;class Tl{configRules=new Map;configRecorders=new Map;deliveryChannels=new Map;ruleCounter=0;createConfigRecorder(n){return this.configRecorders.set(n.name,n),n}createDeliveryChannel(n){return this.deliveryChannels.set(n.name,n),n}createConfigRule(n){let i=`config-rule-${Date.now()}-${this.ruleCounter++}`,s={id:i,...n};return this.configRules.set(i,s),s}createS3EncryptionRule(){return this.createConfigRule({name:"s3-bucket-server-side-encryption-enabled",description:"Checks that S3 buckets have server-side encryption enabled",source:"AWS_MANAGED",identifier:"S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createS3PublicAccessBlockRule(){return this.createConfigRule({name:"s3-bucket-public-read-prohibited",description:"Checks that S3 buckets do not allow public read access",source:"AWS_MANAGED",identifier:"S3_BUCKET_PUBLIC_READ_PROHIBITED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createS3VersioningRule(){return this.createConfigRule({name:"s3-bucket-versioning-enabled",description:"Checks whether versioning is enabled for S3 buckets",source:"AWS_MANAGED",identifier:"S3_BUCKET_VERSIONING_ENABLED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createRdsEncryptionRule(){return this.createConfigRule({name:"rds-storage-encrypted",description:"Checks whether storage encryption is enabled for RDS DB instances",source:"AWS_MANAGED",identifier:"RDS_STORAGE_ENCRYPTED",scope:{complianceResourceTypes:["AWS::RDS::DBInstance"]}})}createRdsSnapshotEncryptionRule(){return this.createConfigRule({name:"rds-snapshots-public-prohibited",description:"Checks if RDS snapshots are public",source:"AWS_MANAGED",identifier:"RDS_SNAPSHOTS_PUBLIC_PROHIBITED",scope:{complianceResourceTypes:["AWS::RDS::DBSnapshot","AWS::RDS::DBClusterSnapshot"]}})}createRdsBackupRule(n=7){return this.createConfigRule({name:"db-backup-enabled",description:"Checks whether RDS DB instances have backups enabled",source:"AWS_MANAGED",identifier:"DB_BACKUP_ENABLED",inputParameters:{backupRetentionPeriod:n},scope:{complianceResourceTypes:["AWS::RDS::DBInstance"]}})}createEc2InstanceProfileRule(){return this.createConfigRule({name:"ec2-instance-managed-by-systems-manager",description:"Checks if EC2 instances are managed by Systems Manager",source:"AWS_MANAGED",identifier:"EC2_INSTANCE_MANAGED_BY_SSM",scope:{complianceResourceTypes:["AWS::EC2::Instance"]}})}createEbsEncryptionRule(){return this.createConfigRule({name:"encrypted-volumes",description:"Checks whether EBS volumes are encrypted",source:"AWS_MANAGED",identifier:"ENCRYPTED_VOLUMES",scope:{complianceResourceTypes:["AWS::EC2::Volume"]}})}createIamPasswordPolicyRule(){return this.createConfigRule({name:"iam-password-policy",description:"Checks whether the IAM password policy meets specified requirements",source:"AWS_MANAGED",identifier:"IAM_PASSWORD_POLICY",inputParameters:{RequireUppercaseCharacters:!0,RequireLowercaseCharacters:!0,RequireSymbols:!0,RequireNumbers:!0,MinimumPasswordLength:14,PasswordReusePrevention:24,MaxPasswordAge:90}})}createIamMfaRule(){return this.createConfigRule({name:"iam-user-mfa-enabled",description:"Checks whether IAM users have MFA enabled",source:"AWS_MANAGED",identifier:"IAM_USER_MFA_ENABLED"})}createRootAccountMfaRule(){return this.createConfigRule({name:"root-account-mfa-enabled",description:"Checks whether the root account has MFA enabled",source:"AWS_MANAGED",identifier:"ROOT_ACCOUNT_MFA_ENABLED"})}createVpcFlowLogsRule(){return this.createConfigRule({name:"vpc-flow-logs-enabled",description:"Checks whether VPC Flow Logs is enabled",source:"AWS_MANAGED",identifier:"VPC_FLOW_LOGS_ENABLED",scope:{complianceResourceTypes:["AWS::EC2::VPC"]}})}createCloudTrailEnabledRule(){return this.createConfigRule({name:"cloudtrail-enabled",description:"Checks whether CloudTrail is enabled",source:"AWS_MANAGED",identifier:"CLOUD_TRAIL_ENABLED",maxExecutionFrequency:"TwentyFour_Hours"})}createCloudWatchAlarmRule(){return this.createConfigRule({name:"cloudwatch-alarm-action-check",description:"Checks whether CloudWatch alarms have actions configured",source:"AWS_MANAGED",identifier:"CLOUDWATCH_ALARM_ACTION_CHECK",inputParameters:{alarmActionRequired:!0,insufficientDataActionRequired:!1,okActionRequired:!1},scope:{complianceResourceTypes:["AWS::CloudWatch::Alarm"]}})}createCustomLambdaRule(n){return this.createConfigRule({name:n.name,description:n.description,source:"CUSTOM_LAMBDA",lambdaFunctionArn:n.lambdaFunctionArn,scope:n.resourceTypes?{complianceResourceTypes:n.resourceTypes}:void 0,maxExecutionFrequency:n.maxExecutionFrequency,inputParameters:n.inputParameters})}createCompliancePreset(n){let i=[];switch(n){case"hipaa":i.push(this.createS3EncryptionRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamPasswordPolicyRule(),this.createRdsBackupRule(7),this.createVpcFlowLogsRule());break;case"pci-dss":i.push(this.createS3EncryptionRule(),this.createS3PublicAccessBlockRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamPasswordPolicyRule(),this.createIamMfaRule(),this.createRootAccountMfaRule(),this.createVpcFlowLogsRule());break;case"sox":i.push(this.createS3VersioningRule(),this.createCloudTrailEnabledRule(),this.createRdsBackupRule(30),this.createIamPasswordPolicyRule());break;case"gdpr":i.push(this.createS3EncryptionRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createRdsSnapshotEncryptionRule());break;case"basic":i.push(this.createS3EncryptionRule(),this.createS3PublicAccessBlockRule(),this.createRdsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamMfaRule(),this.createRootAccountMfaRule());break}return i}getConfigRule(n){return this.configRules.get(n)}listConfigRules(){return Array.from(this.configRules.values())}getConfigRecorder(n){return this.configRecorders.get(n)}listConfigRecorders(){return Array.from(this.configRecorders.values())}getDeliveryChannel(n){return this.deliveryChannels.get(n)}listDeliveryChannels(){return Array.from(this.deliveryChannels.values())}generateConfigRuleCF(n){let i={Type:"AWS::Config::ConfigRule",Properties:{ConfigRuleName:n.name,Description:n.description,Source:{Owner:n.source==="AWS_MANAGED"?"AWS":"CUSTOM_LAMBDA"}}};if(n.source==="AWS_MANAGED"&&n.identifier)i.Properties.Source.SourceIdentifier=n.identifier;if(n.source==="CUSTOM_LAMBDA"&&n.lambdaFunctionArn)i.Properties.Source.SourceIdentifier=n.lambdaFunctionArn,i.Properties.Source.SourceDetails=[{EventSource:"aws.config",MessageType:"ConfigurationItemChangeNotification"}];if(n.inputParameters)i.Properties.InputParameters=JSON.stringify(n.inputParameters);if(n.scope){if(i.Properties.Scope={},n.scope.complianceResourceTypes)i.Properties.Scope.ComplianceResourceTypes=n.scope.complianceResourceTypes;if(n.scope.tagKey)i.Properties.Scope.TagKey=n.scope.tagKey;if(n.scope.tagValue)i.Properties.Scope.TagValue=n.scope.tagValue}if(n.maxExecutionFrequency)i.Properties.MaximumExecutionFrequency=n.maxExecutionFrequency;return i}generateConfigRecorderCF(n){return{Type:"AWS::Config::ConfigurationRecorder",Properties:{Name:n.name,RoleArn:n.roleArn,RecordingGroup:n.recordingGroup||{AllSupported:!0,IncludeGlobalResourceTypes:!0}}}}generateDeliveryChannelCF(n){return{Type:"AWS::Config::DeliveryChannel",Properties:{Name:n.name,S3BucketName:n.s3BucketName,...n.s3KeyPrefix&&{S3KeyPrefix:n.s3KeyPrefix},...n.snsTopicArn&&{SnsTopicARN:n.snsTopicArn},...n.configSnapshotDeliveryProperties&&{ConfigSnapshotDeliveryProperties:n.configSnapshotDeliveryProperties}}}}clear(){this.configRules.clear(),this.configRecorders.clear(),this.deliveryChannels.clear(),this.ruleCounter=0}}var Wy=new Tl;class wl{trails=new Map;trailCounter=0;createTrail(n){let i=`trail-${Date.now()}-${this.trailCounter++}`,s={id:i,...n};return this.trails.set(i,s),s}createOrganizationTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,s3KeyPrefix:"organization-trail",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,kmsKeyId:n.kmsKeyId,cloudWatchLogsLogGroupArn:n.cloudWatchLogsLogGroupArn,cloudWatchLogsRoleArn:n.cloudWatchLogsRoleArn})}createSecurityAuditTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,s3KeyPrefix:"security-audit",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,kmsKeyId:n.kmsKeyId,cloudWatchLogsLogGroupArn:n.cloudWatchLogsLogGroupArn,cloudWatchLogsRoleArn:n.cloudWatchLogsRoleArn,eventSelectors:[{readWriteType:"All",includeManagementEvents:!0,excludeManagementEventSources:[]}],insightSelectors:[{insightType:"ApiCallRateInsight"},{insightType:"ApiErrorRateInsight"}]})}createDataEventsTrail(n){let i=[];if(n.s3DataBuckets&&n.s3DataBuckets.length>0)i.push({type:"AWS::S3::Object",values:n.s3DataBuckets.map((s)=>`arn:aws:s3:::${s}/*`)});if(n.lambdaFunctions&&n.lambdaFunctions.length>0)i.push({type:"AWS::Lambda::Function",values:n.lambdaFunctions});return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,s3KeyPrefix:"data-events",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"All",includeManagementEvents:!1,dataResources:i}]})}createAdvancedTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,advancedEventSelectors:n.selectors})}createReadOnlyTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"ReadOnly",includeManagementEvents:!0}]})}createWriteOnlyTrail(n){return this.createTrail({name:n.name,s3BucketName:n.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"WriteOnly",includeManagementEvents:!0}]})}getTrail(n){return this.trails.get(n)}listTrails(){return Array.from(this.trails.values())}generateTrailCF(n){let i={Type:"AWS::CloudTrail::Trail",Properties:{TrailName:n.name,S3BucketName:n.s3BucketName,IsLogging:!0,IncludeGlobalServiceEvents:n.includeGlobalServiceEvents??!0,IsMultiRegionTrail:n.isMultiRegionTrail??!0,EnableLogFileValidation:n.enableLogFileValidation??!0}};if(n.s3KeyPrefix)i.Properties.S3KeyPrefix=n.s3KeyPrefix;if(n.cloudWatchLogsLogGroupArn)i.Properties.CloudWatchLogsLogGroupArn=n.cloudWatchLogsLogGroupArn;if(n.cloudWatchLogsRoleArn)i.Properties.CloudWatchLogsRoleArn=n.cloudWatchLogsRoleArn;if(n.snsTopicName)i.Properties.SnsTopicName=n.snsTopicName;if(n.kmsKeyId)i.Properties.KMSKeyId=n.kmsKeyId;if(n.eventSelectors)i.Properties.EventSelectors=n.eventSelectors.map((s)=>({ReadWriteType:s.readWriteType,IncludeManagementEvents:s.includeManagementEvents??!0,...s.dataResources&&{DataResources:s.dataResources.map((o)=>({Type:o.type,Values:o.values}))},...s.excludeManagementEventSources&&{ExcludeManagementEventSources:s.excludeManagementEventSources}}));if(n.insightSelectors)i.Properties.InsightSelectors=n.insightSelectors.map((s)=>({InsightType:s.insightType}));if(n.advancedEventSelectors)i.Properties.AdvancedEventSelectors=n.advancedEventSelectors.map((s)=>({Name:s.name,FieldSelectors:s.fieldSelectors.map((o)=>({Field:o.field,...o.equals&&{Equals:o.equals},...o.startsWith&&{StartsWith:o.startsWith},...o.endsWith&&{EndsWith:o.endsWith},...o.notEquals&&{NotEquals:o.notEquals},...o.notStartsWith&&{NotStartsWith:o.notStartsWith},...o.notEndsWith&&{NotEndsWith:o.notEndsWith}}))}));return i}generateBucketPolicy(n,i){return{Version:"2012-10-17",Statement:[{Sid:"AWSCloudTrailAclCheck",Effect:"Allow",Principal:{Service:"cloudtrail.amazonaws.com"},Action:"s3:GetBucketAcl",Resource:`arn:aws:s3:::${n}`},{Sid:"AWSCloudTrailWrite",Effect:"Allow",Principal:{Service:"cloudtrail.amazonaws.com"},Action:"s3:PutObject",Resource:i.map((s)=>`arn:aws:s3:::${n}/AWSLogs/${s}/*`),Condition:{StringEquals:{"s3:x-amz-acl":"bucket-owner-full-control"}}}]}}clear(){this.trails.clear(),this.trailCounter=0}}var Jy=new wl;class Rl{detectors=new Map;threatIntelSets=new Map;ipSets=new Map;filters=new Map;detectorCounter=0;threatIntelCounter=0;ipSetCounter=0;filterCounter=0;createDetector(n){let i=`detector-${Date.now()}-${this.detectorCounter++}`,s={id:i,...n};return this.detectors.set(i,s),s}createComprehensiveDetector(){return this.createDetector({enable:!0,findingPublishingFrequency:"FIFTEEN_MINUTES",dataSources:{s3Logs:{enable:!0},kubernetes:{auditLogs:{enable:!0}},malwareProtection:{scanEc2InstanceWithFindings:{ebsVolumes:{enable:!0}}}},features:[{name:"S3_DATA_EVENTS",status:"ENABLED"},{name:"EKS_AUDIT_LOGS",status:"ENABLED"},{name:"EBS_MALWARE_PROTECTION",status:"ENABLED"},{name:"RDS_LOGIN_EVENTS",status:"ENABLED"},{name:"LAMBDA_NETWORK_LOGS",status:"ENABLED"}]})}createBasicDetector(){return this.createDetector({enable:!0,findingPublishingFrequency:"SIX_HOURS"})}createThreatIntelSet(n){let i=`threat-intel-${Date.now()}-${this.threatIntelCounter++}`,s={id:i,...n};return this.threatIntelSets.set(i,s),s}createIPSet(n){let i=`ip-set-${Date.now()}-${this.ipSetCounter++}`,s={id:i,...n};return this.ipSets.set(i,s),s}createFindingFilter(n){let i=`filter-${Date.now()}-${this.filterCounter++}`,s={id:i,...n};return this.filters.set(i,s),s}createLowSeverityArchiveFilter(n){return this.createFindingFilter({detectorId:n,name:"archive-low-severity",description:"Automatically archive low severity findings",action:"ARCHIVE",rank:1,findingCriteria:{criterion:{severity:{lt:4}}}})}createFindingTypeFilter(n,i,s){return this.createFindingFilter({detectorId:n,name:`filter-finding-types-${s.toLowerCase()}`,description:`${s==="ARCHIVE"?"Archive":"Keep"} specific finding types`,action:s,rank:2,findingCriteria:{criterion:{type:{eq:i}}}})}createTrustedIPFilter(n,i){return this.createFindingFilter({detectorId:n,name:"trusted-ip-addresses",description:"Archive findings from trusted IP addresses",action:"ARCHIVE",rank:3,findingCriteria:{criterion:{"resource.instanceDetails.networkInterfaces.privateIpAddress":{eq:i}}}})}getDetector(n){return this.detectors.get(n)}listDetectors(){return Array.from(this.detectors.values())}getThreatIntelSet(n){return this.threatIntelSets.get(n)}listThreatIntelSets(){return Array.from(this.threatIntelSets.values())}getIPSet(n){return this.ipSets.get(n)}listIPSets(){return Array.from(this.ipSets.values())}getFindingFilter(n){return this.filters.get(n)}listFindingFilters(){return Array.from(this.filters.values())}generateDetectorCF(n){let i={Type:"AWS::GuardDuty::Detector",Properties:{Enable:n.enable}};if(n.findingPublishingFrequency)i.Properties.FindingPublishingFrequency=n.findingPublishingFrequency;if(n.dataSources){if(i.Properties.DataSources={},n.dataSources.s3Logs)i.Properties.DataSources.S3Logs={Enable:n.dataSources.s3Logs.enable};if(n.dataSources.kubernetes)i.Properties.DataSources.Kubernetes={AuditLogs:{Enable:n.dataSources.kubernetes.auditLogs.enable}};if(n.dataSources.malwareProtection)i.Properties.DataSources.MalwareProtection={ScanEc2InstanceWithFindings:{EbsVolumes:{Enable:n.dataSources.malwareProtection.scanEc2InstanceWithFindings.ebsVolumes.enable}}}}if(n.features)i.Properties.Features=n.features.map((s)=>({Name:s.name,Status:s.status,...s.additionalConfiguration&&{AdditionalConfiguration:s.additionalConfiguration}}));return i}generateThreatIntelSetCF(n){return{Type:"AWS::GuardDuty::ThreatIntelSet",Properties:{DetectorId:n.detectorId,Name:n.name,Format:n.format,Location:n.location,Activate:n.activate}}}generateIPSetCF(n){return{Type:"AWS::GuardDuty::IPSet",Properties:{DetectorId:n.detectorId,Name:n.name,Format:n.format,Location:n.location,Activate:n.activate}}}generateFilterCF(n){return{Type:"AWS::GuardDuty::Filter",Properties:{DetectorId:n.detectorId,Name:n.name,Description:n.description,Action:n.action,Rank:n.rank,FindingCriteria:{Criterion:n.findingCriteria.criterion}}}}clear(){this.detectors.clear(),this.threatIntelSets.clear(),this.ipSets.clear(),this.filters.clear(),this.detectorCounter=0,this.threatIntelCounter=0,this.ipSetCounter=0,this.filterCounter=0}}var Xy=new Rl;class mr{hubs=new Map;hubCounter=0;ruleCounter=0;static Standards={AWS_FOUNDATIONAL_SECURITY:{arn:"arn:aws:securityhub:::ruleset/aws-foundational-security-best-practices/v/1.0.0",name:"AWS Foundational Security Best Practices",description:"AWS recommended security best practices"},CIS_AWS_FOUNDATIONS_1_2:{arn:"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0",name:"CIS AWS Foundations Benchmark v1.2.0",description:"CIS AWS Foundations Benchmark v1.2.0"},CIS_AWS_FOUNDATIONS_1_4:{arn:"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.4.0",name:"CIS AWS Foundations Benchmark v1.4.0",description:"CIS AWS Foundations Benchmark v1.4.0"},PCI_DSS:{arn:"arn:aws:securityhub:us-east-1::standards/pci-dss/v/3.2.1",name:"PCI DSS v3.2.1",description:"Payment Card Industry Data Security Standard"},NIST_800_53:{arn:"arn:aws:securityhub:us-east-1::standards/nist-800-53/v/5.0.0",name:"NIST SP 800-53 Rev. 5",description:"NIST Special Publication 800-53 Revision 5"}};createHub(n){let i=`hub-${Date.now()}-${this.hubCounter++}`,s={id:i,...n};return this.hubs.set(i,s),s}createComprehensiveHub(){return this.createHub({enable:!0,controlFindingGenerator:"SECURITY_CONTROL",enableDefaultStandards:!0,standards:[{id:"aws-foundational",...mr.Standards.AWS_FOUNDATIONAL_SECURITY,enabled:!0},{id:"cis-1-4",...mr.Standards.CIS_AWS_FOUNDATIONS_1_4,enabled:!0},{id:"pci-dss",...mr.Standards.PCI_DSS,enabled:!0}]})}createBasicHub(){return this.createHub({enable:!0,controlFindingGenerator:"STANDARD_CONTROL",enableDefaultStandards:!0,standards:[{id:"aws-foundational",...mr.Standards.AWS_FOUNDATIONAL_SECURITY,enabled:!0}]})}createLowSeveritySuppressionRule(){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Suppress Low Severity Informational Findings",description:"Automatically suppress informational findings",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"SUPPRESSED"},note:{text:"Automatically suppressed low severity finding",updatedBy:"SecurityHub Automation"}}}],criteria:{severityLabel:[{value:"INFORMATIONAL",comparison:"EQUALS"}],recordState:[{value:"ACTIVE",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:1}}createResourceTypeNotificationRule(n){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Notify on Critical Resource Findings",description:"Set findings for critical resources to NOTIFIED status",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"NOTIFIED"},note:{text:"Critical resource finding requires attention",updatedBy:"SecurityHub Automation"}}}],criteria:{resourceType:n.map((i)=>({value:i,comparison:"EQUALS"})),severityLabel:[{value:"HIGH",comparison:"EQUALS"},{value:"CRITICAL",comparison:"EQUALS"}],workflowStatus:[{value:"NEW",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:2}}createComplianceFailureRule(){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Flag Compliance Failures",description:"Increase severity for compliance failures",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{severity:{label:"HIGH"},workflow:{status:"NOTIFIED"},note:{text:"Compliance failure detected - requires immediate attention",updatedBy:"SecurityHub Automation"}}}],criteria:{complianceStatus:[{value:"FAILED",comparison:"EQUALS"}],recordState:[{value:"ACTIVE",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:3}}createFalsePositiveSuppressionRule(n,i){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:`Suppress False Positives - ${n}`,description:`Automatically suppress known false positives from ${n}`,actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"SUPPRESSED"},note:{text:"Known false positive - automatically suppressed",updatedBy:"SecurityHub Automation"}}}],criteria:{productName:[{value:n,comparison:"EQUALS"}],title:i.map((s)=>({value:s,comparison:"PREFIX"}))},ruleStatus:"ENABLED",ruleOrder:10}}getHub(n){return this.hubs.get(n)}listHubs(){return Array.from(this.hubs.values())}generateHubCF(n){let i={Type:"AWS::SecurityHub::Hub",Properties:{}};if(n.controlFindingGenerator)i.Properties.ControlFindingGenerator=n.controlFindingGenerator;if(n.enableDefaultStandards!==void 0)i.Properties.EnableDefaultStandards=n.enableDefaultStandards;return i}generateStandardCF(n){let i={Type:"AWS::SecurityHub::Standard",Properties:{StandardsArn:n.arn}};if(n.disabledControls&&n.disabledControls.length>0)i.Properties.DisabledStandardsControls=n.disabledControls.map((s)=>({StandardsControlArn:s,Reason:"Disabled by configuration"}));return i}generateAutomationRuleCF(n){return{Type:"AWS::SecurityHub::AutomationRule",Properties:{RuleName:n.ruleName,Description:n.description,Actions:n.actions.map((i)=>({Type:i.type,FindingFieldsUpdate:i.findingFieldsUpdate})),Criteria:n.criteria,RuleStatus:n.ruleStatus,RuleOrder:n.ruleOrder}}}clear(){this.hubs.clear(),this.hubCounter=0,this.ruleCounter=0}}var Yy=new mr;class Dl{deployments=new Map;deploymentHistory=new Map;deploymentCounter=0;resultCounter=0;createDeployment(n){let i=`bg-deployment-${Date.now()}-${this.deploymentCounter++}`,s={id:i,...n};return this.deployments.set(i,s),s}createALBDeployment(n){return this.createDeployment({name:n.name,blueEnvironment:{name:"blue",targetGroupArn:n.blueTargetGroupArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:n.greenTargetGroupArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"alb",listenerArn:n.listenerArn,switchoverTimeSeconds:0},autoPromote:n.autoPromote,healthCheckConfig:n.healthCheckConfig})}createRoute53Deployment(n){return this.createDeployment({name:n.name,blueEnvironment:{name:"blue",targetGroupArn:n.blueTargetGroupArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:n.greenTargetGroupArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"route53",hostedZoneId:n.hostedZoneId,switchoverTimeSeconds:n.switchoverTimeSeconds||60}})}createECSDeployment(n){return this.createDeployment({name:n.name,blueEnvironment:{name:"blue",targetGroupArn:n.blueTargetGroupArn,taskDefinitionArn:n.blueTaskDefinitionArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:n.greenTargetGroupArn,taskDefinitionArn:n.greenTaskDefinitionArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"alb",listenerArn:n.listenerArn},autoRollback:n.autoRollback??!0})}async executeDeployment(n,i=!1){let s=this.deployments.get(n);if(!s)throw Error(`Deployment not found: ${n}`);let o={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,healthChecksPassed:!1,errors:[]};console.log(`${i?"[DRY RUN] ":""}Starting blue/green deployment: ${s.name}`),console.log(` Active environment: ${s.activeEnvironment}`),console.log(` Routing type: ${s.routingConfig.type}`);let c=s.activeEnvironment==="blue"?"green":"blue";if(console.log(` Switching to: ${c}`),console.log(`\\n1. Deploying to ${c} environment`),!i)await new Promise((u)=>setTimeout(u,100));if(console.log(`\\n2. Running health checks on ${c} environment`),s.healthCheckConfig){let u=await this.runHealthChecks(s,c,i);if(o.healthChecksPassed=u,!u){if(o.errors?.push("Health checks failed"),o.endTime=new Date,s.autoRollback)console.log(" Auto-rollback enabled - keeping current environment active"),o.rolledBackAt=new Date;return this.recordDeployment(n,o),o}}else o.healthChecksPassed=!0;if(console.log(`\\n3. Switching traffic to ${c} environment`),!i)s.activeEnvironment=c,o.switchedAt=new Date;if(console.log(`\\n4. Monitoring ${c} environment`),!i)await new Promise((u)=>setTimeout(u,100));return o.success=!0,o.endTime=new Date,console.log("\\n✓ Deployment completed successfully"),this.recordDeployment(n,o),o}async rollback(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);let s={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,healthChecksPassed:!0,errors:[]};console.log(`Rolling back deployment: ${i.name}`);let o=i.activeEnvironment==="blue"?"green":"blue";return i.activeEnvironment=o,s.success=!0,s.rolledBackAt=new Date,s.endTime=new Date,console.log(` Switched back to: ${o}`),this.recordDeployment(n,s),s}async runHealthChecks(n,i,s){let o=n.healthCheckConfig;if(console.log(` Health check path: ${o.path||"/"}`),console.log(` Healthy threshold: ${o.healthyThreshold}`),console.log(` Interval: ${o.interval}s`),s)return console.log(" [SKIPPED - DRY RUN]"),!0;let c=0,u=o.healthyThreshold+2;for(let d=0;d<u;d++)if(await new Promise((y)=>setTimeout(y,50)),Math.random()>0.1){if(c++,console.log(` Check ${d+1}: ✓ Healthy (${c}/${o.healthyThreshold})`),c>=o.healthyThreshold)return!0}else c=0,console.log(` Check ${d+1}: ✗ Unhealthy`);return!1}recordDeployment(n,i){if(!this.deploymentHistory.has(n))this.deploymentHistory.set(n,[]);this.deploymentHistory.get(n).push(i)}getDeployment(n){return this.deployments.get(n)}listDeployments(){return Array.from(this.deployments.values())}getDeploymentHistory(n){return this.deploymentHistory.get(n)||[]}generateALBListenerCF(n){let i=n.activeEnvironment==="blue"?n.blueEnvironment:n.greenEnvironment;return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:n.routingConfig.listenerArn,Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",TargetGroupArn:i.targetGroupArn}]}}}generateRoute53RecordSetCF(n,i){return[{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.routingConfig.hostedZoneId,Name:i,Type:"A",SetIdentifier:"blue",Weight:n.activeEnvironment==="blue"?100:0,AliasTarget:{HostedZoneId:n.routingConfig.hostedZoneId,DNSName:n.blueEnvironment.targetGroupArn,EvaluateTargetHealth:!0}}},{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.routingConfig.hostedZoneId,Name:i,Type:"A",SetIdentifier:"green",Weight:n.activeEnvironment==="green"?100:0,AliasTarget:{HostedZoneId:n.routingConfig.hostedZoneId,DNSName:n.greenEnvironment.targetGroupArn,EvaluateTargetHealth:!0}}}]}clear(){this.deployments.clear(),this.deploymentHistory.clear(),this.deploymentCounter=0,this.resultCounter=0}}var Zy=new Dl;class rs{deployments=new Map;deploymentHistory=new Map;deploymentCounter=0;resultCounter=0;static Strategies={CONSERVATIVE:[{name:"Initial Canary",trafficPercentage:10,durationMinutes:10},{name:"Quarter Traffic",trafficPercentage:25,durationMinutes:10},{name:"Half Traffic",trafficPercentage:50,durationMinutes:15},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],BALANCED:[{name:"Initial Canary",trafficPercentage:20,durationMinutes:5},{name:"Half Traffic",trafficPercentage:50,durationMinutes:10},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],AGGRESSIVE:[{name:"Half Traffic",trafficPercentage:50,durationMinutes:5},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],LINEAR_10:[{name:"Canary 10%",trafficPercentage:10,durationMinutes:5},{name:"Canary 20%",trafficPercentage:20,durationMinutes:5},{name:"Canary 30%",trafficPercentage:30,durationMinutes:5},{name:"Canary 40%",trafficPercentage:40,durationMinutes:5},{name:"Canary 50%",trafficPercentage:50,durationMinutes:5},{name:"Canary 60%",trafficPercentage:60,durationMinutes:5},{name:"Canary 70%",trafficPercentage:70,durationMinutes:5},{name:"Canary 80%",trafficPercentage:80,durationMinutes:5},{name:"Canary 90%",trafficPercentage:90,durationMinutes:5},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}]};createDeployment(n){let i=`canary-${Date.now()}-${this.deploymentCounter++}`,s={id:i,...n};return this.deployments.set(i,s),s}createLambdaCanaryDeployment(n){let i=n.strategy||"BALANCED",s=rs.Strategies[i].map((o)=>({...o,alarmThresholds:{errorRate:n.errorRateThreshold||1,latencyP99:n.latencyThreshold||1000}}));return this.createDeployment({name:n.name,baselineVersion:{version:"baseline",functionVersionArn:n.baselineVersionArn,weight:100},canaryVersion:{version:"canary",functionVersionArn:n.canaryVersionArn,weight:0},stages:s,currentStage:0,status:"pending",autoPromote:n.autoPromote??!0,autoRollback:!0})}createECSCanaryDeployment(n){let i=n.strategy||"CONSERVATIVE",s=rs.Strategies[i];return this.createDeployment({name:n.name,baselineVersion:{version:"baseline",taskDefinitionArn:n.baselineTaskDefinitionArn,targetGroupArn:n.baselineTargetGroupArn,weight:100},canaryVersion:{version:"canary",taskDefinitionArn:n.canaryTaskDefinitionArn,targetGroupArn:n.canaryTargetGroupArn,weight:0},stages:s,currentStage:0,status:"pending",autoRollback:!0})}async executeDeployment(n,i=!1){let s=this.deployments.get(n);if(!s)throw Error(`Deployment not found: ${n}`);let o={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,completedStages:0,rolledBack:!1};console.log(`${i?"[DRY RUN] ":""}Starting canary deployment: ${s.name}`),console.log(` Strategy: ${s.stages.length} stages`),console.log(` Auto-promote: ${s.autoPromote}`),console.log(` Auto-rollback: ${s.autoRollback}`),console.log(""),s.status="in_progress";for(let c=0;c<s.stages.length;c++){let u=s.stages[c];if(s.currentStage=c,console.log(`Stage ${c+1}/${s.stages.length}: ${u.name}`),console.log(` Traffic: ${u.trafficPercentage}% canary, ${100-u.trafficPercentage}% baseline`),console.log(` Duration: ${u.durationMinutes} minutes`),!i)s.baselineVersion.weight=100-u.trafficPercentage,s.canaryVersion.weight=u.trafficPercentage;if(!await this.monitorStage(s,u,i)){if(console.log(" ✗ Stage failed - metrics exceeded thresholds"),s.autoRollback)console.log("\\n Rolling back deployment..."),await this.rollback(n,i),o.rolledBack=!0,o.reason="Metrics exceeded thresholds";return o.endTime=new Date,s.status="rolled_back",this.recordDeployment(n,o),o}console.log(" ✓ Stage completed successfully"),o.completedStages++,console.log("")}return s.status="completed",o.success=!0,o.endTime=new Date,console.log("✓ Canary deployment completed successfully"),this.recordDeployment(n,o),o}async monitorStage(n,i,s){if(console.log(" Monitoring metrics..."),s)return console.log(" [SKIPPED - DRY RUN]"),!0;await new Promise((c)=>setTimeout(c,100));let o={baselineErrorRate:Math.random()*0.5,canaryErrorRate:Math.random()*0.8,baselineLatencyP99:200+Math.random()*100,canaryLatencyP99:180+Math.random()*150,baselineRequestCount:Math.floor(Math.random()*1000)+500,canaryRequestCount:Math.floor((Math.random()*1000+500)*i.trafficPercentage/100)};if(n.metrics=o,console.log(` Baseline: ${o.baselineErrorRate.toFixed(2)}% errors, ${o.baselineLatencyP99.toFixed(0)}ms P99`),console.log(` Canary: ${o.canaryErrorRate.toFixed(2)}% errors, ${o.canaryLatencyP99.toFixed(0)}ms P99`),i.alarmThresholds){let{errorRate:c,latencyP99:u}=i.alarmThresholds;if(c&&o.canaryErrorRate>c)return console.log(` ⚠ Error rate exceeded threshold: ${o.canaryErrorRate.toFixed(2)}% > ${c}%`),!1;if(u&&o.canaryLatencyP99>u)return console.log(` ⚠ Latency P99 exceeded threshold: ${o.canaryLatencyP99.toFixed(0)}ms > ${u}ms`),!1}return!0}async rollback(n,i=!1){let s=this.deployments.get(n);if(!s)throw Error(`Deployment not found: ${n}`);if(console.log(`${i?"[DRY RUN] ":""}Rolling back canary deployment: ${s.name}`),!i)s.baselineVersion.weight=100,s.canaryVersion.weight=0,s.status="rolled_back";console.log(" Traffic restored to baseline: 100%")}promoteCanary(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);console.log(`Promoting canary to baseline: ${i.name}`);let s=i.baselineVersion;i.baselineVersion=i.canaryVersion,i.canaryVersion=s,i.baselineVersion.weight=100,i.canaryVersion.weight=0,i.status="completed",console.log(" Canary promoted successfully")}recordDeployment(n,i){if(!this.deploymentHistory.has(n))this.deploymentHistory.set(n,[]);this.deploymentHistory.get(n).push(i)}getDeployment(n){return this.deployments.get(n)}listDeployments(){return Array.from(this.deployments.values())}getDeploymentHistory(n){return this.deploymentHistory.get(n)||[]}generateLambdaAliasCF(n,i){return{Type:"AWS::Lambda::Alias",Properties:{FunctionName:{Ref:"LambdaFunction"},Name:i,FunctionVersion:n.canaryVersion.version,RoutingConfig:{AdditionalVersionWeights:[{FunctionVersion:n.baselineVersion.version,FunctionWeight:n.baselineVersion.weight/100}]}}}}generateALBListenerRuleCF(n){return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:{Ref:"LoadBalancerListener"},Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",ForwardConfig:{TargetGroups:[{TargetGroupArn:n.baselineVersion.targetGroupArn,Weight:n.baselineVersion.weight},{TargetGroupArn:n.canaryVersion.targetGroupArn,Weight:n.canaryVersion.weight}],TargetGroupStickinessConfig:{Enabled:!1}}}]}}}clear(){this.deployments.clear(),this.deploymentHistory.clear(),this.deploymentCounter=0,this.resultCounter=0}}var eS=new rs;class Pl{tests=new Map;testCounter=0;createTest(n){let i=`abtest-${Date.now()}-${this.testCounter++}`,s={id:i,...n};return this.tests.set(i,s),s}createSimpleABTest(n){let i=n.variantTrafficPercentage||50;return this.createTest({name:n.name,description:n.description,variants:[{id:"control",name:"Control",description:"Original version",trafficPercentage:100-i,targetGroupArn:n.controlTargetGroupArn,weight:100-i},{id:"variant-a",name:"Variant A",description:"Test version",trafficPercentage:i,targetGroupArn:n.variantTargetGroupArn,weight:i}],routingStrategy:{type:n.stickySession?"cookie":"random",cookieName:n.stickySession?"ab_variant":void 0,stickySession:n.stickySession??!1,sessionDuration:1440},startTime:new Date,status:"draft"})}createMultivariateTest(n){let i=n.variants.reduce((s,o)=>s+o.trafficPercentage,0);if(i!==100)throw Error(`Traffic percentages must sum to 100, got ${i}`);return this.createTest({name:n.name,description:n.description,variants:n.variants.map((s,o)=>({id:`variant-${o}`,name:s.name,description:s.description,trafficPercentage:s.trafficPercentage,targetGroupArn:s.targetGroupArn,weight:s.trafficPercentage})),routingStrategy:n.routingStrategy||{type:"random",stickySession:!1},startTime:new Date,status:"draft"})}createHeaderBasedTest(n){return this.createTest({name:n.name,description:`Route based on ${n.headerName} header`,variants:[{id:"control",name:"Control",trafficPercentage:50,targetGroupArn:n.controlTargetGroupArn,weight:50},{id:"variant-a",name:"Variant A",trafficPercentage:50,targetGroupArn:n.variantTargetGroupArn,weight:50}],routingStrategy:{type:"header",headerName:n.headerName,stickySession:!1},startTime:new Date,status:"draft"})}createGeoBasedTest(n){return this.createTest({name:n.name,description:"Route based on geographic location",variants:[{id:"control",name:"Control (Rest of World)",trafficPercentage:50,targetGroupArn:n.controlTargetGroupArn,weight:50},{id:"variant-a",name:`Variant A (${n.regions.join(", ")})`,trafficPercentage:50,targetGroupArn:n.variantTargetGroupArn,weight:50}],routingStrategy:{type:"geo",stickySession:!0,sessionDuration:1440},startTime:new Date,status:"draft"})}startTest(n){let i=this.tests.get(n);if(!i)throw Error(`Test not found: ${n}`);if(i.status!=="draft"&&i.status!=="paused")throw Error(`Cannot start test in ${i.status} status`);i.status="active",i.startTime=new Date,console.log(`Started A/B test: ${i.name}`),console.log(` Variants: ${i.variants.length}`),i.variants.forEach((s)=>{console.log(` - ${s.name}: ${s.trafficPercentage}%`)})}pauseTest(n){let i=this.tests.get(n);if(!i)throw Error(`Test not found: ${n}`);i.status="paused",console.log(`Paused A/B test: ${i.name}`)}updateTrafficSplit(n,i,s){let o=this.tests.get(n);if(!o)throw Error(`Test not found: ${n}`);let c=o.variants.find((d)=>d.id===i);if(!c)throw Error(`Variant not found: ${i}`);let u=c.trafficPercentage;c.trafficPercentage=s,c.weight=s,console.log(`Updated ${c.name} traffic: ${u}% → ${s}%`)}analyzeResults(n){let i=this.tests.get(n);if(!i)throw Error(`Test not found: ${n}`);if(!i.metrics)i.metrics=this.collectMetrics(i);let s=i.variants[0],o=0;for(let h of i.variants){let b=i.metrics.variants[h.id];if(b&&b.conversionRate>o)o=b.conversionRate,s=h}let c=i.metrics.variants.control||i.metrics.variants[i.variants[0].id],u=i.metrics.variants[s.id],d=(u.conversionRate-c.conversionRate)/c.conversionRate*100,p=100,y=u.requests>p&&c.requests>p&&Math.abs(d)>10;return{testId:n,winningVariant:s.name,confidence:y?95:75,improvement:d,statisticalSignificance:y,metrics:i.metrics,recommendation:this.generateRecommendation(d,y,s.name)}}declareWinner(n,i){let s=this.tests.get(n);if(!s)throw Error(`Test not found: ${n}`);let o=s.variants.find((c)=>c.id===i);if(!o)throw Error(`Variant not found: ${i}`);s.variants.forEach((c)=>{if(c.id===i)c.trafficPercentage=100,c.weight=100;else c.trafficPercentage=0,c.weight=0}),s.status="completed",s.endTime=new Date,s.winner=i,console.log(`Declared winner: ${o.name}`),console.log(` All traffic now routed to ${o.name}`)}collectMetrics(n){let i={},s=0;for(let o of n.variants){let c=Math.floor(Math.random()*1000)+500,u=Math.floor(c*(Math.random()*0.1+0.05)),d=u/c*100;i[o.id]={requests:c,conversions:u,conversionRate:d,averageLatency:150+Math.random()*100,errorRate:Math.random()*0.5,revenue:u*(Math.random()*50+100)},s+=c}return{variants:i,totalRequests:s,startTime:n.startTime,lastUpdated:new Date}}generateRecommendation(n,i,s){if(!i)return"Continue test - sample size too small or no significant difference detected";if(n>20)return`Strong winner detected - ${s} shows ${n.toFixed(1)}% improvement. Recommend deploying to all traffic.`;if(n>10)return`Moderate improvement - ${s} shows ${n.toFixed(1)}% improvement. Consider deploying.`;if(n>0)return`Minor improvement - ${s} shows ${n.toFixed(1)}% improvement. May not be worth the complexity.`;return"No improvement detected - consider reverting to control variant"}getTest(n){return this.tests.get(n)}listTests(){return Array.from(this.tests.values())}generateALBListenerRuleCF(n){return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:{Ref:"LoadBalancerListener"},Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",ForwardConfig:{TargetGroups:n.variants.map((i)=>({TargetGroupArn:i.targetGroupArn,Weight:i.weight})),TargetGroupStickinessConfig:{Enabled:n.routingStrategy.stickySession||!1,DurationSeconds:n.routingStrategy.sessionDuration?n.routingStrategy.sessionDuration*60:void 0}}}]}}}generateLambdaEdgeFunction(n){return`'use strict';
3566
3566
 
3567
3567
  exports.handler = (event, _context, _callback) => {
3568
3568
  const request = event.Records[0].cf.request;
@@ -3609,7 +3609,7 @@ exports.handler = (event, _context, _callback) => {
3609
3609
  }`).join(" else ")}
3610
3610
 
3611
3611
  callback(null, request);
3612
- };`}clear(){this.tests.clear(),this.testCounter=0}}var eS=new Pl;class kl{rollouts=new Map;flags=new Map;gates=new Map;counter=0;createProgressiveRollout(n,i){let s=`rollout-${Date.now()}-${this.counter++}`,o={id:s,name:n,stages:i,currentStage:0};return this.rollouts.set(s,o),o}createFeatureFlag(n,i=0){let s=`flag-${Date.now()}-${this.counter++}`,o={id:s,name:n,enabled:!1,rolloutPercentage:i,targetingRules:[]};return this.flags.set(s,o),o}createDeploymentGate(n,i,s,o){let c=`gate-${Date.now()}-${this.counter++}`,u={id:c,name:n,type:i,approvers:s,conditions:o};return this.gates.set(c,u),u}clear(){this.rollouts.clear(),this.flags.clear(),this.gates.clear()}}var tS=new kl;class Ym{configs=new Map;samplingRules=new Map;configCounter=0;ruleCounter=0;createConfig(n){let i=`xray-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}createLambdaConfig(n){return this.createConfig({name:`${n.functionName}-xray`,serviceName:n.functionName,samplingRate:n.samplingRate||0.1,enableActiveTracing:!0})}createECSConfig(n){return this.createConfig({name:`${n.serviceName}-xray`,serviceName:`${n.clusterName}/${n.serviceName}`,samplingRate:n.samplingRate||0.05,enableActiveTracing:!0})}createAPIGatewayConfig(n){return this.createConfig({name:`${n.apiName}-${n.stage}-xray`,serviceName:`${n.apiName}/${n.stage}`,samplingRate:n.samplingRate||0.05,enableActiveTracing:!0})}createSamplingRule(n){let i=`sampling-rule-${Date.now()}-${this.ruleCounter++}`,s={id:i,...n};return this.samplingRules.set(i,s),s}createHighPrioritySamplingRule(n){return this.createSamplingRule({ruleName:n.ruleName,priority:100,fixedRate:1,reservoirSize:100,serviceName:n.serviceName,serviceType:"*",host:"*",httpMethod:"*",urlPath:n.urlPath,version:1})}createErrorSamplingRule(n){return this.createSamplingRule({ruleName:`${n}-errors`,priority:200,fixedRate:1,reservoirSize:50,serviceName:n,serviceType:"*",host:"*",httpMethod:"*",urlPath:"/error/*",version:1})}createDefaultSamplingRule(n,i=0.05){return this.createSamplingRule({ruleName:`${n}-default`,priority:1000,fixedRate:i,reservoirSize:10,serviceName:n,serviceType:"*",host:"*",httpMethod:"*",urlPath:"*",version:1})}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getSamplingRule(n){return this.samplingRules.get(n)}listSamplingRules(){return Array.from(this.samplingRules.values())}generateLambdaXRayCF(n){return{TracingConfig:{Mode:n.enableActiveTracing?"Active":"PassThrough"}}}generateAPIGatewayXRayCF(n){return{TracingEnabled:n.enableActiveTracing}}generateECSXRaySidecarCF(){return{Name:"xray-daemon",Image:"public.ecr.aws/xray/aws-xray-daemon:latest",Cpu:32,MemoryReservation:256,PortMappings:[{ContainerPort:2000,Protocol:"udp"}]}}generateSamplingRuleCF(n){return{Type:"AWS::XRay::SamplingRule",Properties:{SamplingRule:{RuleName:n.ruleName,Priority:n.priority,FixedRate:n.fixedRate,ReservoirSize:n.reservoirSize,ServiceName:n.serviceName,ServiceType:n.serviceType,Host:n.host,HTTPMethod:n.httpMethod,URLPath:n.urlPath,Version:n.version,ResourceARN:"*"}}}}createTrace(n,i){return{id:`trace-${Date.now()}-${this.configCounter++}`,traceId:n,spans:i}}clear(){this.configs.clear(),this.samplingRules.clear(),this.configCounter=0,this.ruleCounter=0}}var tE=new Ym;class Zm{namespaces=new Map;metrics=new Map;namespaceCounter=0;metricCounter=0;alarmCounter=0;createNamespace(n){let i=`namespace-${Date.now()}-${this.namespaceCounter++}`,s={id:i,...n};return this.namespaces.set(i,s),s}createMetric(n){let i=`metric-${Date.now()}-${this.metricCounter++}`,s={id:i,...n};return this.metrics.set(i,s),s}createBusinessMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:n.unit,dimensions:[{name:"Environment",value:"production"},{name:"Type",value:"Business"}]})}createApplicationMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:n.unit,dimensions:[{name:"Service",value:n.serviceName},{name:"Type",value:"Application"}]})}createPerformanceMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:"Milliseconds",dimensions:[{name:"Operation",value:n.operation},{name:"Type",value:"Performance"}]})}createErrorMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:"Count",dimensions:[{name:"ErrorType",value:n.errorType},{name:"Type",value:"Error"}]})}createAlarm(n,i){let s=this.metrics.get(n);if(!s)throw Error(`Metric not found: ${n}`);let c={id:`alarm-${Date.now()}-${this.alarmCounter++}`,...i};if(!s.alarms)s.alarms=[];return s.alarms.push(c),c}createErrorRateAlarm(n){return this.createAlarm(n.metricId,{name:n.name,description:`Alert when error rate exceeds ${n.threshold} errors/min`,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:2,threshold:n.threshold,period:60,statistic:"Sum",treatMissingData:"notBreaching",actionsEnabled:!0,alarmActions:n.snsTopicArn?[n.snsTopicArn]:void 0})}createLatencyAlarm(n){return this.createAlarm(n.metricId,{name:n.name,description:`Alert when latency exceeds ${n.thresholdMs}ms`,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,threshold:n.thresholdMs,period:300,statistic:"Average",treatMissingData:"notBreaching",actionsEnabled:!0,alarmActions:n.snsTopicArn?[n.snsTopicArn]:void 0})}createThroughputAlarm(n){return this.createAlarm(n.metricId,{name:n.name,description:`Alert when throughput drops below ${n.minimumThreshold}`,comparisonOperator:"LessThanThreshold",evaluationPeriods:2,threshold:n.minimumThreshold,period:300,statistic:"Sum",treatMissingData:"breaching",actionsEnabled:!0,alarmActions:n.snsTopicArn?[n.snsTopicArn]:void 0})}createCompositeAlarm(n){return{name:n.name,description:n.description,alarmRule:n.alarmRule,actionsEnabled:n.actionsEnabled??!0,alarmActions:n.alarmActions}}getNamespace(n){return this.namespaces.get(n)}listNamespaces(){return Array.from(this.namespaces.values())}getMetric(n){return this.metrics.get(n)}listMetrics(){return Array.from(this.metrics.values())}generateAlarmCF(n,i){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:i.name,AlarmDescription:i.description,ComparisonOperator:i.comparisonOperator,EvaluationPeriods:i.evaluationPeriods,MetricName:n.name,Namespace:n.namespace,Period:i.period,Statistic:i.statistic,Threshold:i.threshold,TreatMissingData:i.treatMissingData||"notBreaching",ActionsEnabled:i.actionsEnabled??!0,...i.alarmActions&&{AlarmActions:i.alarmActions},...i.okActions&&{OKActions:i.okActions},...i.insufficientDataActions&&{InsufficientDataActions:i.insufficientDataActions},...n.dimensions&&{Dimensions:n.dimensions.map((s)=>({Name:s.name,Value:s.value}))}}}}generateCompositeAlarmCF(n){return{Type:"AWS::CloudWatch::CompositeAlarm",Properties:{AlarmName:n.name,AlarmDescription:n.description,AlarmRule:n.alarmRule,ActionsEnabled:n.actionsEnabled,...n.alarmActions&&{AlarmActions:n.alarmActions}}}}generateDashboardWidget(n){return{type:"metric",properties:{metrics:[[n.namespace,n.name,...n.dimensions?.flatMap((i)=>[i.name,i.value])||[]]],period:300,stat:"Average",region:"us-east-1",title:n.name}}}publishCustomMetric(n,i,s,o={},c="Count"){return{id:`metric-${Date.now()}-${this.metricCounter++}`,namespace:n,name:i,dimensions:o,value:s,unit:c,timestamp:new Date}}clear(){this.namespaces.clear(),this.metrics.clear(),this.namespaceCounter=0,this.metricCounter=0,this.alarmCounter=0}}var rE=new Zm;class Nl{logGroups=new Map;queries=new Map;insightsQueries=new Map;logGroupCounter=0;filterCounter=0;queryCounter=0;createLogGroup(n){let i=`log-group-${Date.now()}-${this.logGroupCounter++}`,s={id:i,...n};return this.logGroups.set(i,s),s}createLambdaLogGroup(n,i=7){return this.createLogGroup({name:`/aws/lambda/${n}`,retentionDays:i})}createECSLogGroup(n){return this.createLogGroup({name:`/ecs/${n.clusterName}/${n.serviceName}`,retentionDays:n.retentionDays||14})}createAPIGatewayLogGroup(n,i,s=30){return this.createLogGroup({name:`/aws/apigateway/${n}/${i}`,retentionDays:s})}createApplicationLogGroup(n){return this.createLogGroup({name:`/application/${n.appName}/${n.environment}`,retentionDays:n.retentionDays||30,kmsKeyId:n.kmsKeyId})}createMetricFilter(n,i){let s=this.logGroups.get(n);if(!s)throw Error(`Log group not found: ${n}`);let c={id:`filter-${Date.now()}-${this.filterCounter++}`,...i};if(!s.metricFilters)s.metricFilters=[];return s.metricFilters.push(c),c}createErrorCountFilter(n,i){return this.createMetricFilter(n,{name:"ErrorCount",filterPattern:"[timestamp, request_id, level = ERROR*, ...]",metricTransformations:[{metricName:"ErrorCount",metricNamespace:i,metricValue:"1",defaultValue:0,unit:"Count"}]})}createLatencyFilter(n,i){return this.createMetricFilter(n,{name:"Latency",filterPattern:"[timestamp, request_id, level, duration, ...]",metricTransformations:[{metricName:"ResponseTime",metricNamespace:i,metricValue:"$duration",unit:"Milliseconds"}]})}createCustomPatternFilter(n){return this.createMetricFilter(n.logGroupId,{name:n.name,filterPattern:n.pattern,metricTransformations:[{metricName:n.metricName,metricNamespace:n.namespace,metricValue:"1",defaultValue:0,unit:"Count"}]})}createSubscriptionFilter(n,i){let s=this.logGroups.get(n);if(!s)throw Error(`Log group not found: ${n}`);let c={id:`subscription-${Date.now()}-${this.filterCounter++}`,...i};if(!s.subscriptionFilters)s.subscriptionFilters=[];return s.subscriptionFilters.push(c),c}createKinesisSubscription(n){let i=this.logGroups.get(n.logGroupId);if(!i)throw Error(`Log group not found: ${n.logGroupId}`);return this.createSubscriptionFilter(n.logGroupId,{name:"KinesisSubscription",logGroupName:i.name,filterPattern:n.filterPattern||"",destinationArn:n.kinesisStreamArn,roleArn:n.roleArn,distribution:"Random"})}createLambdaSubscription(n){let i=this.logGroups.get(n.logGroupId);if(!i)throw Error(`Log group not found: ${n.logGroupId}`);return this.createSubscriptionFilter(n.logGroupId,{name:"LambdaSubscription",logGroupName:i.name,filterPattern:n.filterPattern||"",destinationArn:n.lambdaFunctionArn,distribution:"ByLogStream"})}createInsightsQuery(n){let i=`query-${Date.now()}-${this.queryCounter++}`,s={id:i,...n};return this.insightsQueries.set(i,s),s}createErrorAnalysisQuery(n){return this.createInsightsQuery({name:"Error Analysis",description:"Analyze error patterns and frequencies",query:`fields @timestamp, @message
3612
+ };`}clear(){this.tests.clear(),this.testCounter=0}}var tS=new Pl;class kl{rollouts=new Map;flags=new Map;gates=new Map;counter=0;createProgressiveRollout(n,i){let s=`rollout-${Date.now()}-${this.counter++}`,o={id:s,name:n,stages:i,currentStage:0};return this.rollouts.set(s,o),o}createFeatureFlag(n,i=0){let s=`flag-${Date.now()}-${this.counter++}`,o={id:s,name:n,enabled:!1,rolloutPercentage:i,targetingRules:[]};return this.flags.set(s,o),o}createDeploymentGate(n,i,s,o){let c=`gate-${Date.now()}-${this.counter++}`,u={id:c,name:n,type:i,approvers:s,conditions:o};return this.gates.set(c,u),u}clear(){this.rollouts.clear(),this.flags.clear(),this.gates.clear()}}var rS=new kl;class Zm{configs=new Map;samplingRules=new Map;configCounter=0;ruleCounter=0;createConfig(n){let i=`xray-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}createLambdaConfig(n){return this.createConfig({name:`${n.functionName}-xray`,serviceName:n.functionName,samplingRate:n.samplingRate||0.1,enableActiveTracing:!0})}createECSConfig(n){return this.createConfig({name:`${n.serviceName}-xray`,serviceName:`${n.clusterName}/${n.serviceName}`,samplingRate:n.samplingRate||0.05,enableActiveTracing:!0})}createAPIGatewayConfig(n){return this.createConfig({name:`${n.apiName}-${n.stage}-xray`,serviceName:`${n.apiName}/${n.stage}`,samplingRate:n.samplingRate||0.05,enableActiveTracing:!0})}createSamplingRule(n){let i=`sampling-rule-${Date.now()}-${this.ruleCounter++}`,s={id:i,...n};return this.samplingRules.set(i,s),s}createHighPrioritySamplingRule(n){return this.createSamplingRule({ruleName:n.ruleName,priority:100,fixedRate:1,reservoirSize:100,serviceName:n.serviceName,serviceType:"*",host:"*",httpMethod:"*",urlPath:n.urlPath,version:1})}createErrorSamplingRule(n){return this.createSamplingRule({ruleName:`${n}-errors`,priority:200,fixedRate:1,reservoirSize:50,serviceName:n,serviceType:"*",host:"*",httpMethod:"*",urlPath:"/error/*",version:1})}createDefaultSamplingRule(n,i=0.05){return this.createSamplingRule({ruleName:`${n}-default`,priority:1000,fixedRate:i,reservoirSize:10,serviceName:n,serviceType:"*",host:"*",httpMethod:"*",urlPath:"*",version:1})}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getSamplingRule(n){return this.samplingRules.get(n)}listSamplingRules(){return Array.from(this.samplingRules.values())}generateLambdaXRayCF(n){return{TracingConfig:{Mode:n.enableActiveTracing?"Active":"PassThrough"}}}generateAPIGatewayXRayCF(n){return{TracingEnabled:n.enableActiveTracing}}generateECSXRaySidecarCF(){return{Name:"xray-daemon",Image:"public.ecr.aws/xray/aws-xray-daemon:latest",Cpu:32,MemoryReservation:256,PortMappings:[{ContainerPort:2000,Protocol:"udp"}]}}generateSamplingRuleCF(n){return{Type:"AWS::XRay::SamplingRule",Properties:{SamplingRule:{RuleName:n.ruleName,Priority:n.priority,FixedRate:n.fixedRate,ReservoirSize:n.reservoirSize,ServiceName:n.serviceName,ServiceType:n.serviceType,Host:n.host,HTTPMethod:n.httpMethod,URLPath:n.urlPath,Version:n.version,ResourceARN:"*"}}}}createTrace(n,i){return{id:`trace-${Date.now()}-${this.configCounter++}`,traceId:n,spans:i}}clear(){this.configs.clear(),this.samplingRules.clear(),this.configCounter=0,this.ruleCounter=0}}var rE=new Zm;class ef{namespaces=new Map;metrics=new Map;namespaceCounter=0;metricCounter=0;alarmCounter=0;createNamespace(n){let i=`namespace-${Date.now()}-${this.namespaceCounter++}`,s={id:i,...n};return this.namespaces.set(i,s),s}createMetric(n){let i=`metric-${Date.now()}-${this.metricCounter++}`,s={id:i,...n};return this.metrics.set(i,s),s}createBusinessMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:n.unit,dimensions:[{name:"Environment",value:"production"},{name:"Type",value:"Business"}]})}createApplicationMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:n.unit,dimensions:[{name:"Service",value:n.serviceName},{name:"Type",value:"Application"}]})}createPerformanceMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:"Milliseconds",dimensions:[{name:"Operation",value:n.operation},{name:"Type",value:"Performance"}]})}createErrorMetric(n){return this.createMetric({name:n.name,namespace:n.namespace,unit:"Count",dimensions:[{name:"ErrorType",value:n.errorType},{name:"Type",value:"Error"}]})}createAlarm(n,i){let s=this.metrics.get(n);if(!s)throw Error(`Metric not found: ${n}`);let c={id:`alarm-${Date.now()}-${this.alarmCounter++}`,...i};if(!s.alarms)s.alarms=[];return s.alarms.push(c),c}createErrorRateAlarm(n){return this.createAlarm(n.metricId,{name:n.name,description:`Alert when error rate exceeds ${n.threshold} errors/min`,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:2,threshold:n.threshold,period:60,statistic:"Sum",treatMissingData:"notBreaching",actionsEnabled:!0,alarmActions:n.snsTopicArn?[n.snsTopicArn]:void 0})}createLatencyAlarm(n){return this.createAlarm(n.metricId,{name:n.name,description:`Alert when latency exceeds ${n.thresholdMs}ms`,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,threshold:n.thresholdMs,period:300,statistic:"Average",treatMissingData:"notBreaching",actionsEnabled:!0,alarmActions:n.snsTopicArn?[n.snsTopicArn]:void 0})}createThroughputAlarm(n){return this.createAlarm(n.metricId,{name:n.name,description:`Alert when throughput drops below ${n.minimumThreshold}`,comparisonOperator:"LessThanThreshold",evaluationPeriods:2,threshold:n.minimumThreshold,period:300,statistic:"Sum",treatMissingData:"breaching",actionsEnabled:!0,alarmActions:n.snsTopicArn?[n.snsTopicArn]:void 0})}createCompositeAlarm(n){return{name:n.name,description:n.description,alarmRule:n.alarmRule,actionsEnabled:n.actionsEnabled??!0,alarmActions:n.alarmActions}}getNamespace(n){return this.namespaces.get(n)}listNamespaces(){return Array.from(this.namespaces.values())}getMetric(n){return this.metrics.get(n)}listMetrics(){return Array.from(this.metrics.values())}generateAlarmCF(n,i){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:i.name,AlarmDescription:i.description,ComparisonOperator:i.comparisonOperator,EvaluationPeriods:i.evaluationPeriods,MetricName:n.name,Namespace:n.namespace,Period:i.period,Statistic:i.statistic,Threshold:i.threshold,TreatMissingData:i.treatMissingData||"notBreaching",ActionsEnabled:i.actionsEnabled??!0,...i.alarmActions&&{AlarmActions:i.alarmActions},...i.okActions&&{OKActions:i.okActions},...i.insufficientDataActions&&{InsufficientDataActions:i.insufficientDataActions},...n.dimensions&&{Dimensions:n.dimensions.map((s)=>({Name:s.name,Value:s.value}))}}}}generateCompositeAlarmCF(n){return{Type:"AWS::CloudWatch::CompositeAlarm",Properties:{AlarmName:n.name,AlarmDescription:n.description,AlarmRule:n.alarmRule,ActionsEnabled:n.actionsEnabled,...n.alarmActions&&{AlarmActions:n.alarmActions}}}}generateDashboardWidget(n){return{type:"metric",properties:{metrics:[[n.namespace,n.name,...n.dimensions?.flatMap((i)=>[i.name,i.value])||[]]],period:300,stat:"Average",region:"us-east-1",title:n.name}}}publishCustomMetric(n,i,s,o={},c="Count"){return{id:`metric-${Date.now()}-${this.metricCounter++}`,namespace:n,name:i,dimensions:o,value:s,unit:c,timestamp:new Date}}clear(){this.namespaces.clear(),this.metrics.clear(),this.namespaceCounter=0,this.metricCounter=0,this.alarmCounter=0}}var nE=new ef;class Nl{logGroups=new Map;queries=new Map;insightsQueries=new Map;logGroupCounter=0;filterCounter=0;queryCounter=0;createLogGroup(n){let i=`log-group-${Date.now()}-${this.logGroupCounter++}`,s={id:i,...n};return this.logGroups.set(i,s),s}createLambdaLogGroup(n,i=7){return this.createLogGroup({name:`/aws/lambda/${n}`,retentionDays:i})}createECSLogGroup(n){return this.createLogGroup({name:`/ecs/${n.clusterName}/${n.serviceName}`,retentionDays:n.retentionDays||14})}createAPIGatewayLogGroup(n,i,s=30){return this.createLogGroup({name:`/aws/apigateway/${n}/${i}`,retentionDays:s})}createApplicationLogGroup(n){return this.createLogGroup({name:`/application/${n.appName}/${n.environment}`,retentionDays:n.retentionDays||30,kmsKeyId:n.kmsKeyId})}createMetricFilter(n,i){let s=this.logGroups.get(n);if(!s)throw Error(`Log group not found: ${n}`);let c={id:`filter-${Date.now()}-${this.filterCounter++}`,...i};if(!s.metricFilters)s.metricFilters=[];return s.metricFilters.push(c),c}createErrorCountFilter(n,i){return this.createMetricFilter(n,{name:"ErrorCount",filterPattern:"[timestamp, request_id, level = ERROR*, ...]",metricTransformations:[{metricName:"ErrorCount",metricNamespace:i,metricValue:"1",defaultValue:0,unit:"Count"}]})}createLatencyFilter(n,i){return this.createMetricFilter(n,{name:"Latency",filterPattern:"[timestamp, request_id, level, duration, ...]",metricTransformations:[{metricName:"ResponseTime",metricNamespace:i,metricValue:"$duration",unit:"Milliseconds"}]})}createCustomPatternFilter(n){return this.createMetricFilter(n.logGroupId,{name:n.name,filterPattern:n.pattern,metricTransformations:[{metricName:n.metricName,metricNamespace:n.namespace,metricValue:"1",defaultValue:0,unit:"Count"}]})}createSubscriptionFilter(n,i){let s=this.logGroups.get(n);if(!s)throw Error(`Log group not found: ${n}`);let c={id:`subscription-${Date.now()}-${this.filterCounter++}`,...i};if(!s.subscriptionFilters)s.subscriptionFilters=[];return s.subscriptionFilters.push(c),c}createKinesisSubscription(n){let i=this.logGroups.get(n.logGroupId);if(!i)throw Error(`Log group not found: ${n.logGroupId}`);return this.createSubscriptionFilter(n.logGroupId,{name:"KinesisSubscription",logGroupName:i.name,filterPattern:n.filterPattern||"",destinationArn:n.kinesisStreamArn,roleArn:n.roleArn,distribution:"Random"})}createLambdaSubscription(n){let i=this.logGroups.get(n.logGroupId);if(!i)throw Error(`Log group not found: ${n.logGroupId}`);return this.createSubscriptionFilter(n.logGroupId,{name:"LambdaSubscription",logGroupName:i.name,filterPattern:n.filterPattern||"",destinationArn:n.lambdaFunctionArn,distribution:"ByLogStream"})}createInsightsQuery(n){let i=`query-${Date.now()}-${this.queryCounter++}`,s={id:i,...n};return this.insightsQueries.set(i,s),s}createErrorAnalysisQuery(n){return this.createInsightsQuery({name:"Error Analysis",description:"Analyze error patterns and frequencies",query:`fields @timestamp, @message
3613
3613
  | filter @message like /ERROR/
3614
3614
  | stats count() by bin(5m)
3615
3615
  | sort @timestamp desc`,logGroupNames:n})}createLatencyAnalysisQuery(n){return this.createInsightsQuery({name:"Latency Analysis",description:"Analyze request latency patterns",query:`fields @timestamp, @duration
@@ -3619,7 +3619,7 @@ exports.handler = (event, _context, _callback) => {
3619
3619
  | filter @message like /ERROR/
3620
3620
  | stats count() as error_count by @message
3621
3621
  | sort error_count desc
3622
- | limit 20`,logGroupNames:n})}getLogGroup(n){return this.logGroups.get(n)}listLogGroups(){return Array.from(this.logGroups.values())}getInsightsQuery(n){return this.insightsQueries.get(n)}listInsightsQueries(){return Array.from(this.insightsQueries.values())}generateLogGroupCF(n){return{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:n.name,...n.retentionDays&&{RetentionInDays:n.retentionDays},...n.kmsKeyId&&{KmsKeyId:n.kmsKeyId}}}}generateMetricFilterCF(n,i){return{Type:"AWS::Logs::MetricFilter",Properties:{FilterName:i.name,FilterPattern:i.filterPattern,LogGroupName:n.name,MetricTransformations:i.metricTransformations.map((s)=>({MetricName:s.metricName,MetricNamespace:s.metricNamespace,MetricValue:s.metricValue,...s.defaultValue!==void 0&&{DefaultValue:s.defaultValue},...s.unit&&{Unit:s.unit},...s.dimensions&&{Dimensions:s.dimensions}}))}}}generateSubscriptionFilterCF(n){return{Type:"AWS::Logs::SubscriptionFilter",Properties:{FilterName:n.name,FilterPattern:n.filterPattern,LogGroupName:n.logGroupName,DestinationArn:n.destinationArn,...n.roleArn&&{RoleArn:n.roleArn},...n.distribution&&{Distribution:n.distribution}}}}generateQueryDefinitionCF(n){return{Type:"AWS::Logs::QueryDefinition",Properties:{Name:n.name,QueryString:n.query,LogGroupNames:n.logGroupNames}}}createLogAggregation(n,i,s=7){let o=`aggregation-${Date.now()}-${this.logGroupCounter++}`,c=this.createLogGroup({name:n,retentionDays:s});return i.forEach((u)=>{this.createMetricFilter(c.id,{name:u.metric,filterPattern:u.pattern,metricTransformations:[{metricName:u.metric,metricNamespace:"CustomMetrics",metricValue:"1",defaultValue:0,unit:"Count"}]})}),{id:o,logGroup:n,filters:i,retention:s}}clear(){this.logGroups.clear(),this.queries.clear(),this.insightsQueries.clear(),this.logGroupCounter=0,this.filterCounter=0,this.queryCounter=0}}var rS=new Nl;class fr{canaries=new Map;heartbeats=new Map;apiMonitors=new Map;canaryCounter=0;heartbeatCounter=0;apiMonitorCounter=0;alarmCounter=0;static RuntimeVersions={NODEJS_PUPPETEER_3_9:"syn-nodejs-puppeteer-3.9",NODEJS_PUPPETEER_4_0:"syn-nodejs-puppeteer-4.0",PYTHON_SELENIUM_1_3:"syn-python-selenium-1.3"};createCanary(n){let i=`canary-${Date.now()}-${this.canaryCounter++}`,s={id:i,...n};return this.canaries.set(i,s),s}createHeartbeatCanary(n){let i=`
3622
+ | limit 20`,logGroupNames:n})}getLogGroup(n){return this.logGroups.get(n)}listLogGroups(){return Array.from(this.logGroups.values())}getInsightsQuery(n){return this.insightsQueries.get(n)}listInsightsQueries(){return Array.from(this.insightsQueries.values())}generateLogGroupCF(n){return{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:n.name,...n.retentionDays&&{RetentionInDays:n.retentionDays},...n.kmsKeyId&&{KmsKeyId:n.kmsKeyId}}}}generateMetricFilterCF(n,i){return{Type:"AWS::Logs::MetricFilter",Properties:{FilterName:i.name,FilterPattern:i.filterPattern,LogGroupName:n.name,MetricTransformations:i.metricTransformations.map((s)=>({MetricName:s.metricName,MetricNamespace:s.metricNamespace,MetricValue:s.metricValue,...s.defaultValue!==void 0&&{DefaultValue:s.defaultValue},...s.unit&&{Unit:s.unit},...s.dimensions&&{Dimensions:s.dimensions}}))}}}generateSubscriptionFilterCF(n){return{Type:"AWS::Logs::SubscriptionFilter",Properties:{FilterName:n.name,FilterPattern:n.filterPattern,LogGroupName:n.logGroupName,DestinationArn:n.destinationArn,...n.roleArn&&{RoleArn:n.roleArn},...n.distribution&&{Distribution:n.distribution}}}}generateQueryDefinitionCF(n){return{Type:"AWS::Logs::QueryDefinition",Properties:{Name:n.name,QueryString:n.query,LogGroupNames:n.logGroupNames}}}createLogAggregation(n,i,s=7){let o=`aggregation-${Date.now()}-${this.logGroupCounter++}`,c=this.createLogGroup({name:n,retentionDays:s});return i.forEach((u)=>{this.createMetricFilter(c.id,{name:u.metric,filterPattern:u.pattern,metricTransformations:[{metricName:u.metric,metricNamespace:"CustomMetrics",metricValue:"1",defaultValue:0,unit:"Count"}]})}),{id:o,logGroup:n,filters:i,retention:s}}clear(){this.logGroups.clear(),this.queries.clear(),this.insightsQueries.clear(),this.logGroupCounter=0,this.filterCounter=0,this.queryCounter=0}}var nS=new Nl;class fr{canaries=new Map;heartbeats=new Map;apiMonitors=new Map;canaryCounter=0;heartbeatCounter=0;apiMonitorCounter=0;alarmCounter=0;static RuntimeVersions={NODEJS_PUPPETEER_3_9:"syn-nodejs-puppeteer-3.9",NODEJS_PUPPETEER_4_0:"syn-nodejs-puppeteer-4.0",PYTHON_SELENIUM_1_3:"syn-python-selenium-1.3"};createCanary(n){let i=`canary-${Date.now()}-${this.canaryCounter++}`,s={id:i,...n};return this.canaries.set(i,s),s}createHeartbeatCanary(n){let i=`
3623
3623
  const synthetics = require('Synthetics');
3624
3624
  const log = require('SyntheticsLogger');
3625
3625
 
@@ -3710,35 +3710,35 @@ const workflowCheck = async function () {
3710
3710
  exports.handler = async () => {
3711
3711
  return await workflowCheck();
3712
3712
  };
3713
- `;return this.createCanary({name:n.name,description:n.description,runtimeVersion:fr.RuntimeVersions.NODEJS_PUPPETEER_4_0,handler:"index.handler",code:{type:"script",script:s},schedule:{expression:`rate(${n.interval} minutes)`},runConfig:{timeoutInSeconds:180,memoryInMB:1024,activeTracing:!0},artifactS3Location:`s3://${n.s3Bucket}/canary-artifacts/${n.name}/`,successRetentionPeriod:31,failureRetentionPeriod:31})}generateActionScript(n){switch(n.type){case"click":return`await page.click('${n.selector}');`;case"type":return`await page.type('${n.selector}', '${n.value}');`;case"wait":return`await page.waitForTimeout(${n.duration});`;case"waitForSelector":return`await page.waitForSelector('${n.selector}');`;default:return""}}createAlarm(n,i){let s=this.canaries.get(n);if(!s)throw Error(`Canary not found: ${n}`);let c={id:`alarm-${Date.now()}-${this.alarmCounter++}`,...i};if(!s.alarms)s.alarms=[];return s.alarms.push(c),c}getCanary(n){return this.canaries.get(n)}listCanaries(){return Array.from(this.canaries.values())}generateCanaryCF(n){let i={Type:"AWS::Synthetics::Canary",Properties:{Name:n.name,RuntimeVersion:n.runtimeVersion,ExecutionRoleArn:{"Fn::GetAtt":["CanaryExecutionRole","Arn"]},Schedule:{Expression:n.schedule.expression,...n.schedule.durationInSeconds&&{DurationInSeconds:n.schedule.durationInSeconds}},ArtifactS3Location:n.artifactS3Location,StartCanaryAfterCreation:!0}};if(n.code.type==="script")i.Properties.Code={Handler:n.handler,Script:n.code.script};else i.Properties.Code={Handler:n.handler,S3Bucket:n.code.s3Bucket,S3Key:n.code.s3Key,...n.code.s3Version&&{S3ObjectVersion:n.code.s3Version}};if(n.runConfig)i.Properties.RunConfig={TimeoutInSeconds:n.runConfig.timeoutInSeconds,MemoryInMB:n.runConfig.memoryInMB,...n.runConfig.environmentVariables&&{EnvironmentVariables:n.runConfig.environmentVariables},...n.runConfig.activeTracing!==void 0&&{ActiveTracing:n.runConfig.activeTracing}};if(n.vpcConfig)i.Properties.VPCConfig={SubnetIds:n.vpcConfig.subnetIds,SecurityGroupIds:n.vpcConfig.securityGroupIds};if(n.successRetentionPeriod)i.Properties.SuccessRetentionPeriod=n.successRetentionPeriod;if(n.failureRetentionPeriod)i.Properties.FailureRetentionPeriod=n.failureRetentionPeriod;return i}generateCanaryRoleCF(){return{Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole","arn:aws:iam::aws:policy/CloudWatchSyntheticsFullAccess"],Policies:[{PolicyName:"CanaryS3Policy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:PutObject","s3:GetBucketLocation"],Resource:["arn:aws:s3:::*/*"]}]}}]}}}clear(){this.canaries.clear(),this.heartbeats.clear(),this.apiMonitors.clear(),this.canaryCounter=0,this.heartbeatCounter=0,this.apiMonitorCounter=0,this.alarmCounter=0}}var nS=new fr;class ef{plans=new Map;migrations=new Map;planCounter=0;migrationCounter=0;createPlan(n){let i=`migration-plan-${Date.now()}-${this.planCounter++}`,s={id:i,...n};return this.plans.set(i,s),s}createMigration(n){let i=`migration-${Date.now()}-${this.migrationCounter++}`,s=this.generateChecksum(n.up+n.down),o={id:i,checksum:s,...n};return this.migrations.set(i,o),o}createSchemaMigration(n){let{up:i,down:s}=this.generateSchemaSQL(n.changes,n.tableName,n.engine);return this.createMigration({version:n.version,name:n.name,description:`Schema changes for ${n.tableName}`,up:i,down:s})}createDataMigration(n){return this.createMigration({version:n.version,name:n.name,description:n.description,up:n.upSQL,down:n.downSQL})}addMigrationToPlan(n,i){let s=this.plans.get(n);if(!s)throw Error(`Migration plan not found: ${n}`);s.migrations.push(i)}async executePlan(n,i=!1){let s=this.plans.get(n);if(!s)throw Error(`Migration plan not found: ${n}`);let o=Date.now(),c=[],u=[];if(console.log(`${i?"[DRY RUN] ":""}Executing migration plan: ${s.name}`),console.log(`Database: ${s.database.type} - ${s.database.identifier}`),console.log(`Migrations to apply: ${s.migrations.length}
3713
+ `;return this.createCanary({name:n.name,description:n.description,runtimeVersion:fr.RuntimeVersions.NODEJS_PUPPETEER_4_0,handler:"index.handler",code:{type:"script",script:s},schedule:{expression:`rate(${n.interval} minutes)`},runConfig:{timeoutInSeconds:180,memoryInMB:1024,activeTracing:!0},artifactS3Location:`s3://${n.s3Bucket}/canary-artifacts/${n.name}/`,successRetentionPeriod:31,failureRetentionPeriod:31})}generateActionScript(n){switch(n.type){case"click":return`await page.click('${n.selector}');`;case"type":return`await page.type('${n.selector}', '${n.value}');`;case"wait":return`await page.waitForTimeout(${n.duration});`;case"waitForSelector":return`await page.waitForSelector('${n.selector}');`;default:return""}}createAlarm(n,i){let s=this.canaries.get(n);if(!s)throw Error(`Canary not found: ${n}`);let c={id:`alarm-${Date.now()}-${this.alarmCounter++}`,...i};if(!s.alarms)s.alarms=[];return s.alarms.push(c),c}getCanary(n){return this.canaries.get(n)}listCanaries(){return Array.from(this.canaries.values())}generateCanaryCF(n){let i={Type:"AWS::Synthetics::Canary",Properties:{Name:n.name,RuntimeVersion:n.runtimeVersion,ExecutionRoleArn:{"Fn::GetAtt":["CanaryExecutionRole","Arn"]},Schedule:{Expression:n.schedule.expression,...n.schedule.durationInSeconds&&{DurationInSeconds:n.schedule.durationInSeconds}},ArtifactS3Location:n.artifactS3Location,StartCanaryAfterCreation:!0}};if(n.code.type==="script")i.Properties.Code={Handler:n.handler,Script:n.code.script};else i.Properties.Code={Handler:n.handler,S3Bucket:n.code.s3Bucket,S3Key:n.code.s3Key,...n.code.s3Version&&{S3ObjectVersion:n.code.s3Version}};if(n.runConfig)i.Properties.RunConfig={TimeoutInSeconds:n.runConfig.timeoutInSeconds,MemoryInMB:n.runConfig.memoryInMB,...n.runConfig.environmentVariables&&{EnvironmentVariables:n.runConfig.environmentVariables},...n.runConfig.activeTracing!==void 0&&{ActiveTracing:n.runConfig.activeTracing}};if(n.vpcConfig)i.Properties.VPCConfig={SubnetIds:n.vpcConfig.subnetIds,SecurityGroupIds:n.vpcConfig.securityGroupIds};if(n.successRetentionPeriod)i.Properties.SuccessRetentionPeriod=n.successRetentionPeriod;if(n.failureRetentionPeriod)i.Properties.FailureRetentionPeriod=n.failureRetentionPeriod;return i}generateCanaryRoleCF(){return{Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole","arn:aws:iam::aws:policy/CloudWatchSyntheticsFullAccess"],Policies:[{PolicyName:"CanaryS3Policy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:PutObject","s3:GetBucketLocation"],Resource:["arn:aws:s3:::*/*"]}]}}]}}}clear(){this.canaries.clear(),this.heartbeats.clear(),this.apiMonitors.clear(),this.canaryCounter=0,this.heartbeatCounter=0,this.apiMonitorCounter=0,this.alarmCounter=0}}var iS=new fr;class tf{plans=new Map;migrations=new Map;planCounter=0;migrationCounter=0;createPlan(n){let i=`migration-plan-${Date.now()}-${this.planCounter++}`,s={id:i,...n};return this.plans.set(i,s),s}createMigration(n){let i=`migration-${Date.now()}-${this.migrationCounter++}`,s=this.generateChecksum(n.up+n.down),o={id:i,checksum:s,...n};return this.migrations.set(i,o),o}createSchemaMigration(n){let{up:i,down:s}=this.generateSchemaSQL(n.changes,n.tableName,n.engine);return this.createMigration({version:n.version,name:n.name,description:`Schema changes for ${n.tableName}`,up:i,down:s})}createDataMigration(n){return this.createMigration({version:n.version,name:n.name,description:n.description,up:n.upSQL,down:n.downSQL})}addMigrationToPlan(n,i){let s=this.plans.get(n);if(!s)throw Error(`Migration plan not found: ${n}`);s.migrations.push(i)}async executePlan(n,i=!1){let s=this.plans.get(n);if(!s)throw Error(`Migration plan not found: ${n}`);let o=Date.now(),c=[],u=[];if(console.log(`${i?"[DRY RUN] ":""}Executing migration plan: ${s.name}`),console.log(`Database: ${s.database.type} - ${s.database.identifier}`),console.log(`Migrations to apply: ${s.migrations.length}
3714
3714
  `),s.backupBeforeMigration&&!i)console.log("Creating database backup before migration...");for(let p of s.migrations)try{if(console.log(`Applying migration: ${p.version} - ${p.name}`),!i){if(this.generateChecksum(p.up+p.down)!==p.checksum)throw Error("Migration checksum mismatch - migration has been modified");let h=Date.now();p.appliedAt=new Date,p.executionTimeMs=Date.now()-h,console.log(`✓ Applied in ${p.executionTimeMs}ms
3715
3715
  `)}else console.log(`[SKIPPED - DRY RUN]
3716
3716
  `);c.push(p.version)}catch(y){if(console.error(`✗ Failed: ${y instanceof Error?y.message:String(y)}
3717
3717
  `),u.push(p.version),!i)return console.log("Rolling back previously applied migrations..."),await this.rollbackMigrations(c.reverse(),s),{success:!1,version:p.version,appliedMigrations:[],failedMigrations:u,executionTimeMs:Date.now()-o,error:y instanceof Error?y.message:String(y),rollbackPerformed:!0}}let d=Date.now()-o;return console.log(`${i?"[DRY RUN] ":""}Migration plan completed successfully`),console.log(`Total time: ${d}ms`),{success:!0,version:s.migrations[s.migrations.length-1]?.version||"unknown",appliedMigrations:c,failedMigrations:u,executionTimeMs:d}}async rollbackMigrations(n,i){for(let s of n){let o=i.migrations.find((c)=>c.version===s);if(o)console.log(`Rolling back: ${o.version} - ${o.name}`),o.rolledBackAt=new Date,console.log(`✓ Rolled back
3718
3718
  `)}}getMigrationStatus(n){let i=this.plans.get(n);if(!i)throw Error(`Migration plan not found: ${n}`);let s=i.migrations.filter((c)=>c.appliedAt&&!c.rolledBackAt),o=i.migrations.filter((c)=>!c.appliedAt);return{currentVersion:s[s.length-1]?.version||"0.0.0",pendingMigrations:o,appliedMigrations:s,lastMigration:s[s.length-1]}}generateSchemaSQL(n,i,s="postgres"){let o=[],c=[];for(let u of n)switch(u.type){case"add_column":o.push(`ALTER TABLE ${i} ADD COLUMN ${u.columnName} ${u.columnType}${u.nullable===!1?" NOT NULL":""}${u.defaultValue?` DEFAULT ${u.defaultValue}`:""}; `),c.push(`ALTER TABLE ${i} DROP COLUMN ${u.columnName};`);break;case"drop_column":o.push(`ALTER TABLE ${i} DROP COLUMN ${u.columnName};`),c.push(`-- Cannot restore dropped column ${u.columnName}`);break;case"modify_column":if(s==="postgres")o.push(`ALTER TABLE ${i} ALTER COLUMN ${u.columnName} TYPE ${u.newType};`);else o.push(`ALTER TABLE ${i} MODIFY COLUMN ${u.columnName} ${u.newType};`);c.push(`-- Reverting ${u.columnName} type change requires manual intervention`);break;case"add_index":o.push(`CREATE INDEX ${u.indexName} ON ${i} (${(u.columns??[]).join(", ")});`),c.push(`DROP INDEX ${u.indexName};`);break;case"drop_index":o.push(`DROP INDEX ${u.indexName};`),c.push(`-- Cannot restore index ${u.indexName} without schema details`);break}return{up:o.join(`
3719
3719
  `),down:c.reverse().join(`
3720
- `)}}generateChecksum(n){let i=0;for(let s=0;s<n.length;s++){let o=n.charCodeAt(s);i=(i<<5)-i+o,i=i&i}return i.toString(16)}validatePlan(n){let i=this.plans.get(n);if(!i)return{valid:!1,errors:["Migration plan not found"]};let s=[],o=new Set;for(let c of i.migrations){if(o.has(c.version))s.push(`Duplicate migration version: ${c.version}`);o.add(c.version)}for(let c of i.migrations)if(!c.down||c.down.trim()==="")s.push(`Migration ${c.version} is missing rollback SQL`);for(let c of i.migrations)if(this.generateChecksum(c.up+c.down)!==c.checksum)s.push(`Migration ${c.version} has invalid checksum`);return{valid:s.length===0,errors:s}}getPlan(n){return this.plans.get(n)}listPlans(){return Array.from(this.plans.values())}getMigration(n){return this.migrations.get(n)}listMigrations(){return Array.from(this.migrations.values())}clear(){this.plans.clear(),this.migrations.clear(),this.planCounter=0,this.migrationCounter=0}}var nE=new ef;class Bl{replicas=new Map;replicationGroups=new Map;proxies=new Map;proxyTargets=new Map;replicaCounter=0;groupCounter=0;proxyCounter=0;targetCounter=0;createReplica(n){let i=`replica-${Date.now()}-${this.replicaCounter++}`,s={id:i,status:"creating",...n};return this.replicas.set(i,s),s}createRDSReplica(n){return this.createReplica({name:n.name,sourceDatabase:n.sourceDatabase,region:n.region||"us-east-1",instanceClass:n.instanceClass||"db.t3.medium",multiAZ:n.multiAZ||!1,autoMinorVersionUpgrade:!0,backupRetentionPeriod:7})}createCrossRegionReplica(n){return this.createReplica({name:n.name,sourceDatabase:n.sourceDatabase,region:n.targetRegion,instanceClass:n.instanceClass||"db.t3.medium",multiAZ:!0,autoMinorVersionUpgrade:!0,backupRetentionPeriod:7})}createReplicationGroup(n){let i=`replication-group-${Date.now()}-${this.groupCounter++}`,s={id:i,...n};return this.replicationGroups.set(i,s),s}createAutoScalingReplicationGroup(n){return this.createReplicationGroup({name:n.name,primaryDatabase:n.primaryDatabase,replicas:[],loadBalancing:n.loadBalancing||{type:"round-robin"},failoverEnabled:!0,autoScaling:{enabled:!0,minReplicas:n.minReplicas,maxReplicas:n.maxReplicas,targetCPU:n.targetCPU||70,scaleUpCooldown:300,scaleDownCooldown:600}})}addReplicaToGroup(n,i){let s=this.replicationGroups.get(n);if(!s)throw Error(`Replication group not found: ${n}`);s.replicas.push(i)}createProxy(n){let i=`rds-proxy-${Date.now()}-${this.proxyCounter++}`,s={id:i,...n};return this.proxies.set(i,s),s}createConnectionPoolProxy(n){return this.createProxy({name:n.name,engineFamily:n.engineFamily,targetDatabase:n.targetDatabase,maxConnectionsPercent:n.maxConnections||100,maxIdleConnectionsPercent:50,connectionBorrowTimeout:120,sessionPinningFilters:["EXCLUDE_VARIABLE_SETS"],requireTLS:!0,idleClientTimeout:1800,vpcSubnetIds:n.vpcSubnetIds,securityGroupIds:n.securityGroupIds,secretArn:n.secretArn})}createServerlessProxy(n){return this.createProxy({name:n.name,engineFamily:n.engineFamily,targetDatabase:n.targetDatabase,maxConnectionsPercent:100,maxIdleConnectionsPercent:10,connectionBorrowTimeout:60,sessionPinningFilters:["EXCLUDE_VARIABLE_SETS"],requireTLS:!0,idleClientTimeout:300,vpcSubnetIds:n.vpcSubnetIds,securityGroupIds:n.securityGroupIds,secretArn:n.secretArn})}addProxyTarget(n){let i=`proxy-target-${Date.now()}-${this.targetCounter++}`,s={id:i,...n};return this.proxyTargets.set(i,s),s}promoteReplica(n){let i=this.replicas.get(n);if(!i)return{success:!1,message:"Replica not found"};if(console.log(`Promoting replica to primary: ${i.name}`),console.log(`Region: ${i.region}`),console.log(`
3720
+ `)}}generateChecksum(n){let i=0;for(let s=0;s<n.length;s++){let o=n.charCodeAt(s);i=(i<<5)-i+o,i=i&i}return i.toString(16)}validatePlan(n){let i=this.plans.get(n);if(!i)return{valid:!1,errors:["Migration plan not found"]};let s=[],o=new Set;for(let c of i.migrations){if(o.has(c.version))s.push(`Duplicate migration version: ${c.version}`);o.add(c.version)}for(let c of i.migrations)if(!c.down||c.down.trim()==="")s.push(`Migration ${c.version} is missing rollback SQL`);for(let c of i.migrations)if(this.generateChecksum(c.up+c.down)!==c.checksum)s.push(`Migration ${c.version} has invalid checksum`);return{valid:s.length===0,errors:s}}getPlan(n){return this.plans.get(n)}listPlans(){return Array.from(this.plans.values())}getMigration(n){return this.migrations.get(n)}listMigrations(){return Array.from(this.migrations.values())}clear(){this.plans.clear(),this.migrations.clear(),this.planCounter=0,this.migrationCounter=0}}var iE=new tf;class Bl{replicas=new Map;replicationGroups=new Map;proxies=new Map;proxyTargets=new Map;replicaCounter=0;groupCounter=0;proxyCounter=0;targetCounter=0;createReplica(n){let i=`replica-${Date.now()}-${this.replicaCounter++}`,s={id:i,status:"creating",...n};return this.replicas.set(i,s),s}createRDSReplica(n){return this.createReplica({name:n.name,sourceDatabase:n.sourceDatabase,region:n.region||"us-east-1",instanceClass:n.instanceClass||"db.t3.medium",multiAZ:n.multiAZ||!1,autoMinorVersionUpgrade:!0,backupRetentionPeriod:7})}createCrossRegionReplica(n){return this.createReplica({name:n.name,sourceDatabase:n.sourceDatabase,region:n.targetRegion,instanceClass:n.instanceClass||"db.t3.medium",multiAZ:!0,autoMinorVersionUpgrade:!0,backupRetentionPeriod:7})}createReplicationGroup(n){let i=`replication-group-${Date.now()}-${this.groupCounter++}`,s={id:i,...n};return this.replicationGroups.set(i,s),s}createAutoScalingReplicationGroup(n){return this.createReplicationGroup({name:n.name,primaryDatabase:n.primaryDatabase,replicas:[],loadBalancing:n.loadBalancing||{type:"round-robin"},failoverEnabled:!0,autoScaling:{enabled:!0,minReplicas:n.minReplicas,maxReplicas:n.maxReplicas,targetCPU:n.targetCPU||70,scaleUpCooldown:300,scaleDownCooldown:600}})}addReplicaToGroup(n,i){let s=this.replicationGroups.get(n);if(!s)throw Error(`Replication group not found: ${n}`);s.replicas.push(i)}createProxy(n){let i=`rds-proxy-${Date.now()}-${this.proxyCounter++}`,s={id:i,...n};return this.proxies.set(i,s),s}createConnectionPoolProxy(n){return this.createProxy({name:n.name,engineFamily:n.engineFamily,targetDatabase:n.targetDatabase,maxConnectionsPercent:n.maxConnections||100,maxIdleConnectionsPercent:50,connectionBorrowTimeout:120,sessionPinningFilters:["EXCLUDE_VARIABLE_SETS"],requireTLS:!0,idleClientTimeout:1800,vpcSubnetIds:n.vpcSubnetIds,securityGroupIds:n.securityGroupIds,secretArn:n.secretArn})}createServerlessProxy(n){return this.createProxy({name:n.name,engineFamily:n.engineFamily,targetDatabase:n.targetDatabase,maxConnectionsPercent:100,maxIdleConnectionsPercent:10,connectionBorrowTimeout:60,sessionPinningFilters:["EXCLUDE_VARIABLE_SETS"],requireTLS:!0,idleClientTimeout:300,vpcSubnetIds:n.vpcSubnetIds,securityGroupIds:n.securityGroupIds,secretArn:n.secretArn})}addProxyTarget(n){let i=`proxy-target-${Date.now()}-${this.targetCounter++}`,s={id:i,...n};return this.proxyTargets.set(i,s),s}promoteReplica(n){let i=this.replicas.get(n);if(!i)return{success:!1,message:"Replica not found"};if(console.log(`Promoting replica to primary: ${i.name}`),console.log(`Region: ${i.region}`),console.log(`
3721
3721
  1. Checking replication lag...`),i.replicationLag&&i.replicationLag>5000)return{success:!1,message:`Replication lag too high: ${i.replicationLag}ms`};return console.log(` Replication lag: ${i.replicationLag||0}ms (acceptable)`),console.log(`
3722
3722
  2. Promoting replica to standalone instance...`),console.log(`
3723
3723
  3. Updating DNS records...`),console.log(`
3724
3724
  4. Updating application configuration...`),console.log(`
3725
- ✓ Promotion completed successfully`),i.status="available",{success:!0,message:"Replica promoted successfully"}}getReplicationLag(n){if(!this.replicas.get(n))throw Error(`Replica not found: ${n}`);return Math.floor(Math.random()*1000)}getReplica(n){return this.replicas.get(n)}listReplicas(){return Array.from(this.replicas.values())}getReplicationGroup(n){return this.replicationGroups.get(n)}listReplicationGroups(){return Array.from(this.replicationGroups.values())}getProxy(n){return this.proxies.get(n)}listProxies(){return Array.from(this.proxies.values())}generateReplicaCF(n){return{Type:"AWS::RDS::DBInstance",Properties:{SourceDBInstanceIdentifier:n.sourceDatabase,DBInstanceIdentifier:n.name,DBInstanceClass:n.instanceClass,MultiAZ:n.multiAZ||!1,AutoMinorVersionUpgrade:n.autoMinorVersionUpgrade??!0,...n.backupRetentionPeriod&&{BackupRetentionPeriod:n.backupRetentionPeriod},...n.preferredBackupWindow&&{PreferredBackupWindow:n.preferredBackupWindow},...n.preferredMaintenanceWindow&&{PreferredMaintenanceWindow:n.preferredMaintenanceWindow}}}}generateProxyCF(n){return{Type:"AWS::RDS::DBProxy",Properties:{DBProxyName:n.name,EngineFamily:n.engineFamily,Auth:[{AuthScheme:"SECRETS",SecretArn:n.secretArn,IAMAuth:"DISABLED"}],RoleArn:{"Fn::GetAtt":["RDSProxyRole","Arn"]},VpcSubnetIds:n.vpcSubnetIds,VpcSecurityGroupIds:n.securityGroupIds,RequireTLS:n.requireTLS??!0,IdleClientTimeout:n.idleClientTimeout||1800,...n.maxConnectionsPercent&&{MaxConnectionsPercent:n.maxConnectionsPercent},...n.maxIdleConnectionsPercent&&{MaxIdleConnectionsPercent:n.maxIdleConnectionsPercent},...n.connectionBorrowTimeout&&{ConnectionBorrowTimeout:n.connectionBorrowTimeout}}}}generateProxyTargetCF(n,i){return{Type:"AWS::RDS::DBProxyTargetGroup",Properties:{DBProxyName:i.name,TargetGroupName:"default",DBInstanceIdentifiers:[n.targetArn],ConnectionPoolConfig:{MaxConnectionsPercent:100,MaxIdleConnectionsPercent:50,ConnectionBorrowTimeout:120}}}}generateProxyRoleCF(){return{Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"rds.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"RDSProxySecretsPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],Resource:"arn:aws:secretsmanager:*:*:secret:*"},{Effect:"Allow",Action:["kms:Decrypt"],Resource:"arn:aws:kms:*:*:key/*",Condition:{StringEquals:{"kms:ViaService":"secretsmanager.*.amazonaws.com"}}}]}}]}}}clear(){this.replicas.clear(),this.replicationGroups.clear(),this.proxies.clear(),this.proxyTargets.clear(),this.replicaCounter=0,this.groupCounter=0,this.proxyCounter=0,this.targetCounter=0}}var iS=new Bl;class tf{insights=new Map;slowQueryLogs=new Map;queryMetrics=new Map;reports=new Map;indexRecommendations=new Map;insightsCounter=0;logCounter=0;metricCounter=0;reportCounter=0;recommendationCounter=0;enablePerformanceInsights(n){let i=`pi-${Date.now()}-${this.insightsCounter++}`,s={id:i,name:n.name,databaseIdentifier:n.databaseIdentifier,enabled:!0,retentionPeriod:n.retentionPeriod||7,kmsKeyId:n.kmsKeyId};return this.insights.set(i,s),s}enableSlowQueryLog(n){let i=`slow-query-${Date.now()}-${this.logCounter++}`,s={id:i,name:n.name,databaseIdentifier:n.databaseIdentifier,enabled:!0,logDestination:n.logDestination,cloudwatchLogGroup:n.cloudwatchLogGroup,s3Bucket:n.s3Bucket,s3Prefix:n.s3Bucket?"slow-queries/":void 0,minExecutionTime:n.minExecutionTime||1000};return this.slowQueryLogs.set(i,s),s}recordQueryMetric(n){let i=`metric-${Date.now()}-${this.metricCounter++}`,s={id:i,timestamp:new Date,...n};return this.queryMetrics.set(i,s),s}generatePerformanceReport(n){let i=`report-${Date.now()}-${this.reportCounter++}`,s={avgCPU:Math.random()*60+20,maxCPU:Math.random()*30+70,avgConnections:Math.floor(Math.random()*50+10),maxConnections:Math.floor(Math.random()*50+100),avgReadIOPS:Math.floor(Math.random()*1000+500),avgWriteIOPS:Math.floor(Math.random()*500+200),avgReadThroughput:Math.random()*50+10,avgWriteThroughput:Math.random()*20+5,avgReadLatency:Math.random()*5+1,avgWriteLatency:Math.random()*8+2,cacheHitRatio:Math.random()*10+90,deadlocks:Math.floor(Math.random()*5),longRunningTransactions:Math.floor(Math.random()*10)},o=Array.from(this.queryMetrics.values()),c=o.sort((y,h)=>h.executionCount-y.executionCount).slice(0,10),u=o.filter((y)=>y.avgExecutionTime>1000).sort((y,h)=>h.avgExecutionTime-y.avgExecutionTime).slice(0,10),d=this.generateRecommendations(s,u),p={id:i,name:n.name,databaseIdentifier:n.databaseIdentifier,reportType:n.reportType,metrics:s,topQueries:c,slowQueries:u,recommendations:d,generatedAt:new Date};return this.reports.set(i,p),p}generateRecommendations(n,i){let s=[];if(n.avgCPU>70)s.push({type:"scaling",severity:"high",title:"High CPU Usage",description:`Average CPU usage is ${n.avgCPU.toFixed(1)}%, which is above the recommended threshold of 70%.`,impact:"Performance degradation, increased latency, potential timeouts",effort:"medium"});if(n.cacheHitRatio<95)s.push({type:"configuration",severity:"medium",title:"Low Cache Hit Ratio",description:`Cache hit ratio is ${n.cacheHitRatio.toFixed(1)}%. Consider increasing buffer pool size.`,impact:"Increased disk I/O, slower query performance",effort:"low"});if(n.deadlocks>0)s.push({type:"query",severity:"medium",title:"Deadlocks Detected",description:`${n.deadlocks} deadlock(s) detected. Review transaction isolation levels and query patterns.`,impact:"Transaction failures, application errors",effort:"high"});if(i.length>0)s.push({type:"index",severity:"high",title:"Slow Queries Detected",description:`${i.length} slow queries detected. Consider adding indexes or optimizing queries.`,impact:"High latency, poor user experience",effort:"medium"});if(n.avgReadLatency>10||n.avgWriteLatency>10)s.push({type:"scaling",severity:"high",title:"High I/O Latency",description:"Read or write latency is high. Consider upgrading to Provisioned IOPS or moving to a larger instance.",impact:"Slow query execution, application timeouts",effort:"medium"});return s}analyzeQuery(n){let i=`analysis-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,s=[{id:1,operation:"Seq Scan",table:"users",rows:1e4,cost:850.5,children:[]}],o=[];if(n.toLowerCase().includes("select *"))o.push({type:"full_table_scan",severity:"warning",description:"Query selects all columns. Consider selecting only required columns."});if(!n.toLowerCase().includes("where")&&n.toLowerCase().includes("select"))o.push({type:"full_table_scan",severity:"critical",description:"Query has no WHERE clause and may scan entire table."});return{id:i,queryId:i,sql:n,executionPlan:s,bottlenecks:o,recommendations:["Add appropriate indexes on WHERE clause columns","Consider using EXPLAIN ANALYZE to get actual execution statistics","Review and optimize JOIN conditions"],estimatedCost:s[0].cost}}recommendIndex(n){let i=`index-rec-${Date.now()}-${this.recommendationCounter++}`,s=`idx_${n.tableName}_${n.columns.join("_")}`,o={id:i,tableName:n.tableName,columns:n.columns,reason:n.reason,estimatedImprovement:n.estimatedImprovement||50,estimatedSize:n.columns.length*10,createSQL:`CREATE INDEX ${s} ON ${n.tableName} (${n.columns.join(", ")});`};return this.indexRecommendations.set(i,o),o}getInsights(n){return this.insights.get(n)}listInsights(){return Array.from(this.insights.values())}getSlowQueryLog(n){return this.slowQueryLogs.get(n)}listSlowQueryLogs(){return Array.from(this.slowQueryLogs.values())}getReport(n){return this.reports.get(n)}listReports(){return Array.from(this.reports.values())}listIndexRecommendations(){return Array.from(this.indexRecommendations.values())}generatePerformanceInsightsCF(n){return{EnablePerformanceInsights:n.enabled,PerformanceInsightsRetentionPeriod:n.retentionPeriod,...n.kmsKeyId&&{PerformanceInsightsKMSKeyId:n.kmsKeyId}}}generateSlowQueryAlarmCF(n){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:n.alarmName,AlarmDescription:"Alert when slow queries exceed threshold",MetricName:"SlowQueryCount",Namespace:"AWS/RDS",Statistic:"Sum",Period:300,EvaluationPeriods:1,Threshold:n.threshold,ComparisonOperator:"GreaterThanThreshold",...n.snsTopicArn&&{AlarmActions:[n.snsTopicArn]}}}}clear(){this.insights.clear(),this.slowQueryLogs.clear(),this.queryMetrics.clear(),this.reports.clear(),this.indexRecommendations.clear(),this.insightsCounter=0,this.logCounter=0,this.metricCounter=0,this.reportCounter=0,this.recommendationCounter=0}}var iE=new tf;class rf{users=new Map;roles=new Map;audits=new Map;userCounter=0;roleCounter=0;auditCounter=0;createUser(n){let i=`db-user-${Date.now()}-${this.userCounter++}`,s={id:i,createdAt:new Date,...n};return this.users.set(i,s),s}createReadOnlyUser(n){let i=n.tables?n.tables.map((s)=>({database:n.database,table:s,privileges:["SELECT"]})):[{database:n.database,privileges:["SELECT"]}];return this.createUser({username:n.username,database:n.database,privileges:i,passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:90})}createReadWriteUser(n){let i=n.tables?n.tables.map((s)=>({database:n.database,table:s,privileges:["SELECT","INSERT","UPDATE","DELETE"]})):[{database:n.database,privileges:["SELECT","INSERT","UPDATE","DELETE"]}];return this.createUser({username:n.username,database:n.database,privileges:i,passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:60})}createAdminUser(n){return this.createUser({username:n.username,database:n.database,privileges:[{database:n.database,privileges:["ALL"]}],passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:30})}createApplicationUser(n){let i=n.tables.map((s)=>({database:n.database,table:s.name,privileges:s.privileges}));return this.createUser({username:n.username,database:n.database,privileges:i,passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:90})}createRole(n){let i=`role-${Date.now()}-${this.roleCounter++}`,s={id:i,users:[],...n};return this.roles.set(i,s),s}assignUserToRole(n,i){let s=this.users.get(n),o=this.roles.get(i);if(!s)throw Error(`User not found: ${n}`);if(!o)throw Error(`Role not found: ${i}`);o.users.push(n);for(let c of o.privileges){let u=s.privileges.find((d)=>d.database===c.database&&d.table===c.table);if(u)u.privileges=Array.from(new Set([...u.privileges,...c.privileges]));else s.privileges.push({...c})}}grantPrivileges(n,i){let s=this.users.get(n);if(!s)return{success:!1,message:"User not found"};for(let o of i){let c=s.privileges.find((u)=>u.database===o.database&&u.table===o.table);if(c)c.privileges=Array.from(new Set([...c.privileges,...o.privileges]));else s.privileges.push(o)}return this.auditAccess({username:s.username,action:"GRANT",database:i[0]?.database,table:i[0]?.table,success:!0}),{success:!0,message:"Privileges granted successfully"}}revokePrivileges(n,i){let s=this.users.get(n);if(!s)return{success:!1,message:"User not found"};for(let o of i){let c=s.privileges.findIndex((u)=>u.database===o.database&&u.table===o.table);if(c!==-1){let u=s.privileges[c];if(u.privileges=u.privileges.filter((d)=>!o.privileges.includes(d)),u.privileges.length===0)s.privileges.splice(c,1)}}return this.auditAccess({username:s.username,action:"REVOKE",database:i[0]?.database,table:i[0]?.table,success:!0}),{success:!0,message:"Privileges revoked successfully"}}rotatePassword(n){let i=this.users.get(n);if(!i)return{success:!1};let s=`arn:aws:secretsmanager:us-east-1:123456789012:secret:db-${i.username}-${Date.now()}`;return i.passwordSecretArn=s,i.lastRotated=new Date,console.log(`Password rotated for user: ${i.username}`),{success:!0,newSecretArn:s}}needsPasswordRotation(n){let i=this.users.get(n);if(!i||!i.rotationEnabled||!i.lastRotated||!i.rotationDays)return!1;return(Date.now()-i.lastRotated.getTime())/86400000>=i.rotationDays}auditAccess(n){let i=`audit-${Date.now()}-${this.auditCounter++}`,s={id:i,timestamp:new Date,...n};return this.audits.set(i,s),s}getUserAccessHistory(n,i=100){return Array.from(this.audits.values()).filter((s)=>s.username===n).sort((s,o)=>o.timestamp.getTime()-s.timestamp.getTime()).slice(0,i)}getFailedLoginAttempts(n,i=24){let s=Date.now()-i*60*60*1000;return Array.from(this.audits.values()).filter((o)=>o.username===n&&o.action==="LOGIN"&&!o.success&&o.timestamp.getTime()>s)}generateCreateUserSQL(n,i="postgres"){let s=[];if(i==="postgres"){s.push(`CREATE USER ${n.username} WITH PASSWORD '${n.passwordSecretArn}';`);for(let o of n.privileges)if(o.privileges.includes("ALL"))s.push(`GRANT ALL PRIVILEGES ON DATABASE ${o.database} TO ${n.username};`);else{let c=o.privileges.join(", ");if(o.table)s.push(`GRANT ${c} ON ${o.database}.${o.table} TO ${n.username};`);else s.push(`GRANT ${c} ON DATABASE ${o.database} TO ${n.username};`)}}else{s.push(`CREATE USER '${n.username}'@'%' IDENTIFIED BY '${n.passwordSecretArn}';`);for(let o of n.privileges){let c=o.privileges.includes("ALL")?"ALL PRIVILEGES":o.privileges.join(", "),u=o.table?`${o.database}.${o.table}`:`${o.database}.*`;s.push(`GRANT ${c} ON ${u} TO '${n.username}'@'%';`)}s.push("FLUSH PRIVILEGES;")}return s.join(`
3726
- `)}getUser(n){return this.users.get(n)}listUsers(){return Array.from(this.users.values())}getRole(n){return this.roles.get(n)}listRoles(){return Array.from(this.roles.values())}clear(){this.users.clear(),this.roles.clear(),this.audits.clear(),this.userCounter=0,this.roleCounter=0,this.auditCounter=0}}var sE=new rf;class nf{rotations=new Map;schedules=new Map;rotationCounter=0;scheduleCounter=0;createRotation(n){let i=`rotation-${Date.now()}-${this.rotationCounter++}`,s={id:i,...n};return this.rotations.set(i,s),s}enableRDSRotation(n){let i=this.createRotation({secretId:n.secretId,secretType:"rds_credentials",rotationEnabled:!0,rotationDays:n.rotationDays||30,rotationLambdaArn:this.generateRDSRotationLambdaArn(n.engine)});return i.nextRotation=new Date(Date.now()+i.rotationDays*24*60*60*1000),i}enableAPIKeyRotation(n){return this.createRotation({secretId:n.secretId,secretType:"api_key",rotationEnabled:!0,rotationDays:n.rotationDays||90,rotationLambdaArn:n.rotationLambdaArn})}enableOAuthRotation(n){return this.createRotation({secretId:n.secretId,secretType:"oauth_token",rotationEnabled:!0,rotationDays:n.rotationDays||60,rotationLambdaArn:n.rotationLambdaArn})}enableSSHKeyRotation(n){return this.createRotation({secretId:n.secretId,secretType:"ssh_key",rotationEnabled:!0,rotationDays:n.rotationDays||180,rotationLambdaArn:n.rotationLambdaArn})}createSchedule(n){let i=`schedule-${Date.now()}-${this.scheduleCounter++}`,s={id:i,...n};return this.schedules.set(i,s),s}async executeRotation(n){let i=this.rotations.get(n);if(!i)throw Error(`Rotation not found: ${n}`);console.log(`
3725
+ ✓ Promotion completed successfully`),i.status="available",{success:!0,message:"Replica promoted successfully"}}getReplicationLag(n){if(!this.replicas.get(n))throw Error(`Replica not found: ${n}`);return Math.floor(Math.random()*1000)}getReplica(n){return this.replicas.get(n)}listReplicas(){return Array.from(this.replicas.values())}getReplicationGroup(n){return this.replicationGroups.get(n)}listReplicationGroups(){return Array.from(this.replicationGroups.values())}getProxy(n){return this.proxies.get(n)}listProxies(){return Array.from(this.proxies.values())}generateReplicaCF(n){return{Type:"AWS::RDS::DBInstance",Properties:{SourceDBInstanceIdentifier:n.sourceDatabase,DBInstanceIdentifier:n.name,DBInstanceClass:n.instanceClass,MultiAZ:n.multiAZ||!1,AutoMinorVersionUpgrade:n.autoMinorVersionUpgrade??!0,...n.backupRetentionPeriod&&{BackupRetentionPeriod:n.backupRetentionPeriod},...n.preferredBackupWindow&&{PreferredBackupWindow:n.preferredBackupWindow},...n.preferredMaintenanceWindow&&{PreferredMaintenanceWindow:n.preferredMaintenanceWindow}}}}generateProxyCF(n){return{Type:"AWS::RDS::DBProxy",Properties:{DBProxyName:n.name,EngineFamily:n.engineFamily,Auth:[{AuthScheme:"SECRETS",SecretArn:n.secretArn,IAMAuth:"DISABLED"}],RoleArn:{"Fn::GetAtt":["RDSProxyRole","Arn"]},VpcSubnetIds:n.vpcSubnetIds,VpcSecurityGroupIds:n.securityGroupIds,RequireTLS:n.requireTLS??!0,IdleClientTimeout:n.idleClientTimeout||1800,...n.maxConnectionsPercent&&{MaxConnectionsPercent:n.maxConnectionsPercent},...n.maxIdleConnectionsPercent&&{MaxIdleConnectionsPercent:n.maxIdleConnectionsPercent},...n.connectionBorrowTimeout&&{ConnectionBorrowTimeout:n.connectionBorrowTimeout}}}}generateProxyTargetCF(n,i){return{Type:"AWS::RDS::DBProxyTargetGroup",Properties:{DBProxyName:i.name,TargetGroupName:"default",DBInstanceIdentifiers:[n.targetArn],ConnectionPoolConfig:{MaxConnectionsPercent:100,MaxIdleConnectionsPercent:50,ConnectionBorrowTimeout:120}}}}generateProxyRoleCF(){return{Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"rds.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"RDSProxySecretsPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],Resource:"arn:aws:secretsmanager:*:*:secret:*"},{Effect:"Allow",Action:["kms:Decrypt"],Resource:"arn:aws:kms:*:*:key/*",Condition:{StringEquals:{"kms:ViaService":"secretsmanager.*.amazonaws.com"}}}]}}]}}}clear(){this.replicas.clear(),this.replicationGroups.clear(),this.proxies.clear(),this.proxyTargets.clear(),this.replicaCounter=0,this.groupCounter=0,this.proxyCounter=0,this.targetCounter=0}}var sS=new Bl;class rf{insights=new Map;slowQueryLogs=new Map;queryMetrics=new Map;reports=new Map;indexRecommendations=new Map;insightsCounter=0;logCounter=0;metricCounter=0;reportCounter=0;recommendationCounter=0;enablePerformanceInsights(n){let i=`pi-${Date.now()}-${this.insightsCounter++}`,s={id:i,name:n.name,databaseIdentifier:n.databaseIdentifier,enabled:!0,retentionPeriod:n.retentionPeriod||7,kmsKeyId:n.kmsKeyId};return this.insights.set(i,s),s}enableSlowQueryLog(n){let i=`slow-query-${Date.now()}-${this.logCounter++}`,s={id:i,name:n.name,databaseIdentifier:n.databaseIdentifier,enabled:!0,logDestination:n.logDestination,cloudwatchLogGroup:n.cloudwatchLogGroup,s3Bucket:n.s3Bucket,s3Prefix:n.s3Bucket?"slow-queries/":void 0,minExecutionTime:n.minExecutionTime||1000};return this.slowQueryLogs.set(i,s),s}recordQueryMetric(n){let i=`metric-${Date.now()}-${this.metricCounter++}`,s={id:i,timestamp:new Date,...n};return this.queryMetrics.set(i,s),s}generatePerformanceReport(n){let i=`report-${Date.now()}-${this.reportCounter++}`,s={avgCPU:Math.random()*60+20,maxCPU:Math.random()*30+70,avgConnections:Math.floor(Math.random()*50+10),maxConnections:Math.floor(Math.random()*50+100),avgReadIOPS:Math.floor(Math.random()*1000+500),avgWriteIOPS:Math.floor(Math.random()*500+200),avgReadThroughput:Math.random()*50+10,avgWriteThroughput:Math.random()*20+5,avgReadLatency:Math.random()*5+1,avgWriteLatency:Math.random()*8+2,cacheHitRatio:Math.random()*10+90,deadlocks:Math.floor(Math.random()*5),longRunningTransactions:Math.floor(Math.random()*10)},o=Array.from(this.queryMetrics.values()),c=o.sort((y,h)=>h.executionCount-y.executionCount).slice(0,10),u=o.filter((y)=>y.avgExecutionTime>1000).sort((y,h)=>h.avgExecutionTime-y.avgExecutionTime).slice(0,10),d=this.generateRecommendations(s,u),p={id:i,name:n.name,databaseIdentifier:n.databaseIdentifier,reportType:n.reportType,metrics:s,topQueries:c,slowQueries:u,recommendations:d,generatedAt:new Date};return this.reports.set(i,p),p}generateRecommendations(n,i){let s=[];if(n.avgCPU>70)s.push({type:"scaling",severity:"high",title:"High CPU Usage",description:`Average CPU usage is ${n.avgCPU.toFixed(1)}%, which is above the recommended threshold of 70%.`,impact:"Performance degradation, increased latency, potential timeouts",effort:"medium"});if(n.cacheHitRatio<95)s.push({type:"configuration",severity:"medium",title:"Low Cache Hit Ratio",description:`Cache hit ratio is ${n.cacheHitRatio.toFixed(1)}%. Consider increasing buffer pool size.`,impact:"Increased disk I/O, slower query performance",effort:"low"});if(n.deadlocks>0)s.push({type:"query",severity:"medium",title:"Deadlocks Detected",description:`${n.deadlocks} deadlock(s) detected. Review transaction isolation levels and query patterns.`,impact:"Transaction failures, application errors",effort:"high"});if(i.length>0)s.push({type:"index",severity:"high",title:"Slow Queries Detected",description:`${i.length} slow queries detected. Consider adding indexes or optimizing queries.`,impact:"High latency, poor user experience",effort:"medium"});if(n.avgReadLatency>10||n.avgWriteLatency>10)s.push({type:"scaling",severity:"high",title:"High I/O Latency",description:"Read or write latency is high. Consider upgrading to Provisioned IOPS or moving to a larger instance.",impact:"Slow query execution, application timeouts",effort:"medium"});return s}analyzeQuery(n){let i=`analysis-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,s=[{id:1,operation:"Seq Scan",table:"users",rows:1e4,cost:850.5,children:[]}],o=[];if(n.toLowerCase().includes("select *"))o.push({type:"full_table_scan",severity:"warning",description:"Query selects all columns. Consider selecting only required columns."});if(!n.toLowerCase().includes("where")&&n.toLowerCase().includes("select"))o.push({type:"full_table_scan",severity:"critical",description:"Query has no WHERE clause and may scan entire table."});return{id:i,queryId:i,sql:n,executionPlan:s,bottlenecks:o,recommendations:["Add appropriate indexes on WHERE clause columns","Consider using EXPLAIN ANALYZE to get actual execution statistics","Review and optimize JOIN conditions"],estimatedCost:s[0].cost}}recommendIndex(n){let i=`index-rec-${Date.now()}-${this.recommendationCounter++}`,s=`idx_${n.tableName}_${n.columns.join("_")}`,o={id:i,tableName:n.tableName,columns:n.columns,reason:n.reason,estimatedImprovement:n.estimatedImprovement||50,estimatedSize:n.columns.length*10,createSQL:`CREATE INDEX ${s} ON ${n.tableName} (${n.columns.join(", ")});`};return this.indexRecommendations.set(i,o),o}getInsights(n){return this.insights.get(n)}listInsights(){return Array.from(this.insights.values())}getSlowQueryLog(n){return this.slowQueryLogs.get(n)}listSlowQueryLogs(){return Array.from(this.slowQueryLogs.values())}getReport(n){return this.reports.get(n)}listReports(){return Array.from(this.reports.values())}listIndexRecommendations(){return Array.from(this.indexRecommendations.values())}generatePerformanceInsightsCF(n){return{EnablePerformanceInsights:n.enabled,PerformanceInsightsRetentionPeriod:n.retentionPeriod,...n.kmsKeyId&&{PerformanceInsightsKMSKeyId:n.kmsKeyId}}}generateSlowQueryAlarmCF(n){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:n.alarmName,AlarmDescription:"Alert when slow queries exceed threshold",MetricName:"SlowQueryCount",Namespace:"AWS/RDS",Statistic:"Sum",Period:300,EvaluationPeriods:1,Threshold:n.threshold,ComparisonOperator:"GreaterThanThreshold",...n.snsTopicArn&&{AlarmActions:[n.snsTopicArn]}}}}clear(){this.insights.clear(),this.slowQueryLogs.clear(),this.queryMetrics.clear(),this.reports.clear(),this.indexRecommendations.clear(),this.insightsCounter=0,this.logCounter=0,this.metricCounter=0,this.reportCounter=0,this.recommendationCounter=0}}var sE=new rf;class nf{users=new Map;roles=new Map;audits=new Map;userCounter=0;roleCounter=0;auditCounter=0;createUser(n){let i=`db-user-${Date.now()}-${this.userCounter++}`,s={id:i,createdAt:new Date,...n};return this.users.set(i,s),s}createReadOnlyUser(n){let i=n.tables?n.tables.map((s)=>({database:n.database,table:s,privileges:["SELECT"]})):[{database:n.database,privileges:["SELECT"]}];return this.createUser({username:n.username,database:n.database,privileges:i,passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:90})}createReadWriteUser(n){let i=n.tables?n.tables.map((s)=>({database:n.database,table:s,privileges:["SELECT","INSERT","UPDATE","DELETE"]})):[{database:n.database,privileges:["SELECT","INSERT","UPDATE","DELETE"]}];return this.createUser({username:n.username,database:n.database,privileges:i,passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:60})}createAdminUser(n){return this.createUser({username:n.username,database:n.database,privileges:[{database:n.database,privileges:["ALL"]}],passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:30})}createApplicationUser(n){let i=n.tables.map((s)=>({database:n.database,table:s.name,privileges:s.privileges}));return this.createUser({username:n.username,database:n.database,privileges:i,passwordSecretArn:n.passwordSecretArn,rotationEnabled:!0,rotationDays:90})}createRole(n){let i=`role-${Date.now()}-${this.roleCounter++}`,s={id:i,users:[],...n};return this.roles.set(i,s),s}assignUserToRole(n,i){let s=this.users.get(n),o=this.roles.get(i);if(!s)throw Error(`User not found: ${n}`);if(!o)throw Error(`Role not found: ${i}`);o.users.push(n);for(let c of o.privileges){let u=s.privileges.find((d)=>d.database===c.database&&d.table===c.table);if(u)u.privileges=Array.from(new Set([...u.privileges,...c.privileges]));else s.privileges.push({...c})}}grantPrivileges(n,i){let s=this.users.get(n);if(!s)return{success:!1,message:"User not found"};for(let o of i){let c=s.privileges.find((u)=>u.database===o.database&&u.table===o.table);if(c)c.privileges=Array.from(new Set([...c.privileges,...o.privileges]));else s.privileges.push(o)}return this.auditAccess({username:s.username,action:"GRANT",database:i[0]?.database,table:i[0]?.table,success:!0}),{success:!0,message:"Privileges granted successfully"}}revokePrivileges(n,i){let s=this.users.get(n);if(!s)return{success:!1,message:"User not found"};for(let o of i){let c=s.privileges.findIndex((u)=>u.database===o.database&&u.table===o.table);if(c!==-1){let u=s.privileges[c];if(u.privileges=u.privileges.filter((d)=>!o.privileges.includes(d)),u.privileges.length===0)s.privileges.splice(c,1)}}return this.auditAccess({username:s.username,action:"REVOKE",database:i[0]?.database,table:i[0]?.table,success:!0}),{success:!0,message:"Privileges revoked successfully"}}rotatePassword(n){let i=this.users.get(n);if(!i)return{success:!1};let s=`arn:aws:secretsmanager:us-east-1:123456789012:secret:db-${i.username}-${Date.now()}`;return i.passwordSecretArn=s,i.lastRotated=new Date,console.log(`Password rotated for user: ${i.username}`),{success:!0,newSecretArn:s}}needsPasswordRotation(n){let i=this.users.get(n);if(!i||!i.rotationEnabled||!i.lastRotated||!i.rotationDays)return!1;return(Date.now()-i.lastRotated.getTime())/86400000>=i.rotationDays}auditAccess(n){let i=`audit-${Date.now()}-${this.auditCounter++}`,s={id:i,timestamp:new Date,...n};return this.audits.set(i,s),s}getUserAccessHistory(n,i=100){return Array.from(this.audits.values()).filter((s)=>s.username===n).sort((s,o)=>o.timestamp.getTime()-s.timestamp.getTime()).slice(0,i)}getFailedLoginAttempts(n,i=24){let s=Date.now()-i*60*60*1000;return Array.from(this.audits.values()).filter((o)=>o.username===n&&o.action==="LOGIN"&&!o.success&&o.timestamp.getTime()>s)}generateCreateUserSQL(n,i="postgres"){let s=[];if(i==="postgres"){s.push(`CREATE USER ${n.username} WITH PASSWORD '${n.passwordSecretArn}';`);for(let o of n.privileges)if(o.privileges.includes("ALL"))s.push(`GRANT ALL PRIVILEGES ON DATABASE ${o.database} TO ${n.username};`);else{let c=o.privileges.join(", ");if(o.table)s.push(`GRANT ${c} ON ${o.database}.${o.table} TO ${n.username};`);else s.push(`GRANT ${c} ON DATABASE ${o.database} TO ${n.username};`)}}else{s.push(`CREATE USER '${n.username}'@'%' IDENTIFIED BY '${n.passwordSecretArn}';`);for(let o of n.privileges){let c=o.privileges.includes("ALL")?"ALL PRIVILEGES":o.privileges.join(", "),u=o.table?`${o.database}.${o.table}`:`${o.database}.*`;s.push(`GRANT ${c} ON ${u} TO '${n.username}'@'%';`)}s.push("FLUSH PRIVILEGES;")}return s.join(`
3726
+ `)}getUser(n){return this.users.get(n)}listUsers(){return Array.from(this.users.values())}getRole(n){return this.roles.get(n)}listRoles(){return Array.from(this.roles.values())}clear(){this.users.clear(),this.roles.clear(),this.audits.clear(),this.userCounter=0,this.roleCounter=0,this.auditCounter=0}}var oE=new nf;class sf{rotations=new Map;schedules=new Map;rotationCounter=0;scheduleCounter=0;createRotation(n){let i=`rotation-${Date.now()}-${this.rotationCounter++}`,s={id:i,...n};return this.rotations.set(i,s),s}enableRDSRotation(n){let i=this.createRotation({secretId:n.secretId,secretType:"rds_credentials",rotationEnabled:!0,rotationDays:n.rotationDays||30,rotationLambdaArn:this.generateRDSRotationLambdaArn(n.engine)});return i.nextRotation=new Date(Date.now()+i.rotationDays*24*60*60*1000),i}enableAPIKeyRotation(n){return this.createRotation({secretId:n.secretId,secretType:"api_key",rotationEnabled:!0,rotationDays:n.rotationDays||90,rotationLambdaArn:n.rotationLambdaArn})}enableOAuthRotation(n){return this.createRotation({secretId:n.secretId,secretType:"oauth_token",rotationEnabled:!0,rotationDays:n.rotationDays||60,rotationLambdaArn:n.rotationLambdaArn})}enableSSHKeyRotation(n){return this.createRotation({secretId:n.secretId,secretType:"ssh_key",rotationEnabled:!0,rotationDays:n.rotationDays||180,rotationLambdaArn:n.rotationLambdaArn})}createSchedule(n){let i=`schedule-${Date.now()}-${this.scheduleCounter++}`,s={id:i,...n};return this.schedules.set(i,s),s}async executeRotation(n){let i=this.rotations.get(n);if(!i)throw Error(`Rotation not found: ${n}`);console.log(`
3727
3727
  Executing rotation for secret: ${i.secretId}`),console.log(`Secret type: ${i.secretType}`),console.log(`Rotation interval: ${i.rotationDays} days`);try{console.log(`
3728
3728
  Rotation steps:`),console.log("1. Creating new secret version...");let s=`v${Date.now()}`;console.log("2. Testing new credentials..."),console.log("3. Updating application references..."),console.log("4. Marking previous version as deprecated...");let o=i.versionStages?.[0]||"v1";return console.log("5. Finalizing rotation..."),i.lastRotated=new Date,i.nextRotation=new Date(Date.now()+i.rotationDays*24*60*60*1000),console.log(`
3729
3729
  ✓ Rotation completed successfully`),console.log(` New version: ${s}`),console.log(` Next rotation: ${i.nextRotation.toISOString()}`),{success:!0,secretId:i.secretId,oldVersion:o,newVersion:s,rotatedAt:new Date}}catch(s){return console.error(`
3730
- ✗ Rotation failed:`,s),{success:!1,secretId:i.secretId,oldVersion:"unknown",newVersion:"unknown",rotatedAt:new Date,error:s instanceof Error?s.message:String(s)}}}needsRotation(n){let i=this.rotations.get(n);if(!i||!i.rotationEnabled)return!1;if(!i.lastRotated)return!0;return(Date.now()-i.lastRotated.getTime())/86400000>=i.rotationDays}getSecretsNeedingRotation(){return Array.from(this.rotations.values()).filter((n)=>this.needsRotation(n.id))}generateRDSRotationLambdaArn(n){let i={postgres:"SecretsManagerRDSPostgreSQLRotationSingleUser",mysql:"SecretsManagerRDSMySQLRotationSingleUser",sqlserver:"SecretsManagerRDSSQLServerRotationSingleUser",oracle:"SecretsManagerRDSOracleRotationSingleUser"};return`arn:aws:lambda:us-east-1:123456789012:function:${i[n]||i.postgres}`}getRotation(n){return this.rotations.get(n)}listRotations(){return Array.from(this.rotations.values())}getSchedule(n){return this.schedules.get(n)}listSchedules(){return Array.from(this.schedules.values())}generateRotationCF(n){return{RotationEnabled:n.rotationEnabled,RotationRules:{AutomaticallyAfterDays:n.rotationDays},...n.rotationLambdaArn&&{RotationLambdaARN:n.rotationLambdaArn}}}generateRotationLambdaCF(n){return{Type:"AWS::Lambda::Function",Properties:{FunctionName:n.functionName,Runtime:"python3.11",Handler:"lambda_function.lambda_handler",Role:{"Fn::GetAtt":["RotationLambdaRole","Arn"]},Timeout:30,Environment:{Variables:{SECRETS_MANAGER_ENDPOINT:"https://secretsmanager.us-east-1.amazonaws.com"}},...n.vpcConfig&&{VpcConfig:{SubnetIds:n.vpcConfig.subnetIds,SecurityGroupIds:n.vpcConfig.securityGroupIds}}}}}generateRotationLambdaRoleCF(){return{Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole","arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"],Policies:[{PolicyName:"SecretsRotationPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:DescribeSecret","secretsmanager:GetSecretValue","secretsmanager:PutSecretValue","secretsmanager:UpdateSecretVersionStage"],Resource:"*"},{Effect:"Allow",Action:["secretsmanager:GetRandomPassword"],Resource:"*"}]}}]}}}generateRotationScheduleCF(n){return{Type:"AWS::Events::Rule",Properties:{Name:n.name,Description:`Rotation schedule for ${n.secrets.length} secrets`,ScheduleExpression:n.schedule,State:n.enabled?"ENABLED":"DISABLED",Targets:[{Arn:{"Fn::GetAtt":["RotationStateMachine","Arn"]},RoleArn:{"Fn::GetAtt":["EventBridgeRotationRole","Arn"]},Input:JSON.stringify({secrets:n.secrets})}]}}}clear(){this.rotations.clear(),this.schedules.clear(),this.rotationCounter=0,this.scheduleCounter=0}}var oE=new nf;class xl{versions=new Map;audits=new Map;externalManagers=new Map;replications=new Map;policies=new Map;versionCounter=0;auditCounter=0;managerCounter=0;replicationCounter=0;policyCounter=0;createVersion(n){let i=`version-${Date.now()}-${this.versionCounter++}`,s={id:i,...n};return this.versions.set(i,s),this.auditAction({secretId:n.secretId,action:"CREATE",actor:"system",versionId:n.versionId,success:!0}),s}getVersionByStage(n,i){return Array.from(this.versions.values()).find((s)=>s.secretId===n&&s.versionStages.includes(i))}listVersions(n){return Array.from(this.versions.values()).filter((i)=>i.secretId===n).sort((i,s)=>s.createdAt.getTime()-i.createdAt.getTime())}deprecateVersion(n){let i=Array.from(this.versions.values()).find((s)=>s.versionId===n);if(i)i.deprecatedAt=new Date,i.versionStages=i.versionStages.filter((s)=>s!=="AWSCURRENT"),this.auditAction({secretId:i.secretId,action:"UPDATE",actor:"system",versionId:n,success:!0})}restoreVersion(n){let i=Array.from(this.versions.values()).find((s)=>s.versionId===n);if(i)Array.from(this.versions.values()).filter((s)=>s.secretId===i.secretId&&s.versionId!==n).forEach((s)=>{s.versionStages=s.versionStages.filter((o)=>o!=="AWSCURRENT")}),i.versionStages.push("AWSCURRENT"),i.deprecatedAt=void 0,this.auditAction({secretId:i.secretId,action:"RESTORE",actor:"system",versionId:n,success:!0})}auditAction(n){let i=`audit-${Date.now()}-${this.auditCounter++}`,s={id:i,timestamp:new Date,...n};return this.audits.set(i,s),s}getAuditTrail(n,i=100){return Array.from(this.audits.values()).filter((s)=>s.secretId===n).sort((s,o)=>o.timestamp.getTime()-s.timestamp.getTime()).slice(0,i)}getFailedAccesses(n,i=24){let s=Date.now()-i*60*60*1000;return Array.from(this.audits.values()).filter((o)=>o.secretId===n&&!o.success&&o.timestamp.getTime()>s)}registerExternalManager(n){let i=`ext-manager-${Date.now()}-${this.managerCounter++}`,s={id:i,...n};return this.externalManagers.set(i,s),s}registerVault(n){return this.registerExternalManager({type:"vault",name:n.name,endpoint:n.endpoint,authentication:{type:n.token?"token":"iam",credentials:n.token?{token:n.token}:void 0,roleArn:n.roleArn},syncEnabled:n.syncEnabled||!1,syncInterval:60})}registerOnePassword(n){return this.registerExternalManager({type:"onepassword",name:n.name,endpoint:n.endpoint||"https://my.1password.com",authentication:{type:"apikey",credentials:{apiKey:n.apiKey}},syncEnabled:n.syncEnabled||!1,syncInterval:30})}enableReplication(n){let i=`replication-${Date.now()}-${this.replicationCounter++}`,s={id:i,secretId:n.secretId,sourceRegion:n.sourceRegion,replicaRegions:n.replicaRegions,kmsKeyIds:n.kmsKeyIds,status:"replicating"};return this.replications.set(i,s),this.auditAction({secretId:n.secretId,action:"REPLICATE",actor:"system",success:!0}),setTimeout(()=>{s.status="completed"},100),s}createPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,secretId:n.secretId,policy:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:n.allowedPrincipals},Action:n.allowedActions,Resource:"*"}]}};return this.policies.set(i,s),s}createCrossAccountPolicy(n){let i=n.roleNames.map((s)=>`arn:aws:iam::${n.accountId}:role/${s}`);return this.createPolicy({secretId:n.secretId,allowedPrincipals:i,allowedActions:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"]})}getVersion(n){return this.versions.get(n)}getExternalManager(n){return this.externalManagers.get(n)}listExternalManagers(){return Array.from(this.externalManagers.values())}getReplication(n){return this.replications.get(n)}listReplications(){return Array.from(this.replications.values())}generateSecretCF(n){return{Type:"AWS::SecretsManager::Secret",Properties:{Name:n.name,Description:n.description,...n.kmsKeyId&&{KmsKeyId:n.kmsKeyId},...n.replicaRegions&&{ReplicaRegions:n.replicaRegions.map((i)=>({Region:i}))}}}}generateSecretPolicyCF(n){return{Type:"AWS::SecretsManager::ResourcePolicy",Properties:{SecretId:n.secretId,ResourcePolicy:n.policy}}}clear(){this.versions.clear(),this.audits.clear(),this.externalManagers.clear(),this.replications.clear(),this.policies.clear(),this.versionCounter=0,this.auditCounter=0,this.managerCounter=0,this.replicationCounter=0,this.policyCounter=0}}var sS=new xl;class sf{certificates=new Map;renewals=new Map;validations=new Map;monitors=new Map;alerts=new Map;certificateCounter=0;renewalCounter=0;validationCounter=0;monitorCounter=0;alertCounter=0;requestCertificate(n){let i=`cert-${Date.now()}-${this.certificateCounter++}`,s=`arn:aws:acm:us-east-1:123456789012:certificate/${i}`,o={id:i,arn:s,domainName:n.domainName,subjectAlternativeNames:n.subjectAlternativeNames,validationMethod:n.validationMethod||"DNS",status:"PENDING_VALIDATION"};return this.certificates.set(i,o),this.createValidation(o),o}requestWildcardCertificate(n){let i=[];if(n.includeApex)i.push(n.domainName.replace("*.",""));return this.requestCertificate({domainName:n.domainName,subjectAlternativeNames:i.length>0?i:void 0,validationMethod:"DNS"})}requestMultiDomainCertificate(n){return this.requestCertificate({domainName:n.primaryDomain,subjectAlternativeNames:n.additionalDomains,validationMethod:n.validationMethod||"DNS"})}createValidation(n){let i={domainName:n.domainName,validationMethod:n.validationMethod,validationStatus:"PENDING"};if(n.validationMethod==="DNS")i.resourceRecords=[{name:`_${Math.random().toString(36).slice(2)}.${n.domainName}`,type:"CNAME",value:`_${Math.random().toString(36).slice(2)}.acm-validations.aws.`}];else i.validationEmails=[`admin@${n.domainName}`,`administrator@${n.domainName}`,`hostmaster@${n.domainName}`];return this.validations.set(n.id,i),i}validateCertificate(n){let i=this.certificates.get(n),s=this.validations.get(n);if(!i||!s)return{success:!1,message:"Certificate or validation not found"};return s.validationStatus="SUCCESS",i.status="ISSUED",i.issuedAt=new Date,i.expiresAt=new Date(Date.now()+31536000000),i.renewalEligibility=!0,i.issuer="Amazon",{success:!0,message:"Certificate validated and issued successfully"}}enableAutoRenewal(n){let i=`renewal-${Date.now()}-${this.renewalCounter++}`,s={id:i,certificateArn:n.certificateArn,autoRenew:!0,renewBeforeDays:n.renewBeforeDays||30};return this.renewals.set(i,s),s}async renewCertificate(n){let i=this.renewals.get(n);if(!i)return{success:!1,message:"Renewal configuration not found"};let s=Array.from(this.certificates.values()).find((o)=>o.arn===i.certificateArn);if(!s)return{success:!1,message:"Certificate not found"};console.log(`
3730
+ ✗ Rotation failed:`,s),{success:!1,secretId:i.secretId,oldVersion:"unknown",newVersion:"unknown",rotatedAt:new Date,error:s instanceof Error?s.message:String(s)}}}needsRotation(n){let i=this.rotations.get(n);if(!i||!i.rotationEnabled)return!1;if(!i.lastRotated)return!0;return(Date.now()-i.lastRotated.getTime())/86400000>=i.rotationDays}getSecretsNeedingRotation(){return Array.from(this.rotations.values()).filter((n)=>this.needsRotation(n.id))}generateRDSRotationLambdaArn(n){let i={postgres:"SecretsManagerRDSPostgreSQLRotationSingleUser",mysql:"SecretsManagerRDSMySQLRotationSingleUser",sqlserver:"SecretsManagerRDSSQLServerRotationSingleUser",oracle:"SecretsManagerRDSOracleRotationSingleUser"};return`arn:aws:lambda:us-east-1:123456789012:function:${i[n]||i.postgres}`}getRotation(n){return this.rotations.get(n)}listRotations(){return Array.from(this.rotations.values())}getSchedule(n){return this.schedules.get(n)}listSchedules(){return Array.from(this.schedules.values())}generateRotationCF(n){return{RotationEnabled:n.rotationEnabled,RotationRules:{AutomaticallyAfterDays:n.rotationDays},...n.rotationLambdaArn&&{RotationLambdaARN:n.rotationLambdaArn}}}generateRotationLambdaCF(n){return{Type:"AWS::Lambda::Function",Properties:{FunctionName:n.functionName,Runtime:"python3.11",Handler:"lambda_function.lambda_handler",Role:{"Fn::GetAtt":["RotationLambdaRole","Arn"]},Timeout:30,Environment:{Variables:{SECRETS_MANAGER_ENDPOINT:"https://secretsmanager.us-east-1.amazonaws.com"}},...n.vpcConfig&&{VpcConfig:{SubnetIds:n.vpcConfig.subnetIds,SecurityGroupIds:n.vpcConfig.securityGroupIds}}}}}generateRotationLambdaRoleCF(){return{Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole","arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"],Policies:[{PolicyName:"SecretsRotationPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:DescribeSecret","secretsmanager:GetSecretValue","secretsmanager:PutSecretValue","secretsmanager:UpdateSecretVersionStage"],Resource:"*"},{Effect:"Allow",Action:["secretsmanager:GetRandomPassword"],Resource:"*"}]}}]}}}generateRotationScheduleCF(n){return{Type:"AWS::Events::Rule",Properties:{Name:n.name,Description:`Rotation schedule for ${n.secrets.length} secrets`,ScheduleExpression:n.schedule,State:n.enabled?"ENABLED":"DISABLED",Targets:[{Arn:{"Fn::GetAtt":["RotationStateMachine","Arn"]},RoleArn:{"Fn::GetAtt":["EventBridgeRotationRole","Arn"]},Input:JSON.stringify({secrets:n.secrets})}]}}}clear(){this.rotations.clear(),this.schedules.clear(),this.rotationCounter=0,this.scheduleCounter=0}}var aE=new sf;class xl{versions=new Map;audits=new Map;externalManagers=new Map;replications=new Map;policies=new Map;versionCounter=0;auditCounter=0;managerCounter=0;replicationCounter=0;policyCounter=0;createVersion(n){let i=`version-${Date.now()}-${this.versionCounter++}`,s={id:i,...n};return this.versions.set(i,s),this.auditAction({secretId:n.secretId,action:"CREATE",actor:"system",versionId:n.versionId,success:!0}),s}getVersionByStage(n,i){return Array.from(this.versions.values()).find((s)=>s.secretId===n&&s.versionStages.includes(i))}listVersions(n){return Array.from(this.versions.values()).filter((i)=>i.secretId===n).sort((i,s)=>s.createdAt.getTime()-i.createdAt.getTime())}deprecateVersion(n){let i=Array.from(this.versions.values()).find((s)=>s.versionId===n);if(i)i.deprecatedAt=new Date,i.versionStages=i.versionStages.filter((s)=>s!=="AWSCURRENT"),this.auditAction({secretId:i.secretId,action:"UPDATE",actor:"system",versionId:n,success:!0})}restoreVersion(n){let i=Array.from(this.versions.values()).find((s)=>s.versionId===n);if(i)Array.from(this.versions.values()).filter((s)=>s.secretId===i.secretId&&s.versionId!==n).forEach((s)=>{s.versionStages=s.versionStages.filter((o)=>o!=="AWSCURRENT")}),i.versionStages.push("AWSCURRENT"),i.deprecatedAt=void 0,this.auditAction({secretId:i.secretId,action:"RESTORE",actor:"system",versionId:n,success:!0})}auditAction(n){let i=`audit-${Date.now()}-${this.auditCounter++}`,s={id:i,timestamp:new Date,...n};return this.audits.set(i,s),s}getAuditTrail(n,i=100){return Array.from(this.audits.values()).filter((s)=>s.secretId===n).sort((s,o)=>o.timestamp.getTime()-s.timestamp.getTime()).slice(0,i)}getFailedAccesses(n,i=24){let s=Date.now()-i*60*60*1000;return Array.from(this.audits.values()).filter((o)=>o.secretId===n&&!o.success&&o.timestamp.getTime()>s)}registerExternalManager(n){let i=`ext-manager-${Date.now()}-${this.managerCounter++}`,s={id:i,...n};return this.externalManagers.set(i,s),s}registerVault(n){return this.registerExternalManager({type:"vault",name:n.name,endpoint:n.endpoint,authentication:{type:n.token?"token":"iam",credentials:n.token?{token:n.token}:void 0,roleArn:n.roleArn},syncEnabled:n.syncEnabled||!1,syncInterval:60})}registerOnePassword(n){return this.registerExternalManager({type:"onepassword",name:n.name,endpoint:n.endpoint||"https://my.1password.com",authentication:{type:"apikey",credentials:{apiKey:n.apiKey}},syncEnabled:n.syncEnabled||!1,syncInterval:30})}enableReplication(n){let i=`replication-${Date.now()}-${this.replicationCounter++}`,s={id:i,secretId:n.secretId,sourceRegion:n.sourceRegion,replicaRegions:n.replicaRegions,kmsKeyIds:n.kmsKeyIds,status:"replicating"};return this.replications.set(i,s),this.auditAction({secretId:n.secretId,action:"REPLICATE",actor:"system",success:!0}),setTimeout(()=>{s.status="completed"},100),s}createPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,secretId:n.secretId,policy:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:n.allowedPrincipals},Action:n.allowedActions,Resource:"*"}]}};return this.policies.set(i,s),s}createCrossAccountPolicy(n){let i=n.roleNames.map((s)=>`arn:aws:iam::${n.accountId}:role/${s}`);return this.createPolicy({secretId:n.secretId,allowedPrincipals:i,allowedActions:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"]})}getVersion(n){return this.versions.get(n)}getExternalManager(n){return this.externalManagers.get(n)}listExternalManagers(){return Array.from(this.externalManagers.values())}getReplication(n){return this.replications.get(n)}listReplications(){return Array.from(this.replications.values())}generateSecretCF(n){return{Type:"AWS::SecretsManager::Secret",Properties:{Name:n.name,Description:n.description,...n.kmsKeyId&&{KmsKeyId:n.kmsKeyId},...n.replicaRegions&&{ReplicaRegions:n.replicaRegions.map((i)=>({Region:i}))}}}}generateSecretPolicyCF(n){return{Type:"AWS::SecretsManager::ResourcePolicy",Properties:{SecretId:n.secretId,ResourcePolicy:n.policy}}}clear(){this.versions.clear(),this.audits.clear(),this.externalManagers.clear(),this.replications.clear(),this.policies.clear(),this.versionCounter=0,this.auditCounter=0,this.managerCounter=0,this.replicationCounter=0,this.policyCounter=0}}var oS=new xl;class of{certificates=new Map;renewals=new Map;validations=new Map;monitors=new Map;alerts=new Map;certificateCounter=0;renewalCounter=0;validationCounter=0;monitorCounter=0;alertCounter=0;requestCertificate(n){let i=`cert-${Date.now()}-${this.certificateCounter++}`,s=`arn:aws:acm:us-east-1:123456789012:certificate/${i}`,o={id:i,arn:s,domainName:n.domainName,subjectAlternativeNames:n.subjectAlternativeNames,validationMethod:n.validationMethod||"DNS",status:"PENDING_VALIDATION"};return this.certificates.set(i,o),this.createValidation(o),o}requestWildcardCertificate(n){let i=[];if(n.includeApex)i.push(n.domainName.replace("*.",""));return this.requestCertificate({domainName:n.domainName,subjectAlternativeNames:i.length>0?i:void 0,validationMethod:"DNS"})}requestMultiDomainCertificate(n){return this.requestCertificate({domainName:n.primaryDomain,subjectAlternativeNames:n.additionalDomains,validationMethod:n.validationMethod||"DNS"})}createValidation(n){let i={domainName:n.domainName,validationMethod:n.validationMethod,validationStatus:"PENDING"};if(n.validationMethod==="DNS")i.resourceRecords=[{name:`_${Math.random().toString(36).slice(2)}.${n.domainName}`,type:"CNAME",value:`_${Math.random().toString(36).slice(2)}.acm-validations.aws.`}];else i.validationEmails=[`admin@${n.domainName}`,`administrator@${n.domainName}`,`hostmaster@${n.domainName}`];return this.validations.set(n.id,i),i}validateCertificate(n){let i=this.certificates.get(n),s=this.validations.get(n);if(!i||!s)return{success:!1,message:"Certificate or validation not found"};return s.validationStatus="SUCCESS",i.status="ISSUED",i.issuedAt=new Date,i.expiresAt=new Date(Date.now()+31536000000),i.renewalEligibility=!0,i.issuer="Amazon",{success:!0,message:"Certificate validated and issued successfully"}}enableAutoRenewal(n){let i=`renewal-${Date.now()}-${this.renewalCounter++}`,s={id:i,certificateArn:n.certificateArn,autoRenew:!0,renewBeforeDays:n.renewBeforeDays||30};return this.renewals.set(i,s),s}async renewCertificate(n){let i=this.renewals.get(n);if(!i)return{success:!1,message:"Renewal configuration not found"};let s=Array.from(this.certificates.values()).find((o)=>o.arn===i.certificateArn);if(!s)return{success:!1,message:"Certificate not found"};console.log(`
3731
3731
  Renewing certificate: ${s.domainName}`),console.log(`Certificate ARN: ${s.arn}`);try{return console.log(`
3732
3732
  1. Requesting new certificate...`),console.log("2. Validating domain ownership..."),console.log("3. Issuing renewed certificate..."),console.log("4. Updating resource associations..."),s.issuedAt=new Date,s.expiresAt=new Date(Date.now()+31536000000),i.lastRenewal=new Date,i.renewalStatus="success",i.nextRenewal=new Date(s.expiresAt.getTime()-i.renewBeforeDays*24*60*60*1000),console.log(`
3733
- ✓ Certificate renewed successfully`),console.log(` New expiration: ${s.expiresAt.toISOString()}`),console.log(` Next renewal: ${i.nextRenewal.toISOString()}`),{success:!0,message:"Certificate renewed successfully"}}catch(o){return i.renewalStatus="failed",this.createAlert({certificateArn:s.arn,alertType:"renewal_failed",severity:"critical",message:`Certificate renewal failed: ${o}`}),{success:!1,message:o instanceof Error?o.message:String(o)}}}createMonitor(n){let i=`monitor-${Date.now()}-${this.monitorCounter++}`,s={id:i,...n};return this.monitors.set(i,s),s}checkExpiration(){let n=[],i=Date.now();for(let s of this.certificates.values()){if(!s.expiresAt)continue;let o=(s.expiresAt.getTime()-i)/86400000;if(o<0)n.push(this.createAlert({certificateArn:s.arn,alertType:"expired",severity:"critical",message:`Certificate has expired for ${s.domainName}`}));else if(o<30)n.push(this.createAlert({certificateArn:s.arn,alertType:"expiring_soon",severity:o<7?"critical":"warning",message:`Certificate expiring in ${Math.floor(o)} days for ${s.domainName}`}))}return n}createAlert(n){let i=`alert-${Date.now()}-${this.alertCounter++}`,s={id:i,timestamp:new Date,acknowledged:!1,...n};return this.alerts.set(i,s),s}acknowledgeAlert(n){let i=this.alerts.get(n);if(i)i.acknowledged=!0}getCertificate(n){return this.certificates.get(n)}listCertificates(){return Array.from(this.certificates.values())}getExpiringCertificates(n=30){let i=Date.now()+n*24*60*60*1000;return Array.from(this.certificates.values()).filter((s)=>s.expiresAt&&s.expiresAt.getTime()<i)}getValidation(n){return this.validations.get(n)}getRenewal(n){return this.renewals.get(n)}listRenewals(){return Array.from(this.renewals.values())}listAlerts(n=!1){return Array.from(this.alerts.values()).filter((i)=>i.acknowledged===n)}generateCertificateCF(n){return{Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:n.domainName,...n.subjectAlternativeNames&&{SubjectAlternativeNames:n.subjectAlternativeNames},ValidationMethod:n.validationMethod}}}generateExpirationAlarmCF(n){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:n.alarmName,AlarmDescription:`Certificate expiring in ${n.daysBeforeExpiration} days`,MetricName:"DaysToExpiry",Namespace:"AWS/CertificateManager",Statistic:"Minimum",Period:86400,EvaluationPeriods:1,Threshold:n.daysBeforeExpiration,ComparisonOperator:"LessThanThreshold",Dimensions:[{Name:"CertificateArn",Value:n.certificateArn}],...n.snsTopicArn&&{AlarmActions:[n.snsTopicArn]}}}}clear(){this.certificates.clear(),this.renewals.clear(),this.validations.clear(),this.monitors.clear(),this.alerts.clear(),this.certificateCounter=0,this.renewalCounter=0,this.validationCounter=0,this.monitorCounter=0,this.alertCounter=0}}var aE=new sf;class of{scans=new Map;findings=new Map;reports=new Map;complianceChecks=new Map;postures=new Map;scanCounter=0;findingCounter=0;reportCounter=0;checkCounter=0;postureCounter=0;createScan(n){let i=`scan-${Date.now()}-${this.scanCounter++}`,s={id:i,status:"queued",findings:[],...n};return this.scans.set(i,s),s}createContainerScan(n){return this.createScan({name:n.name,scanType:"container_image",target:{type:"ecr_image",identifier:n.imageUri,region:n.region||"us-east-1"}})}createLambdaScan(n){return this.createScan({name:n.name,scanType:"vulnerability",target:{type:"lambda",identifier:n.functionName,region:n.region||"us-east-1"}})}createSecretsDetectionScan(n){return this.createScan({name:n.name,scanType:"secrets_detection",target:{type:"repository",identifier:n.repositoryUrl}})}async executeScan(n){let i=this.scans.get(n);if(!i)throw Error(`Scan not found: ${n}`);console.log(`
3733
+ ✓ Certificate renewed successfully`),console.log(` New expiration: ${s.expiresAt.toISOString()}`),console.log(` Next renewal: ${i.nextRenewal.toISOString()}`),{success:!0,message:"Certificate renewed successfully"}}catch(o){return i.renewalStatus="failed",this.createAlert({certificateArn:s.arn,alertType:"renewal_failed",severity:"critical",message:`Certificate renewal failed: ${o}`}),{success:!1,message:o instanceof Error?o.message:String(o)}}}createMonitor(n){let i=`monitor-${Date.now()}-${this.monitorCounter++}`,s={id:i,...n};return this.monitors.set(i,s),s}checkExpiration(){let n=[],i=Date.now();for(let s of this.certificates.values()){if(!s.expiresAt)continue;let o=(s.expiresAt.getTime()-i)/86400000;if(o<0)n.push(this.createAlert({certificateArn:s.arn,alertType:"expired",severity:"critical",message:`Certificate has expired for ${s.domainName}`}));else if(o<30)n.push(this.createAlert({certificateArn:s.arn,alertType:"expiring_soon",severity:o<7?"critical":"warning",message:`Certificate expiring in ${Math.floor(o)} days for ${s.domainName}`}))}return n}createAlert(n){let i=`alert-${Date.now()}-${this.alertCounter++}`,s={id:i,timestamp:new Date,acknowledged:!1,...n};return this.alerts.set(i,s),s}acknowledgeAlert(n){let i=this.alerts.get(n);if(i)i.acknowledged=!0}getCertificate(n){return this.certificates.get(n)}listCertificates(){return Array.from(this.certificates.values())}getExpiringCertificates(n=30){let i=Date.now()+n*24*60*60*1000;return Array.from(this.certificates.values()).filter((s)=>s.expiresAt&&s.expiresAt.getTime()<i)}getValidation(n){return this.validations.get(n)}getRenewal(n){return this.renewals.get(n)}listRenewals(){return Array.from(this.renewals.values())}listAlerts(n=!1){return Array.from(this.alerts.values()).filter((i)=>i.acknowledged===n)}generateCertificateCF(n){return{Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:n.domainName,...n.subjectAlternativeNames&&{SubjectAlternativeNames:n.subjectAlternativeNames},ValidationMethod:n.validationMethod}}}generateExpirationAlarmCF(n){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:n.alarmName,AlarmDescription:`Certificate expiring in ${n.daysBeforeExpiration} days`,MetricName:"DaysToExpiry",Namespace:"AWS/CertificateManager",Statistic:"Minimum",Period:86400,EvaluationPeriods:1,Threshold:n.daysBeforeExpiration,ComparisonOperator:"LessThanThreshold",Dimensions:[{Name:"CertificateArn",Value:n.certificateArn}],...n.snsTopicArn&&{AlarmActions:[n.snsTopicArn]}}}}clear(){this.certificates.clear(),this.renewals.clear(),this.validations.clear(),this.monitors.clear(),this.alerts.clear(),this.certificateCounter=0,this.renewalCounter=0,this.validationCounter=0,this.monitorCounter=0,this.alertCounter=0}}var cE=new of;class af{scans=new Map;findings=new Map;reports=new Map;complianceChecks=new Map;postures=new Map;scanCounter=0;findingCounter=0;reportCounter=0;checkCounter=0;postureCounter=0;createScan(n){let i=`scan-${Date.now()}-${this.scanCounter++}`,s={id:i,status:"queued",findings:[],...n};return this.scans.set(i,s),s}createContainerScan(n){return this.createScan({name:n.name,scanType:"container_image",target:{type:"ecr_image",identifier:n.imageUri,region:n.region||"us-east-1"}})}createLambdaScan(n){return this.createScan({name:n.name,scanType:"vulnerability",target:{type:"lambda",identifier:n.functionName,region:n.region||"us-east-1"}})}createSecretsDetectionScan(n){return this.createScan({name:n.name,scanType:"secrets_detection",target:{type:"repository",identifier:n.repositoryUrl}})}async executeScan(n){let i=this.scans.get(n);if(!i)throw Error(`Scan not found: ${n}`);console.log(`
3734
3734
  Executing security scan: ${i.name}`),console.log(`Scan type: ${i.scanType}`),console.log(`Target: ${i.target.type} - ${i.target.identifier}`),i.status="running",i.startedAt=new Date;try{console.log(`
3735
3735
  Scanning...`);let s=this.simulateFindings(i);return i.findings=s,i.status="completed",i.completedAt=new Date,i.summary={totalFindings:s.length,criticalCount:s.filter((o)=>o.severity==="CRITICAL").length,highCount:s.filter((o)=>o.severity==="HIGH").length,mediumCount:s.filter((o)=>o.severity==="MEDIUM").length,lowCount:s.filter((o)=>o.severity==="LOW").length,infoCount:s.filter((o)=>o.severity==="INFO").length,executionTime:i.completedAt.getTime()-i.startedAt.getTime()},console.log(`
3736
- ✓ Scan completed`),console.log(` Findings: ${i.summary.totalFindings}`),console.log(` Critical: ${i.summary.criticalCount}`),console.log(` High: ${i.summary.highCount}`),console.log(` Medium: ${i.summary.mediumCount}`),console.log(` Low: ${i.summary.lowCount}`),i}catch(s){throw i.status="failed",i.completedAt=new Date,s}}simulateFindings(n){let i=[],s=new Date;if(n.scanType==="container_image")i.push(this.createFinding({severity:"HIGH",title:"Vulnerable OpenSSL version detected",description:"OpenSSL 1.1.1k contains known vulnerabilities",cve:"CVE-2021-3711",cvss:7.5,affectedResource:n.target.identifier,remediation:"Update OpenSSL to version 1.1.1l or later",status:"OPEN",firstDetected:s,lastSeen:s})),i.push(this.createFinding({severity:"MEDIUM",title:"Outdated npm package: lodash",description:"lodash 4.17.19 has known security issues",cve:"CVE-2020-8203",cvss:5.3,affectedResource:n.target.identifier,remediation:"Update lodash to version 4.17.21 or later",status:"OPEN",firstDetected:s,lastSeen:s}));else if(n.scanType==="secrets_detection")i.push(this.createFinding({severity:"CRITICAL",title:"AWS Access Key exposed in code",description:"Hardcoded AWS access key found in source code",affectedResource:`${n.target.identifier}/src/config.ts:12`,remediation:"Remove hardcoded credentials and use AWS Secrets Manager",status:"OPEN",firstDetected:s,lastSeen:s}));return i}createFinding(n){let i=`finding-${Date.now()}-${this.findingCounter++}`,s={id:i,...n};return this.findings.set(i,s),s}suppressFinding(n,i){let s=this.findings.get(n);if(s){if(s.status="SUPPRESSED",console.log(`Finding suppressed: ${s.title}`),i)console.log(`Reason: ${i}`)}}resolveFinding(n){let i=this.findings.get(n);if(i)i.status="RESOLVED",console.log(`Finding resolved: ${i.title}`)}generateReport(n){let i=`report-${Date.now()}-${this.reportCounter++}`,s={id:i,scanId:n.scanId,reportType:n.reportType,format:n.format,generatedAt:new Date,s3Location:`s3://security-reports/${i}.${n.format}`};return this.reports.set(i,s),s}runComplianceCheck(n){let i=[];if(n.framework.includes("CIS"))i.push(this.createComplianceCheck({framework:n.framework,checkId:"1.1",title:"Avoid the use of root account",description:"Root account should not be used for everyday tasks",status:"PASS",severity:"CRITICAL",resourceType:n.resourceType,resourceId:n.resourceId})),i.push(this.createComplianceCheck({framework:n.framework,checkId:"2.1",title:"Ensure CloudTrail is enabled",description:"CloudTrail should be enabled in all regions",status:"FAIL",severity:"HIGH",resourceType:n.resourceType,resourceId:n.resourceId,remediation:"Enable CloudTrail in all regions"}));return i}createComplianceCheck(n){let i=`check-${Date.now()}-${this.checkCounter++}`,s={id:i,...n};return this.complianceChecks.set(i,s),s}assessSecurityPosture(n){let i=`posture-${Date.now()}-${this.postureCounter++}`,s=Array.from(this.complianceChecks.values()),o=s.filter((y)=>y.status==="PASS").length,c=s.length,u=c>0?Math.round(o/c*100):0,d;if(u>=90)d="A";else if(u>=80)d="B";else if(u>=70)d="C";else if(u>=60)d="D";else d="F";let p={id:i,accountId:n.accountId,region:n.region,score:u,grade:d,assessedAt:new Date,strengths:["IAM password policy enforced","Multi-factor authentication enabled","CloudTrail logging enabled"],weaknesses:["Some S3 buckets are publicly accessible","Security groups allow unrestricted ingress","Outdated dependencies in Lambda functions"],recommendations:["Review and update S3 bucket policies","Implement least-privilege security group rules","Update Lambda runtime versions and dependencies","Enable GuardDuty for threat detection"]};return this.postures.set(i,p),p}getScan(n){return this.scans.get(n)}listScans(){return Array.from(this.scans.values())}getOpenFindings(n){return Array.from(this.findings.values()).filter((i)=>i.status==="OPEN"&&(!n||i.severity===n))}getComplianceChecksByStatus(n){return Array.from(this.complianceChecks.values()).filter((i)=>i.status===n)}listPostures(){return Array.from(this.postures.values())}generateECRScanCF(n){return{Type:"AWS::ECR::Repository",Properties:{RepositoryName:n,ImageScanningConfiguration:{ScanOnPush:!0},ImageTagMutability:"IMMUTABLE"}}}clear(){this.scans.clear(),this.findings.clear(),this.reports.clear(),this.complianceChecks.clear(),this.postures.clear(),this.scanCounter=0,this.findingCounter=0,this.reportCounter=0,this.checkCounter=0,this.postureCounter=0}}var cE=new of;class af{configs=new Map;results=new Map;policies=new Map;configCounter=0;resultCounter=0;policyCounter=0;configureScan(n){let i=`scan-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}configureTrivyScan(n){return this.configureScan({repository:n.repository,imageTag:n.imageTag,scanner:"trivy",scanOnPush:n.scanOnPush??!0,ignoreUnfixed:n.ignoreUnfixed??!1,failOnSeverity:"HIGH"})}configureSnykScan(n){return this.configureScan({repository:n.repository,imageTag:n.imageTag,scanner:"snyk",scanOnPush:n.scanOnPush??!0,failOnSeverity:"HIGH"})}configureECRScan(n){return this.configureScan({repository:n.repository,imageTag:"latest",scanner:"ecr",scanOnPush:n.scanOnPush??!0,failOnSeverity:"CRITICAL"})}async scanImage(n){let i=this.configs.get(n);if(!i)throw Error(`Scan config not found: ${n}`);let s=`${i.repository}:${i.imageTag}`;console.log(`
3736
+ ✓ Scan completed`),console.log(` Findings: ${i.summary.totalFindings}`),console.log(` Critical: ${i.summary.criticalCount}`),console.log(` High: ${i.summary.highCount}`),console.log(` Medium: ${i.summary.mediumCount}`),console.log(` Low: ${i.summary.lowCount}`),i}catch(s){throw i.status="failed",i.completedAt=new Date,s}}simulateFindings(n){let i=[],s=new Date;if(n.scanType==="container_image")i.push(this.createFinding({severity:"HIGH",title:"Vulnerable OpenSSL version detected",description:"OpenSSL 1.1.1k contains known vulnerabilities",cve:"CVE-2021-3711",cvss:7.5,affectedResource:n.target.identifier,remediation:"Update OpenSSL to version 1.1.1l or later",status:"OPEN",firstDetected:s,lastSeen:s})),i.push(this.createFinding({severity:"MEDIUM",title:"Outdated npm package: lodash",description:"lodash 4.17.19 has known security issues",cve:"CVE-2020-8203",cvss:5.3,affectedResource:n.target.identifier,remediation:"Update lodash to version 4.17.21 or later",status:"OPEN",firstDetected:s,lastSeen:s}));else if(n.scanType==="secrets_detection")i.push(this.createFinding({severity:"CRITICAL",title:"AWS Access Key exposed in code",description:"Hardcoded AWS access key found in source code",affectedResource:`${n.target.identifier}/src/config.ts:12`,remediation:"Remove hardcoded credentials and use AWS Secrets Manager",status:"OPEN",firstDetected:s,lastSeen:s}));return i}createFinding(n){let i=`finding-${Date.now()}-${this.findingCounter++}`,s={id:i,...n};return this.findings.set(i,s),s}suppressFinding(n,i){let s=this.findings.get(n);if(s){if(s.status="SUPPRESSED",console.log(`Finding suppressed: ${s.title}`),i)console.log(`Reason: ${i}`)}}resolveFinding(n){let i=this.findings.get(n);if(i)i.status="RESOLVED",console.log(`Finding resolved: ${i.title}`)}generateReport(n){let i=`report-${Date.now()}-${this.reportCounter++}`,s={id:i,scanId:n.scanId,reportType:n.reportType,format:n.format,generatedAt:new Date,s3Location:`s3://security-reports/${i}.${n.format}`};return this.reports.set(i,s),s}runComplianceCheck(n){let i=[];if(n.framework.includes("CIS"))i.push(this.createComplianceCheck({framework:n.framework,checkId:"1.1",title:"Avoid the use of root account",description:"Root account should not be used for everyday tasks",status:"PASS",severity:"CRITICAL",resourceType:n.resourceType,resourceId:n.resourceId})),i.push(this.createComplianceCheck({framework:n.framework,checkId:"2.1",title:"Ensure CloudTrail is enabled",description:"CloudTrail should be enabled in all regions",status:"FAIL",severity:"HIGH",resourceType:n.resourceType,resourceId:n.resourceId,remediation:"Enable CloudTrail in all regions"}));return i}createComplianceCheck(n){let i=`check-${Date.now()}-${this.checkCounter++}`,s={id:i,...n};return this.complianceChecks.set(i,s),s}assessSecurityPosture(n){let i=`posture-${Date.now()}-${this.postureCounter++}`,s=Array.from(this.complianceChecks.values()),o=s.filter((y)=>y.status==="PASS").length,c=s.length,u=c>0?Math.round(o/c*100):0,d;if(u>=90)d="A";else if(u>=80)d="B";else if(u>=70)d="C";else if(u>=60)d="D";else d="F";let p={id:i,accountId:n.accountId,region:n.region,score:u,grade:d,assessedAt:new Date,strengths:["IAM password policy enforced","Multi-factor authentication enabled","CloudTrail logging enabled"],weaknesses:["Some S3 buckets are publicly accessible","Security groups allow unrestricted ingress","Outdated dependencies in Lambda functions"],recommendations:["Review and update S3 bucket policies","Implement least-privilege security group rules","Update Lambda runtime versions and dependencies","Enable GuardDuty for threat detection"]};return this.postures.set(i,p),p}getScan(n){return this.scans.get(n)}listScans(){return Array.from(this.scans.values())}getOpenFindings(n){return Array.from(this.findings.values()).filter((i)=>i.status==="OPEN"&&(!n||i.severity===n))}getComplianceChecksByStatus(n){return Array.from(this.complianceChecks.values()).filter((i)=>i.status===n)}listPostures(){return Array.from(this.postures.values())}generateECRScanCF(n){return{Type:"AWS::ECR::Repository",Properties:{RepositoryName:n,ImageScanningConfiguration:{ScanOnPush:!0},ImageTagMutability:"IMMUTABLE"}}}clear(){this.scans.clear(),this.findings.clear(),this.reports.clear(),this.complianceChecks.clear(),this.postures.clear(),this.scanCounter=0,this.findingCounter=0,this.reportCounter=0,this.checkCounter=0,this.postureCounter=0}}var dE=new af;class cf{configs=new Map;results=new Map;policies=new Map;configCounter=0;resultCounter=0;policyCounter=0;configureScan(n){let i=`scan-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}configureTrivyScan(n){return this.configureScan({repository:n.repository,imageTag:n.imageTag,scanner:"trivy",scanOnPush:n.scanOnPush??!0,ignoreUnfixed:n.ignoreUnfixed??!1,failOnSeverity:"HIGH"})}configureSnykScan(n){return this.configureScan({repository:n.repository,imageTag:n.imageTag,scanner:"snyk",scanOnPush:n.scanOnPush??!0,failOnSeverity:"HIGH"})}configureECRScan(n){return this.configureScan({repository:n.repository,imageTag:"latest",scanner:"ecr",scanOnPush:n.scanOnPush??!0,failOnSeverity:"CRITICAL"})}async scanImage(n){let i=this.configs.get(n);if(!i)throw Error(`Scan config not found: ${n}`);let s=`${i.repository}:${i.imageTag}`;console.log(`
3737
3737
  Scanning image: ${s}`),console.log(`Scanner: ${i.scanner}`);let o=`scan-result-${Date.now()}-${this.resultCounter++}`,c=this.simulateVulnerabilities(i),u={total:c.length,critical:c.filter((y)=>y.severity==="CRITICAL").length,high:c.filter((y)=>y.severity==="HIGH").length,medium:c.filter((y)=>y.severity==="MEDIUM").length,low:c.filter((y)=>y.severity==="LOW").length,unknown:c.filter((y)=>y.severity==="UNKNOWN").length},d=this.evaluateScanResult(i,u),p={id:o,imageUri:s,scannerType:i.scanner,scanDate:new Date,vulnerabilities:c,summary:u,passed:d};return this.results.set(o,p),console.log(`
3738
- Scan Results:`),console.log(` Total vulnerabilities: ${u.total}`),console.log(` Critical: ${u.critical}`),console.log(` High: ${u.high}`),console.log(` Medium: ${u.medium}`),console.log(` Low: ${u.low}`),console.log(` Status: ${d?"✓ PASSED":"✗ FAILED"}`),p}simulateVulnerabilities(n){let i=[];if(n.scanner==="trivy"||n.scanner==="ecr")i.push({id:"vuln-1",cve:"CVE-2024-1234",severity:"HIGH",packageName:"openssl",installedVersion:"1.1.1k",fixedVersion:"1.1.1l",title:"OpenSSL buffer overflow",description:"Buffer overflow vulnerability in OpenSSL",references:["https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-1234"],cvss:7.5}),i.push({id:"vuln-2",cve:"CVE-2024-5678",severity:"MEDIUM",packageName:"curl",installedVersion:"7.68.0",fixedVersion:"7.79.0",title:"curl remote code execution",description:"Remote code execution in curl",references:["https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-5678"],cvss:5.3});return i}evaluateScanResult(n,i){if(!n.failOnSeverity)return!0;switch(n.failOnSeverity){case"CRITICAL":return i.critical===0;case"HIGH":return i.critical===0&&i.high===0;case"MEDIUM":return i.critical===0&&i.high===0&&i.medium===0;case"LOW":return i.total===0;default:return!0}}createPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,...n};return this.policies.set(i,s),s}createStrictPolicy(n){return this.createPolicy({name:n,allowedSeverities:[],maxCritical:0,maxHigh:0,blockOnFailure:!0,exemptions:[]})}createPermissivePolicy(n){return this.createPolicy({name:n,allowedSeverities:["CRITICAL","HIGH","MEDIUM","LOW"],maxCritical:5,maxHigh:10,blockOnFailure:!1,exemptions:[]})}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getResult(n){return this.results.get(n)}listResults(){return Array.from(this.results.values())}generateECRScanCF(n){return{Type:"AWS::ECR::Repository",Properties:{RepositoryName:n.repository,ImageScanningConfiguration:{ScanOnPush:n.scanOnPush},ImageTagMutability:"IMMUTABLE",EncryptionConfiguration:{EncryptionType:"AES256"}}}}clear(){this.configs.clear(),this.results.clear(),this.policies.clear(),this.configCounter=0,this.resultCounter=0,this.policyCounter=0}}var dE=new af;class cf{configs=new Map;multiStageConfigs=new Map;optimizations=new Map;analyses=new Map;configCounter=0;multiStageCounter=0;optimizationCounter=0;analysisCounter=0;createBuildConfig(n){let i=`build-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}createOptimizedBuildConfig(n){let i={type:n.enableCache?"registry":"inline",cacheFrom:n.registry?[`${n.registry}/cache`]:void 0,cacheTo:n.registry?`${n.registry}/cache`:void 0,maxCacheAge:7};return this.createBuildConfig({name:n.name,dockerfile:n.dockerfile,context:".",cacheStrategy:i,buildArgs:{BUILDKIT_INLINE_CACHE:"1"}})}createMultiStageConfig(n){let i=`multi-stage-${Date.now()}-${this.multiStageCounter++}`,s={id:i,...n};return this.multiStageConfigs.set(i,s),s}createNodeMultiStageBuild(n){let i=n.nodeVersion||"18-alpine";return this.createMultiStageConfig({name:n.name,targetStage:n.targetStage||"production",stages:[{name:"dependencies",baseImage:`node:${i}`,workdir:"/app",commands:["COPY package*.json ./","RUN npm ci --only=production"]},{name:"build",baseImage:`node:${i}`,workdir:"/app",commands:["COPY package*.json ./","RUN npm ci","COPY . .","RUN npm run build"]},{name:"production",baseImage:`node:${i}`,workdir:"/app",copyFrom:["dependencies:/app/node_modules","build:/app/dist"],commands:["COPY package*.json ./","ENV NODE_ENV=production",'CMD ["node", "dist/index.js"]']}]})}generateDockerfile(n){let i=this.multiStageConfigs.get(n);if(!i)throw Error(`Multi-stage config not found: ${n}`);let s=[];for(let o of i.stages){if(s.push(`# Stage: ${o.name}`),s.push(`FROM ${o.baseImage} AS ${o.name}`),o.workdir)s.push(`WORKDIR ${o.workdir}`);if(o.env)for(let[c,u]of Object.entries(o.env))s.push(`ENV ${c}=${u}`);for(let c of o.commands)s.push(c);s.push("")}return s.join(`
3738
+ Scan Results:`),console.log(` Total vulnerabilities: ${u.total}`),console.log(` Critical: ${u.critical}`),console.log(` High: ${u.high}`),console.log(` Medium: ${u.medium}`),console.log(` Low: ${u.low}`),console.log(` Status: ${d?"✓ PASSED":"✗ FAILED"}`),p}simulateVulnerabilities(n){let i=[];if(n.scanner==="trivy"||n.scanner==="ecr")i.push({id:"vuln-1",cve:"CVE-2024-1234",severity:"HIGH",packageName:"openssl",installedVersion:"1.1.1k",fixedVersion:"1.1.1l",title:"OpenSSL buffer overflow",description:"Buffer overflow vulnerability in OpenSSL",references:["https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-1234"],cvss:7.5}),i.push({id:"vuln-2",cve:"CVE-2024-5678",severity:"MEDIUM",packageName:"curl",installedVersion:"7.68.0",fixedVersion:"7.79.0",title:"curl remote code execution",description:"Remote code execution in curl",references:["https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-5678"],cvss:5.3});return i}evaluateScanResult(n,i){if(!n.failOnSeverity)return!0;switch(n.failOnSeverity){case"CRITICAL":return i.critical===0;case"HIGH":return i.critical===0&&i.high===0;case"MEDIUM":return i.critical===0&&i.high===0&&i.medium===0;case"LOW":return i.total===0;default:return!0}}createPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,...n};return this.policies.set(i,s),s}createStrictPolicy(n){return this.createPolicy({name:n,allowedSeverities:[],maxCritical:0,maxHigh:0,blockOnFailure:!0,exemptions:[]})}createPermissivePolicy(n){return this.createPolicy({name:n,allowedSeverities:["CRITICAL","HIGH","MEDIUM","LOW"],maxCritical:5,maxHigh:10,blockOnFailure:!1,exemptions:[]})}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getResult(n){return this.results.get(n)}listResults(){return Array.from(this.results.values())}generateECRScanCF(n){return{Type:"AWS::ECR::Repository",Properties:{RepositoryName:n.repository,ImageScanningConfiguration:{ScanOnPush:n.scanOnPush},ImageTagMutability:"IMMUTABLE",EncryptionConfiguration:{EncryptionType:"AES256"}}}}clear(){this.configs.clear(),this.results.clear(),this.policies.clear(),this.configCounter=0,this.resultCounter=0,this.policyCounter=0}}var lE=new cf;class df{configs=new Map;multiStageConfigs=new Map;optimizations=new Map;analyses=new Map;configCounter=0;multiStageCounter=0;optimizationCounter=0;analysisCounter=0;createBuildConfig(n){let i=`build-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}createOptimizedBuildConfig(n){let i={type:n.enableCache?"registry":"inline",cacheFrom:n.registry?[`${n.registry}/cache`]:void 0,cacheTo:n.registry?`${n.registry}/cache`:void 0,maxCacheAge:7};return this.createBuildConfig({name:n.name,dockerfile:n.dockerfile,context:".",cacheStrategy:i,buildArgs:{BUILDKIT_INLINE_CACHE:"1"}})}createMultiStageConfig(n){let i=`multi-stage-${Date.now()}-${this.multiStageCounter++}`,s={id:i,...n};return this.multiStageConfigs.set(i,s),s}createNodeMultiStageBuild(n){let i=n.nodeVersion||"18-alpine";return this.createMultiStageConfig({name:n.name,targetStage:n.targetStage||"production",stages:[{name:"dependencies",baseImage:`node:${i}`,workdir:"/app",commands:["COPY package*.json ./","RUN npm ci --only=production"]},{name:"build",baseImage:`node:${i}`,workdir:"/app",commands:["COPY package*.json ./","RUN npm ci","COPY . .","RUN npm run build"]},{name:"production",baseImage:`node:${i}`,workdir:"/app",copyFrom:["dependencies:/app/node_modules","build:/app/dist"],commands:["COPY package*.json ./","ENV NODE_ENV=production",'CMD ["node", "dist/index.js"]']}]})}generateDockerfile(n){let i=this.multiStageConfigs.get(n);if(!i)throw Error(`Multi-stage config not found: ${n}`);let s=[];for(let o of i.stages){if(s.push(`# Stage: ${o.name}`),s.push(`FROM ${o.baseImage} AS ${o.name}`),o.workdir)s.push(`WORKDIR ${o.workdir}`);if(o.env)for(let[c,u]of Object.entries(o.env))s.push(`ENV ${c}=${u}`);for(let c of o.commands)s.push(c);s.push("")}return s.join(`
3739
3739
  `)}analyzeImage(n,i){let s=`analysis-${Date.now()}-${this.analysisCounter++}`,o=i.map((p)=>({...p,cacheable:this.isLayerCacheable(p.command)})),c=o.reduce((p,y)=>p+y.size,0),u=o.filter((p)=>!p.cacheable&&p.size>100).length,d={id:s,imageId:n,layers:o,totalSize:c,unnecessaryLayers:u};return this.analyses.set(s,d),d}isLayerCacheable(n){let i=["FROM","RUN","COPY","ADD","WORKDIR","ENV"],s=["CMD","ENTRYPOINT","LABEL"];for(let o of i)if(n.startsWith(o))return!0;for(let o of s)if(n.startsWith(o))return!1;return!1}generateOptimizations(n){let i=this.analyses.get(n);if(!i)throw Error(`Analysis not found: ${n}`);let s=`optimization-${Date.now()}-${this.optimizationCounter++}`,o=[],c=i.layers.filter((h)=>h.command.startsWith("RUN"));if(c.length>5)o.push({type:"layer_reduction",priority:"high",title:"Combine RUN commands",description:`${c.length} RUN commands found. Combine them to reduce layers.`,example:"RUN apt-get update && apt-get install -y package1 package2",impact:"Reduce image size by 20-30% and improve build time"});let u=i.layers[0];if(u.command.includes("ubuntu")||u.command.includes("debian"))o.push({type:"base_image",priority:"medium",title:"Use Alpine base image",description:"Switch to Alpine Linux for smaller image size",example:"FROM node:18-alpine",impact:"Reduce image size by 50-70%"});let d=i.layers.filter((h)=>h.command.startsWith("COPY"));if(d.length>0&&d[0].index>3)o.push({type:"cache_optimization",priority:"high",title:"Copy dependencies first",description:"Copy package files before source code to leverage layer caching",example:`COPY package*.json ./
3740
3740
  RUN npm install
3741
- COPY . .`,impact:"Improve build time by 60-80% on subsequent builds"});let p={sizeBefore:i.totalSize,sizeAfter:i.totalSize*0.6,timeBefore:300,timeAfter:120},y={id:s,name:`Optimization for ${i.imageId}`,recommendations:o,estimatedSavings:p};return this.optimizations.set(s,y),y}getBuildConfig(n){return this.configs.get(n)}listBuildConfigs(){return Array.from(this.configs.values())}getMultiStageConfig(n){return this.multiStageConfigs.get(n)}listMultiStageConfigs(){return Array.from(this.multiStageConfigs.values())}getOptimization(n){return this.optimizations.get(n)}listOptimizations(){return Array.from(this.optimizations.values())}clear(){this.configs.clear(),this.multiStageConfigs.clear(),this.optimizations.clear(),this.analyses.clear(),this.configCounter=0,this.multiStageCounter=0,this.optimizationCounter=0,this.analysisCounter=0}}var lE=new cf;class Ol{registries=new Map;credentials=new Map;registryCounter=0;credentialsCounter=0;createRegistry(n){let i=`registry-${Date.now()}-${this.registryCounter++}`,s={id:i,...n};return this.registries.set(i,s),s}createECRRepository(n){return this.createRegistry({name:n.name,registryType:"ecr",repositoryUri:`123456789012.dkr.ecr.${n.region||"us-east-1"}.amazonaws.com/${n.name}`,region:n.region||"us-east-1",encryption:{encryptionType:n.encryption||"AES256",kmsKeyId:n.kmsKeyId},scanning:{scanOnPush:n.scanOnPush??!0}})}createManagedRepository(n){let i=this.createECRRepository({name:n.name,region:n.region,scanOnPush:!0,encryption:"KMS"});return i.lifecycle={id:`lifecycle-${Date.now()}`,rules:[{rulePriority:1,description:"Keep only last N images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:n.maxImageCount||10},action:{type:"expire"}},{rulePriority:2,description:"Remove images older than N days",selection:{tagStatus:"untagged",countType:"sinceImagePushed",countNumber:n.maxImageAgeDays||30,countUnit:"days"},action:{type:"expire"}}]},i}enableReplication(n,i){let s=this.registries.get(n);if(!s)throw Error(`Registry not found: ${n}`);return s.replication={enabled:!0,destinations:i},s}createCredentials(n){let i=`creds-${Date.now()}-${this.credentialsCounter++}`,s={id:i,...n};return this.credentials.set(i,s),s}getRegistry(n){return this.registries.get(n)}listRegistries(){return Array.from(this.registries.values())}generateECRRepositoryCF(n){return{Type:"AWS::ECR::Repository",Properties:{RepositoryName:n.name,ImageScanningConfiguration:{ScanOnPush:n.scanning?.scanOnPush??!1},EncryptionConfiguration:{EncryptionType:n.encryption?.encryptionType||"AES256",...n.encryption?.kmsKeyId&&{KmsKey:n.encryption.kmsKeyId}},ImageTagMutability:"MUTABLE",...n.lifecycle&&{LifecyclePolicy:{LifecyclePolicyText:JSON.stringify({rules:n.lifecycle.rules})}}}}}generateReplicationConfigCF(n){return{Type:"AWS::ECR::ReplicationConfiguration",Properties:{ReplicationConfiguration:{Rules:n.destinations.map((i)=>({Destinations:[{Region:i.region,...i.registryId&&{RegistryId:i.registryId}}]}))}}}}clear(){this.registries.clear(),this.credentials.clear(),this.registryCounter=0,this.credentialsCounter=0}}var oS=new Ol;class _l{meshes=new Map;virtualNodes=new Map;virtualRouters=new Map;virtualGateways=new Map;meshCounter=0;nodeCounter=0;routerCounter=0;gatewayCounter=0;createMesh(n){let i=`mesh-${Date.now()}-${this.meshCounter++}`,s={id:i,...n};return this.meshes.set(i,s),s}createAppMesh(n){return this.createMesh({name:n.name,meshType:"app_mesh",services:n.services,virtualNodes:[],virtualRouters:[],virtualGateways:[]})}createVirtualNode(n){let i=`vnode-${Date.now()}-${this.nodeCounter++}`,s={id:i,...n};return this.virtualNodes.set(i,s),s}createHTTPVirtualNode(n){return this.createVirtualNode({name:n.name,serviceName:n.serviceName,listeners:[{port:n.port,protocol:"http",healthCheck:{protocol:"http",path:"/health",interval:30,timeout:10,healthyThreshold:2,unhealthyThreshold:3},timeout:{perRequest:15000,idle:300000}}],serviceDiscovery:{type:"aws_cloud_map",namespace:n.namespace,serviceName:n.serviceName}})}createVirtualRouter(n){let i=`vrouter-${Date.now()}-${this.routerCounter++}`,s={id:i,...n};return this.virtualRouters.set(i,s),s}createCanaryRoute(n){return this.createVirtualRouter({name:n.name,listeners:[{port:n.port,protocol:n.protocol}],routes:[{name:"canary-route",match:{prefix:"/"},action:{weightedTargets:[{virtualNode:n.stableTarget,weight:100-n.canaryWeight},{virtualNode:n.canaryTarget,weight:n.canaryWeight}]},retryPolicy:{maxRetries:3,perRetryTimeout:5000,httpRetryEvents:["server-error","gateway-error"],tcpRetryEvents:["connection-error"]}}]})}createVirtualGateway(n){let i=`vgateway-${Date.now()}-${this.gatewayCounter++}`,s={id:i,...n};return this.virtualGateways.set(i,s),s}createIngressGateway(n){let i={port:n.port,protocol:"http",healthCheck:{protocol:"http",path:"/health",interval:30,timeout:10,healthyThreshold:2,unhealthyThreshold:3}};if(n.enableTLS&&n.certificateArn)i.tls={mode:"STRICT",certificate:{acm:n.certificateArn}};return this.createVirtualGateway({name:n.name,listeners:[i],logging:{accessLog:{file:{path:"/dev/stdout"}}}})}getMesh(n){return this.meshes.get(n)}listMeshes(){return Array.from(this.meshes.values())}getVirtualNode(n){return this.virtualNodes.get(n)}listVirtualNodes(){return Array.from(this.virtualNodes.values())}generateMeshCF(n){return{Type:"AWS::AppMesh::Mesh",Properties:{MeshName:n.name,Spec:{EgressFilter:{Type:"ALLOW_ALL"}}}}}generateVirtualNodeCF(n,i){return{Type:"AWS::AppMesh::VirtualNode",Properties:{MeshName:i,VirtualNodeName:n.name,Spec:{Listeners:n.listeners.map((s)=>({PortMapping:{Port:s.port,Protocol:s.protocol},...s.healthCheck&&{HealthCheck:{Protocol:s.healthCheck.protocol,...s.healthCheck.path&&{Path:s.healthCheck.path},IntervalMillis:s.healthCheck.interval*1000,TimeoutMillis:s.healthCheck.timeout*1000,HealthyThreshold:s.healthCheck.healthyThreshold,UnhealthyThreshold:s.healthCheck.unhealthyThreshold}}})),ServiceDiscovery:{AWSCloudMap:{NamespaceName:n.serviceDiscovery.namespace,ServiceName:n.serviceDiscovery.serviceName}}}}}}generateVirtualRouterCF(n,i){return{Type:"AWS::AppMesh::VirtualRouter",Properties:{MeshName:i,VirtualRouterName:n.name,Spec:{Listeners:n.listeners.map((s)=>({PortMapping:{Port:s.port,Protocol:s.protocol}}))}}}}clear(){this.meshes.clear(),this.virtualNodes.clear(),this.virtualRouters.clear(),this.virtualGateways.clear(),this.meshCounter=0,this.nodeCounter=0,this.routerCounter=0,this.gatewayCounter=0}}var aS=new _l;class df{layers=new Map;versions=new Map;permissions=new Map;layerCounter=0;versionCounter=0;permissionCounter=0;createLayer(n){let i=`layer-${Date.now()}-${this.layerCounter++}`,s=1,o={id:i,layerArn:`arn:aws:lambda:us-east-1:123456789012:layer:${n.layerName}:1`,version:1,...n};return this.layers.set(i,o),o}createNodeDependenciesLayer(n){return this.createLayer({layerName:n.layerName,description:"Node.js dependencies layer",compatibleRuntimes:[`nodejs${n.nodeVersion}`],content:{type:"s3",s3Bucket:n.s3Bucket,s3Key:n.s3Key},size:5242880})}createUtilitiesLayer(n){return this.createLayer({layerName:n.layerName,description:"Shared utilities and helpers",compatibleRuntimes:n.runtimes,content:{type:"s3",s3Bucket:n.s3Bucket,s3Key:n.s3Key},size:1048576})}publishVersion(n){let i=this.layers.get(n);if(!i)throw Error(`Layer not found: ${n}`);let s=`version-${Date.now()}-${this.versionCounter++}`,o=i.version+1,c={id:s,layerName:i.layerName,version:o,createdAt:new Date,compatibleRuntimes:i.compatibleRuntimes,size:i.size,codeHash:this.generateHash()};return this.versions.set(s,c),i.version=o,i.layerArn=`arn:aws:lambda:us-east-1:123456789012:layer:${i.layerName}:${o}`,c}addPermission(n){let i=`permission-${Date.now()}-${this.permissionCounter++}`,s={id:i,layerName:n.layerName,version:n.version,principal:n.principal,action:"lambda:GetLayerVersion",organizationId:n.organizationId};return this.permissions.set(i,s),s}generateHash(){return Math.random().toString(36).substring(2,15)}getLayer(n){return this.layers.get(n)}listLayers(){return Array.from(this.layers.values())}getLayerVersions(n){return Array.from(this.versions.values()).filter((i)=>i.layerName===n)}generateLayerCF(n){return{Type:"AWS::Lambda::LayerVersion",Properties:{LayerName:n.layerName,Description:n.description,Content:n.content.type==="s3"?{S3Bucket:n.content.s3Bucket,S3Key:n.content.s3Key,...n.content.s3ObjectVersion&&{S3ObjectVersion:n.content.s3ObjectVersion}}:{ZipFile:n.content.zipFile},CompatibleRuntimes:n.compatibleRuntimes,...n.licenseInfo&&{LicenseInfo:n.licenseInfo}}}}generateLayerPermissionCF(n){return{Type:"AWS::Lambda::LayerVersionPermission",Properties:{LayerVersionArn:`arn:aws:lambda:us-east-1:123456789012:layer:${n.layerName}:${n.version}`,Action:n.action,Principal:n.principal,...n.organizationId&&{OrganizationId:n.organizationId}}}}clear(){this.layers.clear(),this.versions.clear(),this.permissions.clear(),this.layerCounter=0,this.versionCounter=0,this.permissionCounter=0}}var uE=new df;class lf{versions=new Map;aliases=new Map;deployments=new Map;versionCounter=0;aliasCounter=0;deploymentCounter=0;publishVersion(n){let i=`version-${Date.now()}-${this.versionCounter++}`,s=this.getNextVersionNumber(n.functionName),o={id:i,functionName:n.functionName,version:s.toString(),functionArn:`arn:aws:lambda:us-east-1:123456789012:function:${n.functionName}:${s}`,codeHash:this.generateHash(),description:n.description,runtime:n.runtime,memorySize:n.memorySize,timeout:n.timeout,publishedAt:new Date};return this.versions.set(i,o),o}getNextVersionNumber(n){let i=Array.from(this.versions.values()).filter((s)=>s.functionName===n).map((s)=>parseInt(s.version));return i.length>0?Math.max(...i)+1:1}createAlias(n){let i=`alias-${Date.now()}-${this.aliasCounter++}`,s={id:i,aliasArn:`arn:aws:lambda:us-east-1:123456789012:function:${n.functionName}:${n.aliasName}`,revisionId:this.generateHash(),...n};return this.aliases.set(i,s),s}createProductionAlias(n){return this.createAlias({functionName:n.functionName,aliasName:"production",functionVersion:n.version,description:"Production alias"})}createStagingAlias(n){return this.createAlias({functionName:n.functionName,aliasName:"staging",functionVersion:n.version,description:"Staging alias"})}updateAlias(n,i){let s=this.aliases.get(n);if(!s)throw Error(`Alias not found: ${n}`);return s.functionVersion=i,s.revisionId=this.generateHash(),s}configureWeightedRouting(n,i){let s=this.aliases.get(n);if(!s)throw Error(`Alias not found: ${n}`);return s.routingConfig={additionalVersionWeights:i},s}createCanaryDeployment(n){let i=`deployment-${Date.now()}-${this.deploymentCounter++}`,s=Array.from(this.aliases.values()).find((c)=>c.functionName===n.functionName&&c.aliasName===n.aliasName);if(!s)s=this.createAlias({functionName:n.functionName,aliasName:n.aliasName,functionVersion:n.fromVersion});this.configureWeightedRouting(s.id,{[n.toVersion]:n.canaryWeight});let o={id:i,functionName:n.functionName,fromVersion:n.fromVersion,toVersion:n.toVersion,aliasName:n.aliasName,strategy:"canary",status:"in_progress",startedAt:new Date};return this.deployments.set(i,o),o}completeDeployment(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);let s=Array.from(this.aliases.values()).find((o)=>o.functionName===i.functionName&&o.aliasName===i.aliasName);if(s)s.functionVersion=i.toVersion,s.routingConfig=void 0;return i.status="completed",i.completedAt=new Date,i}rollbackDeployment(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);let s=Array.from(this.aliases.values()).find((o)=>o.functionName===i.functionName&&o.aliasName===i.aliasName);if(s)s.functionVersion=i.fromVersion,s.routingConfig=void 0;return i.status="failed",i.completedAt=new Date,i}generateHash(){return Math.random().toString(36).substring(2,15)}getVersion(n){return this.versions.get(n)}listVersions(n){let i=Array.from(this.versions.values());return n?i.filter((s)=>s.functionName===n):i}getAlias(n){return this.aliases.get(n)}listAliases(n){let i=Array.from(this.aliases.values());return n?i.filter((s)=>s.functionName===n):i}generateVersionCF(n){return{Type:"AWS::Lambda::Version",Properties:{FunctionName:n.functionName,Description:n.description}}}generateAliasCF(n){return{Type:"AWS::Lambda::Alias",Properties:{FunctionName:n.functionName,Name:n.aliasName,FunctionVersion:n.functionVersion,Description:n.description,...n.routingConfig&&{RoutingConfig:{AdditionalVersionWeights:Object.entries(n.routingConfig.additionalVersionWeights||{}).map(([i,s])=>({FunctionVersion:i,FunctionWeight:s}))}}}}}clear(){this.versions.clear(),this.aliases.clear(),this.deployments.clear(),this.versionCounter=0,this.aliasCounter=0,this.deploymentCounter=0}}var gE=new lf;class uf{configs=new Map;provisionedConfigs=new Map;schedules=new Map;autoScalingConfigs=new Map;configCounter=0;provisionedCounter=0;scheduleCounter=0;autoScalingCounter=0;setReservedConcurrency(n){let i=`concurrency-${Date.now()}-${this.configCounter++}`,s={id:i,functionName:n.functionName,reservedConcurrency:n.reservedConcurrency};return this.configs.set(i,s),s}setProvisionedConcurrency(n){let i=`provisioned-${Date.now()}-${this.provisionedCounter++}`,s={id:i,functionName:n.functionName,qualifier:n.qualifier,provisionedConcurrentExecutions:n.provisionedConcurrentExecutions,status:"pending",lastModified:new Date};return this.provisionedConfigs.set(i,s),setTimeout(()=>{s.status="ready",s.allocatedConcurrency=n.provisionedConcurrentExecutions,s.availableConcurrency=n.provisionedConcurrentExecutions},100),s}configureWarmPool(n){return this.setProvisionedConcurrency({functionName:n.functionName,qualifier:n.alias,provisionedConcurrentExecutions:n.minInstances})}createSchedule(n){let i=`schedule-${Date.now()}-${this.scheduleCounter++}`,s={id:i,...n};return this.schedules.set(i,s),s}createBusinessHoursSchedule(n){return this.createSchedule({name:`${n.functionName}-business-hours`,functionName:n.functionName,qualifier:n.qualifier,schedule:[{name:"business-hours",cronExpression:"0 8 * * MON-FRI",targetConcurrency:n.businessHoursConcurrency},{name:"off-hours",cronExpression:"0 18 * * MON-FRI",targetConcurrency:n.offHoursConcurrency},{name:"weekend",cronExpression:"0 0 * * SAT",targetConcurrency:n.offHoursConcurrency}]})}configureAutoScaling(n){let i=`autoscaling-${Date.now()}-${this.autoScalingCounter++}`,s={id:i,...n};return this.autoScalingConfigs.set(i,s),s}configurePredictiveScaling(n){return this.configureAutoScaling({functionName:n.functionName,qualifier:n.qualifier,minCapacity:n.baselineCapacity,maxCapacity:n.peakCapacity,targetUtilization:0.7,scaleInCooldown:300,scaleOutCooldown:60})}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getProvisionedConfig(n){return this.provisionedConfigs.get(n)}listProvisionedConfigs(){return Array.from(this.provisionedConfigs.values())}generateReservedConcurrencyCF(n){return{Type:"AWS::Lambda::Function",Properties:{FunctionName:n.functionName,ReservedConcurrentExecutions:n.reservedConcurrency}}}generateProvisionedConcurrencyCF(n){return{Type:"AWS::Lambda::Alias",Properties:{FunctionName:n.functionName,Name:n.qualifier,ProvisionedConcurrencyConfig:{ProvisionedConcurrentExecutions:n.provisionedConcurrentExecutions}}}}generateAutoScalingTargetCF(n){return{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{ServiceNamespace:"lambda",ResourceId:`function:${n.functionName}:${n.qualifier}`,ScalableDimension:"lambda:function:ProvisionedConcurrentExecutions",MinCapacity:n.minCapacity,MaxCapacity:n.maxCapacity}}}generateAutoScalingPolicyCF(n){return{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${n.functionName}-autoscaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:`${n.functionName}AutoScalingTarget`},TargetTrackingScalingPolicyConfiguration:{TargetValue:n.targetUtilization*100,PredefinedMetricSpecification:{PredefinedMetricType:"LambdaProvisionedConcurrencyUtilization"},ScaleInCooldown:n.scaleInCooldown||300,ScaleOutCooldown:n.scaleOutCooldown||60}}}}clear(){this.configs.clear(),this.provisionedConfigs.clear(),this.schedules.clear(),this.autoScalingConfigs.clear(),this.configCounter=0,this.provisionedCounter=0,this.scheduleCounter=0,this.autoScalingCounter=0}}var pE=new uf;class gf{destinations=new Map;records=new Map;eventBridgeDestinations=new Map;destinationCounter=0;recordCounter=0;eventBridgeCounter=0;configureDestinations(n){let i=`destination-${Date.now()}-${this.destinationCounter++}`,s={id:i,...n};return this.destinations.set(i,s),s}configureSQSDestination(n){let i={type:"sqs",arn:n.queueArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureSNSDestination(n){let i={type:"sns",arn:n.topicArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureEventBridgeDestination(n){let i={type:"eventbridge",arn:n.eventBusArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureLambdaDestination(n){let i={type:"lambda",arn:n.destinationFunctionArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureDLQWithNotification(n){return this.configureDestinations({functionName:n.functionName,failureDestination:{type:"sqs",arn:n.dlqArn},maxEventAge:3600,maxRetries:0})}createEventBridgeIntegration(n){let i=`eventbridge-${Date.now()}-${this.eventBridgeCounter++}`,s={id:i,functionName:n.functionName,eventBusArn:n.eventBusArn,detailType:n.detailType||"Lambda Function Invocation Result",source:n.source||`lambda.${n.functionName}`};return this.eventBridgeDestinations.set(i,s),s}sendToDestination(n){let i=Array.from(this.destinations.values()).find((u)=>u.functionName===n.functionName);if(!i)return null;let s=n.status==="success"?i.successDestination:i.failureDestination;if(!s)return null;let o=`record-${Date.now()}-${this.recordCounter++}`,c={id:o,timestamp:new Date,functionName:n.functionName,requestId:n.requestId,status:n.status,destinationType:s.type,destinationArn:s.arn,payload:n.payload,error:n.error};return this.records.set(o,c),c}getDestination(n){return this.destinations.get(n)}listDestinations(n){let i=Array.from(this.destinations.values());return n?i.filter((s)=>s.functionName===n):i}getDestinationRecords(n){let i=Array.from(this.records.values());return n?i.filter((s)=>s.functionName===n):i}generateEventInvokeConfigCF(n){return{Type:"AWS::Lambda::EventInvokeConfig",Properties:{FunctionName:n.functionName,Qualifier:n.qualifier||"$LATEST",MaximumEventAgeInSeconds:n.maxEventAge||21600,MaximumRetryAttempts:n.maxRetries??2,...n.successDestination&&{DestinationConfig:{OnSuccess:{Destination:n.successDestination.arn}}},...n.failureDestination&&{DestinationConfig:{OnFailure:{Destination:n.failureDestination.arn}}}}}}generateEventBridgeRuleCF(n){return{Type:"AWS::Events::Rule",Properties:{EventBusName:n.eventBusArn.split("/").pop(),EventPattern:{source:[n.source],"detail-type":[n.detailType]},State:"ENABLED",Targets:[{Arn:`arn:aws:lambda:us-east-1:123456789012:function:${n.functionName}`,Id:n.id}]}}}clear(){this.destinations.clear(),this.records.clear(),this.eventBridgeDestinations.clear(),this.destinationCounter=0,this.recordCounter=0,this.eventBridgeCounter=0}}var mE=new gf;class pf{vpcConfigs=new Map;endpoints=new Map;networkInterfaces=new Map;connectivity=new Map;configCounter=0;endpointCounter=0;eniCounter=0;connectivityCounter=0;configureVPC(n){let i=`vpc-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};this.vpcConfigs.set(i,s);for(let o of n.subnetIds)this.createNetworkInterface({functionName:n.functionName,subnetId:o});return s}configurePrivateVPC(n){return this.configureVPC({functionName:n.functionName,vpcId:n.vpcId,subnetIds:n.privateSubnetIds,securityGroupIds:[n.securityGroupId],ipv6Allowed:!1})}configureMultiAZVPC(n){if(n.subnetIds.length<2)throw Error("Multi-AZ configuration requires at least 2 subnets");return this.configureVPC({functionName:n.functionName,vpcId:n.vpcId,subnetIds:n.subnetIds,securityGroupIds:n.securityGroupIds})}createVPCEndpoint(n){let i=`endpoint-${Date.now()}-${this.endpointCounter++}`,s={id:i,...n};return this.endpoints.set(i,s),s}createS3Endpoint(n){return this.createVPCEndpoint({vpcId:n.vpcId,serviceName:"com.amazonaws.us-east-1.s3",endpointType:"Gateway",privateDnsEnabled:!1})}createDynamoDBEndpoint(n){return this.createVPCEndpoint({vpcId:n.vpcId,serviceName:"com.amazonaws.us-east-1.dynamodb",endpointType:"Gateway",privateDnsEnabled:!1})}createSecretsManagerEndpoint(n){return this.createVPCEndpoint({vpcId:n.vpcId,serviceName:"com.amazonaws.us-east-1.secretsmanager",endpointType:"Interface",subnetIds:n.subnetIds,securityGroupIds:n.securityGroupIds,privateDnsEnabled:!0})}createNetworkInterface(n){let i=`eni-${Date.now()}-${this.eniCounter++}`,s={id:i,functionName:n.functionName,networkInterfaceId:`eni-${Math.random().toString(36).substring(2,15)}`,subnetId:n.subnetId,privateIpAddress:`10.0.${Math.floor(Math.random()*255)}.${Math.floor(Math.random()*255)}`,status:"creating",attachedAt:new Date};return this.networkInterfaces.set(i,s),setTimeout(()=>{s.status="available"},100),s}analyzeConnectivity(n){let i=`connectivity-${Date.now()}-${this.connectivityCounter++}`,s=Array.from(this.vpcConfigs.values()).find((y)=>y.functionName===n.functionName),o=Array.from(this.endpoints.values()).filter((y)=>y.vpcId===s?.vpcId).map((y)=>y.serviceName),c=[],u=n.hasNATGateway??!1,d=n.hasInternetGateway??!1;if(!u&&!d)c.push("Add NAT Gateway for internet access");if(!o.includes("com.amazonaws.us-east-1.s3"))c.push("Add S3 VPC endpoint to reduce NAT costs");if(!o.includes("com.amazonaws.us-east-1.dynamodb"))c.push("Add DynamoDB VPC endpoint for private access");let p={id:i,functionName:n.functionName,hasInternetAccess:u||d,hasNATGateway:u,hasVPCEndpoints:o.length>0,endpoints:o,recommendations:c};return this.connectivity.set(i,p),p}getVPCConfig(n){return this.vpcConfigs.get(n)}listVPCConfigs(n){let i=Array.from(this.vpcConfigs.values());return n?i.filter((s)=>s.functionName===n):i}getNetworkInterfaces(n){return Array.from(this.networkInterfaces.values()).filter((i)=>i.functionName===n)}listVPCEndpoints(n){let i=Array.from(this.endpoints.values());return n?i.filter((s)=>s.vpcId===n):i}generateVPCConfigCF(n){return{VpcConfig:{SubnetIds:n.subnetIds,SecurityGroupIds:n.securityGroupIds,...n.ipv6Allowed&&{Ipv6AllowedForDualStack:!0}}}}generateVPCEndpointCF(n){return{Type:"AWS::EC2::VPCEndpoint",Properties:{VpcId:n.vpcId,ServiceName:n.serviceName,VpcEndpointType:n.endpointType,...n.subnetIds&&{SubnetIds:n.subnetIds},...n.securityGroupIds&&{SecurityGroupIds:n.securityGroupIds},...n.privateDnsEnabled!==void 0&&{PrivateDnsEnabled:n.privateDnsEnabled}}}}generateSecurityGroupCF(n){return{Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:n.groupName,GroupDescription:`Security group for Lambda ${n.groupName}`,VpcId:n.vpcId,...n.ingressRules&&{SecurityGroupIngress:n.ingressRules.map((i)=>({IpProtocol:i.protocol,FromPort:i.fromPort,ToPort:i.toPort,...i.cidrIp&&{CidrIp:i.cidrIp},...i.sourceSecurityGroupId&&{SourceSecurityGroupId:i.sourceSecurityGroupId}}))},...n.egressRules&&{SecurityGroupEgress:n.egressRules.map((i)=>({IpProtocol:i.protocol,FromPort:i.fromPort,ToPort:i.toPort,CidrIp:i.cidrIp||"0.0.0.0/0"}))}}}}clear(){this.vpcConfigs.clear(),this.endpoints.clear(),this.networkInterfaces.clear(),this.connectivity.clear(),this.configCounter=0,this.endpointCounter=0,this.eniCounter=0,this.connectivityCounter=0}}var fE=new pf;class mf{dlqConfigs=new Map;messages=new Map;alarms=new Map;reprocessing=new Map;configCounter=0;messageCounter=0;alarmCounter=0;reprocessCounter=0;configureDLQ(n){let i=`dlq-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.dlqConfigs.set(i,s),s}configureSQSDLQ(n){return this.configureDLQ({functionName:n.functionName,targetArn:n.queueArn,targetType:"sqs",maxReceiveCount:n.maxReceiveCount||3,retentionPeriod:n.retentionPeriod||1209600})}configureSNSDLQ(n){return this.configureDLQ({functionName:n.functionName,targetArn:n.topicArn,targetType:"sns"})}configureDLQWithAlarm(n){let i=this.configureSQSDLQ({functionName:n.functionName,queueArn:n.queueArn});return this.createDLQAlarm({dlqConfigId:i.id,alarmName:`${n.functionName}-dlq-alarm`,threshold:n.alarmThreshold,evaluationPeriods:1,notificationTopicArn:n.notificationTopicArn,enabled:!0}),i}sendToDLQ(n){let i=`message-${Date.now()}-${this.messageCounter++}`,s={id:i,timestamp:new Date,...n};return this.messages.set(i,s),s}createDLQAlarm(n){let i=`alarm-${Date.now()}-${this.alarmCounter++}`,s={id:i,...n};return this.alarms.set(i,s),s}createAgeAlarm(n){let i=this.dlqConfigs.get(n.dlqConfigId);if(!i)throw Error(`DLQ config not found: ${n.dlqConfigId}`);return this.createDLQAlarm({dlqConfigId:n.dlqConfigId,alarmName:`${i.functionName}-dlq-age-alarm`,threshold:n.maxAgeSeconds,evaluationPeriods:1,notificationTopicArn:n.notificationTopicArn,enabled:!0})}async reprocessMessage(n){let i=this.messages.get(n);if(!i)throw Error(`Message not found: ${n}`);let s=Array.from(this.dlqConfigs.values()).find((u)=>u.functionName===i.functionName);if(!s)throw Error(`DLQ config not found for function: ${i.functionName}`);let o=`reprocess-${Date.now()}-${this.reprocessCounter++}`,c={id:o,dlqConfigId:s.id,messageId:n,status:"pending",startedAt:new Date};return this.reprocessing.set(o,c),setTimeout(()=>{c.status="processing",setTimeout(()=>{let u=Math.random()>0.3;if(c.status=u?"success":"failed",c.completedAt=new Date,!u)c.error="Reprocessing failed - same error occurred";else this.messages.delete(n)},100)},50),c}async batchReprocess(n){let i=this.dlqConfigs.get(n.dlqConfigId);if(!i)throw Error(`DLQ config not found: ${n.dlqConfigId}`);let o=Array.from(this.messages.values()).filter((c)=>c.functionName===i.functionName).slice(0,n.maxMessages||10).map((c)=>this.reprocessMessage(c.id));return Promise.all(o)}getDLQStats(n){let i=this.dlqConfigs.get(n);if(!i)throw Error(`DLQ config not found: ${n}`);let s=Array.from(this.messages.values()).filter((d)=>d.functionName===i.functionName),o={},c=0;for(let d of s)o[d.errorType]=(o[d.errorType]||0)+1,c+=d.attemptCount;let u=s.map((d)=>d.timestamp);return{totalMessages:s.length,oldestMessage:u.length>0?new Date(Math.min(...u.map((d)=>d.getTime()))):void 0,newestMessage:u.length>0?new Date(Math.max(...u.map((d)=>d.getTime()))):void 0,averageAttempts:s.length>0?c/s.length:0,errorTypes:o}}getDLQConfig(n){return this.dlqConfigs.get(n)}listDLQConfigs(){return Array.from(this.dlqConfigs.values())}getDLQMessages(n){let i=this.dlqConfigs.get(n);if(!i)return[];return Array.from(this.messages.values()).filter((s)=>s.functionName===i.functionName)}generateDLQCF(n){return{DeadLetterConfig:{TargetArn:n.targetArn}}}generateSQSDLQCF(n){return{Type:"AWS::SQS::Queue",Properties:{QueueName:`${n.functionName}-dlq`,MessageRetentionPeriod:n.retentionPeriod||1209600,...n.maxReceiveCount&&{RedrivePolicy:{deadLetterTargetArn:n.targetArn,maxReceiveCount:n.maxReceiveCount}}}}}generateDLQAlarmCF(n){let i=this.dlqConfigs.get(n.dlqConfigId);if(!i)throw Error(`DLQ config not found: ${n.dlqConfigId}`);return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:n.alarmName,AlarmDescription:`DLQ alarm for ${i.functionName}`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Sum",Period:300,EvaluationPeriods:n.evaluationPeriods,Threshold:n.threshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:i.targetArn.split(":").pop()}],...n.notificationTopicArn&&{AlarmActions:[n.notificationTopicArn]}}}}clear(){this.dlqConfigs.clear(),this.messages.clear(),this.alarms.clear(),this.reprocessing.clear(),this.configCounter=0,this.messageCounter=0,this.alarmCounter=0,this.reprocessCounter=0}}var hE=new mf;class Ll{policies=new Map;healthChecks=new Map;trafficPolicies=new Map;policyCounter=0;healthCheckCounter=0;trafficPolicyCounter=0;createWeightedPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"weighted",...n};return this.policies.set(i,s),s}createLatencyPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"latency",...n};return this.policies.set(i,s),s}createFailoverPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"failover",...n};return this.policies.set(i,s),s}createGeolocationPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"geolocation",...n};return this.policies.set(i,s),s}createGeoproximityPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"geoproximity",...n};return this.policies.set(i,s),s}createHTTPHealthCheck(n){let i=`health-check-${Date.now()}-${this.healthCheckCounter++}`,s={id:i,type:n.port===443?"https":"http",requestInterval:n.requestInterval||30,failureThreshold:n.failureThreshold||3,healthCheckStatus:"Unknown",port:n.port||(n.port===443?443:80),...n};return this.healthChecks.set(i,s),setTimeout(()=>{s.healthCheckStatus=Math.random()>0.2?"Healthy":"Unhealthy"},100),s}createTCPHealthCheck(n){let i=`health-check-${Date.now()}-${this.healthCheckCounter++}`,s={id:i,type:"tcp",fullyQualifiedDomainName:n.ipAddress,requestInterval:n.requestInterval||30,failureThreshold:n.failureThreshold||3,healthCheckStatus:"Unknown",...n};return this.healthChecks.set(i,s),setTimeout(()=>{s.healthCheckStatus=Math.random()>0.1?"Healthy":"Unhealthy"},100),s}createCalculatedHealthCheck(n){let i=`health-check-${Date.now()}-${this.healthCheckCounter++}`,s={id:i,type:"calculated",requestInterval:30,failureThreshold:0,healthCheckStatus:"Unknown",...n};return this.healthChecks.set(i,s),setTimeout(()=>{let c=n.childHealthChecks.filter((u)=>this.healthChecks.get(u)?.healthCheckStatus==="Healthy").length;s.healthCheckStatus=c>=n.healthThreshold?"Healthy":"Unhealthy"},150),s}createTrafficPolicy(n){let i=`traffic-policy-${Date.now()}-${this.trafficPolicyCounter++}`,s={id:i,version:1,...n};return this.trafficPolicies.set(i,s),s}createFailoverTrafficPolicy(n){return this.createTrafficPolicy({name:n.name,document:{recordType:n.recordType||"A",startRule:"failover",endpoints:{primary:{type:"value",value:n.primaryEndpoint},secondary:{type:"value",value:n.secondaryEndpoint}},rules:{failover:{ruleType:"failover",primary:"primary",secondary:"secondary"}}}})}createGeoproximityTrafficPolicy(n){let i={},s=[];return n.locations.forEach((o,c)=>{let u=`endpoint${c}`;i[u]={type:"value",value:o.endpoint},s.push({endpointReference:u,region:o.region,latitude:o.latitude,longitude:o.longitude,bias:o.bias})}),this.createTrafficPolicy({name:n.name,document:{recordType:"A",startRule:"geoproximity",endpoints:i,rules:{geoproximity:{ruleType:"geoproximity",locations:s}}}})}getPolicy(n){return this.policies.get(n)}listPolicies(){return Array.from(this.policies.values())}getHealthCheck(n){return this.healthChecks.get(n)}listHealthChecks(){return Array.from(this.healthChecks.values())}getHealthCheckStatus(n){return this.healthChecks.get(n)?.healthCheckStatus||"Unknown"}generateHealthCheckCF(n){let i={Type:"AWS::Route53::HealthCheck",Properties:{HealthCheckConfig:{Type:n.type.toUpperCase(),RequestInterval:n.requestInterval,FailureThreshold:n.failureThreshold,...n.measureLatency&&{MeasureLatency:!0}},HealthCheckTags:[{Key:"Name",Value:n.name}]}};if(n.type==="calculated"){let s=n;i.Properties.HealthCheckConfig.ChildHealthChecks=s.childHealthChecks,i.Properties.HealthCheckConfig.HealthThreshold=s.healthThreshold}else{if(n.ipAddress)i.Properties.HealthCheckConfig.IPAddress=n.ipAddress;if(n.fullyQualifiedDomainName)i.Properties.HealthCheckConfig.FullyQualifiedDomainName=n.fullyQualifiedDomainName;if(n.port)i.Properties.HealthCheckConfig.Port=n.port;if(n.resourcePath)i.Properties.HealthCheckConfig.ResourcePath=n.resourcePath;if(n.enableSNI)i.Properties.HealthCheckConfig.EnableSNI=!0}return i}generateWeightedRecordSetCF(n){return{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.hostedZoneId,Name:n.name,Type:n.type,TTL:n.ttl,ResourceRecords:n.resourceRecords,Weight:n.weight,SetIdentifier:n.setIdentifier,...n.healthCheckId&&{HealthCheckId:n.healthCheckId}}}}generateFailoverRecordSetCF(n){return{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.hostedZoneId,Name:n.name,Type:n.type,TTL:n.ttl,ResourceRecords:n.resourceRecords,Failover:n.failover,SetIdentifier:n.setIdentifier,...n.healthCheckId&&{HealthCheckId:n.healthCheckId}}}}clear(){this.policies.clear(),this.healthChecks.clear(),this.trafficPolicies.clear(),this.policyCounter=0,this.healthCheckCounter=0,this.trafficPolicyCounter=0}}var cS=new Ll;class ff{configs=new Map;ksks=new Map;validations=new Map;configCounter=0;kskCounter=0;validationCounter=0;enableDNSSEC(n){let i=`dnssec-${Date.now()}-${this.configCounter++}`,s={id:i,hostedZoneId:n.hostedZoneId,status:"SIGNING",signingStatus:"Initializing DNSSEC signing"};if(this.configs.set(i,s),n.kmsKeyArn)this.createKSK({name:`ksk-${n.hostedZoneId}`,hostedZoneId:n.hostedZoneId,kmsKeyArn:n.kmsKeyArn});return setTimeout(()=>{s.status="SIGNED",s.signingStatus="DNSSEC signing complete"},100),s}disableDNSSEC(n){let i=this.configs.get(n);if(!i)throw Error(`DNSSEC config not found: ${n}`);return i.status="DELETING",i.signingStatus="Removing DNSSEC signing",setTimeout(()=>{i.status="NOT_SIGNING",i.signingStatus="DNSSEC signing removed"},100),i}createKSK(n){let i=`ksk-${Date.now()}-${this.kskCounter++}`,s={id:i,status:"ACTIVE",flag:257,keyManagementServiceArn:n.kmsKeyArn,digestAlgorithm:2,keyTag:Math.floor(Math.random()*65535),publicKey:this.generatePublicKey(),...n};s.dnskeyRecord=`${s.flag} 3 8 ${s.publicKey}`;let o=this.generateDigest(s.dnskeyRecord);return s.digestValue=o,s.dsRecord=`${s.keyTag} 8 ${s.digestAlgorithm} ${o}`,this.ksks.set(i,s),s}deactivateKSK(n){let i=this.ksks.get(n);if(!i)throw Error(`KSK not found: ${n}`);return i.status="INACTIVE",i}validateDNSSEC(n){let i=`validation-${Date.now()}-${this.validationCounter++}`,s=n.checkDNSKEY!==!1?Math.random()>0.1:!1,o=n.checkRRSIG!==!1?Math.random()>0.1:!1,c=s&&o,u=[];if(!s)u.push("DNSKEY record not found");if(!o)u.push("RRSIG record not found");let d;if(!s&&!o)d="INSECURE";else if(s&&o&&c)d="VALID";else if(s||o)d="BOGUS",u.push("Invalid signature or incomplete DNSSEC chain");else d="INVALID";let p={id:i,domain:n.domain,validationStatus:d,dnskeyPresent:s,rrsigPresent:o,validSignature:c,errors:u};return this.validations.set(i,p),p}getDNSSECConfig(n){return this.configs.get(n)}listDNSSECConfigs(){return Array.from(this.configs.values())}getKSK(n){return this.ksks.get(n)}listKSKs(n){let i=Array.from(this.ksks.values());return n?i.filter((s)=>s.hostedZoneId===n):i}getDSRecord(n){let i=this.ksks.get(n);if(!i||!i.dsRecord)throw Error("DS record not available");return i.dsRecord}generatePublicKey(){let i="";for(let s=0;s<256;s++)i+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(Math.floor(Math.random()*64));return i}generateDigest(n){let s="";for(let o=0;o<64;o++)s+="0123456789ABCDEF".charAt(Math.floor(Math.random()*16));return s}generateDNSSECCF(n){return{Type:"AWS::Route53::DNSSEC",Properties:{HostedZoneId:n.hostedZoneId}}}generateKSKCF(n){return{Type:"AWS::Route53::KeySigningKey",Properties:{Name:n.name,HostedZoneId:n.hostedZoneId,KeyManagementServiceArn:n.keyManagementServiceArn,Status:n.status}}}clear(){this.configs.clear(),this.ksks.clear(),this.validations.clear(),this.configCounter=0,this.kskCounter=0,this.validationCounter=0}}var AE=new ff;class hf{endpoints=new Map;rules=new Map;firewalls=new Map;ruleGroups=new Map;domainLists=new Map;endpointCounter=0;ruleCounter=0;firewallCounter=0;ruleGroupCounter=0;domainListCounter=0;createResolverEndpoint(n){let i=`endpoint-${Date.now()}-${this.endpointCounter++}`,s={id:i,status:"CREATING",...n};return this.endpoints.set(i,s),setTimeout(()=>{s.status="OPERATIONAL",s.ipAddresses.forEach((o)=>{if(!o.ip)o.ip=`10.0.${Math.floor(Math.random()*255)}.${Math.floor(Math.random()*255)}`})},100),s}createInboundEndpoint(n){return this.createResolverEndpoint({name:n.name,direction:"INBOUND",ipAddresses:n.subnetIds.map((i)=>({subnetId:i})),securityGroupIds:n.securityGroupIds})}createOutboundEndpoint(n){return this.createResolverEndpoint({name:n.name,direction:"OUTBOUND",ipAddresses:n.subnetIds.map((i)=>({subnetId:i})),securityGroupIds:n.securityGroupIds})}createResolverRule(n){let i=`rule-${Date.now()}-${this.ruleCounter++}`,s={id:i,status:"CREATING",...n};return this.rules.set(i,s),setTimeout(()=>{s.status="COMPLETE"},100),s}createForwardRule(n){return this.createResolverRule({name:n.name,ruleType:"FORWARD",domainName:n.domainName,targetIps:n.targetIps,resolverEndpointId:n.resolverEndpointId})}createSystemRule(n){return this.createResolverRule({name:n.name,ruleType:"SYSTEM",domainName:n.domainName})}createFirewallDomainList(n){let i=`domain-list-${Date.now()}-${this.domainListCounter++}`,s={id:i,status:"CREATING",...n};return this.domainLists.set(i,s),setTimeout(()=>{s.status="COMPLETE"},100),s}createFirewallRuleGroup(n){let i=`rule-group-${Date.now()}-${this.ruleGroupCounter++}`,s={id:i,name:n.name,rules:n.rules.map((o,c)=>({id:`rule-${i}-${c}`,...o})),shareStatus:"NOT_SHARED"};return this.ruleGroups.set(i,s),s}createBlockRule(n){return this.createFirewallRuleGroup({name:n.name,rules:[{name:n.name,priority:n.priority,action:"BLOCK",blockResponse:n.blockResponse||"NODATA",blockOverrideDomain:n.blockOverrideDomain,firewallDomainListId:n.domainListId}]})}createAllowRule(n){return this.createFirewallRuleGroup({name:n.name,rules:[{name:n.name,priority:n.priority,action:"ALLOW",firewallDomainListId:n.domainListId}]})}createDNSFirewall(n){let i=`firewall-${Date.now()}-${this.firewallCounter++}`,s={id:i,name:n.name,firewallRuleGroupAssociations:n.ruleGroupAssociations.map((o,c)=>({id:`assoc-${i}-${c}`,vpcId:n.vpcId,firewallRuleGroupId:o.firewallRuleGroupId,priority:o.priority,mutationProtection:o.mutationProtection||"DISABLED",status:"COMPLETE"}))};return this.firewalls.set(i,s),s}createMalwareProtectionFirewall(n){let i=this.createFirewallDomainList({name:`${n.name}-malware-domains`,domains:n.maliciousDomains}),s=this.createBlockRule({name:`${n.name}-block-malware`,priority:100,domainListId:i.id,blockResponse:"NXDOMAIN"});return this.createDNSFirewall({name:n.name,vpcId:n.vpcId,ruleGroupAssociations:[{firewallRuleGroupId:s.id,priority:100,mutationProtection:"ENABLED"}]})}getEndpoint(n){return this.endpoints.get(n)}listEndpoints(n){let i=Array.from(this.endpoints.values());return n?i.filter((s)=>s.direction===n):i}getRule(n){return this.rules.get(n)}listRules(){return Array.from(this.rules.values())}getFirewall(n){return this.firewalls.get(n)}listFirewalls(){return Array.from(this.firewalls.values())}generateResolverEndpointCF(n){return{Type:"AWS::Route53Resolver::ResolverEndpoint",Properties:{Name:n.name,Direction:n.direction,IpAddresses:n.ipAddresses.map((i)=>({SubnetId:i.subnetId,...i.ip&&{Ip:i.ip}})),SecurityGroupIds:n.securityGroupIds}}}generateResolverRuleCF(n){return{Type:"AWS::Route53Resolver::ResolverRule",Properties:{Name:n.name,RuleType:n.ruleType,DomainName:n.domainName,...n.targetIps&&{TargetIps:n.targetIps.map((i)=>({Ip:i.ip,Port:i.port||53}))},...n.resolverEndpointId&&{ResolverEndpointId:n.resolverEndpointId}}}}generateFirewallRuleGroupCF(n){return{Type:"AWS::Route53Resolver::FirewallRuleGroup",Properties:{Name:n.name,FirewallRules:n.rules.map((i)=>({Name:i.name,Priority:i.priority,Action:i.action,FirewallDomainListId:i.firewallDomainListId,...i.blockResponse&&{BlockResponse:i.blockResponse},...i.blockOverrideDomain&&{BlockOverrideDomain:i.blockOverrideDomain},...i.blockOverrideTTL&&{BlockOverrideTtl:i.blockOverrideTTL}}))}}}clear(){this.endpoints.clear(),this.rules.clear(),this.firewalls.clear(),this.ruleGroups.clear(),this.domainLists.clear(),this.endpointCounter=0,this.ruleCounter=0,this.firewallCounter=0,this.ruleGroupCounter=0,this.domainListCounter=0}}var yE=new hf;class Af{bounces=new Map;complaints=new Map;handlers=new Map;suppressionList=new Map;metrics=new Map;bounceCounter=0;complaintCounter=0;handlerCounter=0;suppressionCounter=0;metricsCounter=0;recordBounce(n){let i=`bounce-${Date.now()}-${this.bounceCounter++}`,s={id:i,...n};if(this.bounces.set(i,s),n.bounceType==="Permanent")this.addToSuppressionList({emailAddress:n.recipient,reason:"BOUNCE"});return s}recordComplaint(n){let i=`complaint-${Date.now()}-${this.complaintCounter++}`,s={id:i,...n};this.complaints.set(i,s);for(let o of n.recipients)this.addToSuppressionList({emailAddress:o,reason:"COMPLAINT"});return s}createBounceHandler(n){let i=`handler-${Date.now()}-${this.handlerCounter++}`,s={id:i,...n};return this.handlers.set(i,s),s}createAutomaticBounceHandler(n){return this.createBounceHandler({name:n.name,bounceThreshold:5,complaintThreshold:0.1,suppressionDuration:2592000,autoSuppress:!0,notificationTopicArn:n.notificationTopicArn})}addToSuppressionList(n){let i=`suppression-${Date.now()}-${this.suppressionCounter++}`,s=n.expirationDays?new Date(Date.now()+n.expirationDays*24*60*60*1000):void 0,o={id:i,emailAddress:n.emailAddress,reason:n.reason,suppressedAt:new Date,expiresAt:s,bounceCount:n.reason==="BOUNCE"?1:0,complaintCount:n.reason==="COMPLAINT"?1:0};return this.suppressionList.set(n.emailAddress,o),o}removeFromSuppressionList(n){return this.suppressionList.delete(n)}isSuppressed(n){let i=this.suppressionList.get(n);if(!i)return!1;if(i.expiresAt&&i.expiresAt<new Date)return this.suppressionList.delete(n),!1;return!0}getBounceStatistics(n,i){let s=Array.from(this.bounces.values()).filter((b)=>b.timestamp>=n&&b.timestamp<=i),o=s.length,c=s.filter((b)=>b.bounceType==="Permanent").length,u=s.filter((b)=>b.bounceType==="Transient").length,d=o*10,p=o/d*100,y=new Map;for(let b of s)y.set(b.recipient,(y.get(b.recipient)||0)+1);let h=Array.from(y.entries()).map(([b,v])=>({email:b,count:v})).sort((b,v)=>v.count-b.count).slice(0,10);return{totalBounces:o,permanentBounces:c,transientBounces:u,bounceRate:p,topRecipients:h}}getComplaintStatistics(n,i){let s=Array.from(this.complaints.values()).filter((y)=>y.timestamp>=n&&y.timestamp<=i),o=s.length,c=new Set;for(let y of s)for(let h of y.recipients)c.add(h);let u=c.size,d=o*1000,p=o/d*100;return{totalComplaints:o,uniqueComplainters:u,complaintRate:p}}calculateReputationMetrics(){let n=`metrics-${Date.now()}-${this.metricsCounter++}`,i=new Date,s=new Date(i.getTime()-86400000),o=this.getBounceStatistics(s,i),c=this.getComplaintStatistics(s,i),u;if(o.bounceRate>10||c.complaintRate>0.5)u="Shutdown";else if(o.bounceRate>5||c.complaintRate>0.1)u="Probation";else if(o.bounceRate>2||c.complaintRate>0.05)u="Warning";else u="Good";let d={id:n,timestamp:i,bounceRate:o.bounceRate,complaintRate:c.complaintRate,sendingQuota:50000,maxSendRate:14,sentLast24Hours:o.totalBounces*10,reputationStatus:u};return this.metrics.set(n,d),d}getBounces(n){let i=Array.from(this.bounces.values());return n?i.filter((s)=>s.messageId===n):i}getComplaints(n){let i=Array.from(this.complaints.values());return n?i.filter((s)=>s.messageId===n):i}listSuppressionList(n){let i=Array.from(this.suppressionList.values());return n?i.filter((s)=>s.reason===n):i}generateSNSSubscriptionCF(n){return{Type:"AWS::SNS::Subscription",Properties:{TopicArn:n.topicArn,Endpoint:n.endpoint,Protocol:n.protocol}}}generateEventDestinationCF(n){return{Type:"AWS::SES::ConfigurationSetEventDestination",Properties:{ConfigurationSetName:n.configurationSetName,EventDestination:{Name:n.eventDestinationName,Enabled:!0,MatchingEventTypes:n.eventTypes,...n.snsTopicArn&&{SnsDestination:{TopicARN:n.snsTopicArn}},...n.cloudWatchDestination&&{CloudWatchDestination:n.cloudWatchDestination}}}}}clear(){this.bounces.clear(),this.complaints.clear(),this.handlers.clear(),this.suppressionList.clear(),this.metrics.clear(),this.bounceCounter=0,this.complaintCounter=0,this.handlerCounter=0,this.suppressionCounter=0,this.metricsCounter=0}}var SE=new Af;class yf{events=new Map;campaigns=new Map;reports=new Map;abTests=new Map;eventCounter=0;campaignCounter=0;reportCounter=0;abTestCounter=0;trackEvent(n){let i=`event-${Date.now()}-${this.eventCounter++}`,s={id:i,...n};if(this.events.set(i,s),n.tags?.campaignId)this.updateCampaignStats(n.tags.campaignId,n.eventType);return s}trackOpen(n){return this.trackEvent({...n,eventType:"open",timestamp:new Date})}trackClick(n){return this.trackEvent({...n,eventType:"click",timestamp:new Date})}createCampaign(n){let i=`campaign-${Date.now()}-${this.campaignCounter++}`,s={id:i,sentCount:0,deliveredCount:0,openCount:0,clickCount:0,bounceCount:0,complaintCount:0,createdAt:new Date,...n};return this.campaigns.set(i,s),s}updateCampaignStats(n,i){let s=this.campaigns.get(n);if(!s)return;switch(i){case"send":s.sentCount++;break;case"delivery":s.deliveredCount++;break;case"open":s.openCount++;break;case"click":s.clickCount++;break;case"bounce":s.bounceCount++;break;case"complaint":s.complaintCount++;break}}generateReport(n){let i=`report-${Date.now()}-${this.reportCounter++}`,s=Array.from(this.events.values()).filter((N)=>{let O=N.timestamp>=n.startDate&&N.timestamp<=n.endDate,B=!n.campaignId||N.tags?.campaignId===n.campaignId;return O&&B}),o=s.filter((N)=>N.eventType==="send").length,c=s.filter((N)=>N.eventType==="delivery").length,u=s.filter((N)=>N.eventType==="open").length,d=s.filter((N)=>N.eventType==="click").length,p=s.filter((N)=>N.eventType==="bounce").length,y=s.filter((N)=>N.eventType==="complaint").length,h=o>0?c/o*100:0,b=c>0?u/c*100:0,v=c>0?d/c*100:0,A=u>0?d/u*100:0,T=o>0?p/o*100:0,R=c>0?y/c*100:0,P=new Map;for(let N of s)if(N.eventType==="click"){let O=N;P.set(O.link,(P.get(O.link)||0)+1)}let I=Array.from(P.entries()).map(([N,O])=>({link:N,clicks:O})).sort((N,O)=>O.clicks-N.clicks).slice(0,10),M={desktop:0,mobile:0,tablet:0,unknown:0};for(let N of s)if(N.eventType==="open"||N.eventType==="click"){let O=N.userAgent.toLowerCase();if(O.includes("mobile"))M.mobile++;else if(O.includes("tablet"))M.tablet++;else if(O.includes("mozilla"))M.desktop++;else M.unknown++}let L={id:i,campaignId:n.campaignId,startDate:n.startDate,endDate:n.endDate,totalSent:o,totalDelivered:c,totalOpened:u,totalClicked:d,totalBounced:p,totalComplaints:y,deliveryRate:h,openRate:b,clickRate:v,clickToOpenRate:A,bounceRate:T,complaintRate:R,topLinks:I,deviceBreakdown:M,locationBreakdown:{}};return this.reports.set(i,L),L}createABTest(n){let i=`abtest-${Date.now()}-${this.abTestCounter++}`,s={id:i,name:n.name,variants:n.variants.map((o,c)=>({id:`variant-${i}-${c}`,sentCount:0,openCount:0,clickCount:0,conversionCount:0,...o})),status:"draft"};return this.abTests.set(i,s),s}startABTest(n){let i=this.abTests.get(n);if(!i)throw Error(`A/B test not found: ${n}`);return i.status="running",i.startedAt=new Date,i}completeABTest(n){let i=this.abTests.get(n);if(!i)throw Error(`A/B test not found: ${n}`);let s=i.variants[0],o=0;for(let c of i.variants){let u=c.sentCount>0?c.openCount/c.sentCount:0;if(u>o)o=u,s=c}return i.status="completed",i.completedAt=new Date,i.winner=s.id,i}getCampaign(n){return this.campaigns.get(n)}listCampaigns(){return Array.from(this.campaigns.values())}getEvents(n){let i=Array.from(this.events.values());if(n?.messageId)i=i.filter((s)=>s.messageId===n.messageId);if(n?.eventType)i=i.filter((s)=>s.eventType===n.eventType);if(n?.startDate)i=i.filter((s)=>s.timestamp>=n.startDate);if(n?.endDate)i=i.filter((s)=>s.timestamp<=n.endDate);return i}generateTrackingConfigurationCF(n){return{Type:"AWS::SES::ConfigurationSet",Properties:{Name:n.configurationSetName,...n.openTracking&&{TrackingOptions:{CustomRedirectDomain:"tracking.example.com"}}}}}clear(){this.events.clear(),this.campaigns.clear(),this.reports.clear(),this.abTests.clear(),this.eventCounter=0,this.campaignCounter=0,this.reportCounter=0,this.abTestCounter=0}}var IE=new yf;class Sf{dashboards=new Map;warmupPlans=new Map;domainReputations=new Map;dashboardCounter=0;warmupCounter=0;domainCounter=0;getReputationDashboard(){let n=`dashboard-${Date.now()}-${this.dashboardCounter++}`,i=Math.random()*5,s=Math.random()*0.5,o=Math.floor(Math.random()*10),c=Math.max(0,100-i*10-s*100-o*2),u=[];if(i>2)u.push("Reduce bounce rate by cleaning email list");if(s>0.1)u.push("Review email content and unsubscribe process");if(o>5)u.push("Improve email relevance and targeting");let d={id:n,timestamp:new Date,overallScore:c,bounceRate:i,complaintRate:s,spamReports:o,blacklistStatus:this.checkBlacklists(),dkimStatus:"VERIFIED",spfStatus:"PASS",dmarcStatus:"PASS",sendingLimits:{maxSendRate:14,max24HourSend:50000,sentLast24Hours:12000,remainingQuota:38000,quotaResetTime:new Date(Date.now()+86400000)},recommendations:u};return this.dashboards.set(n,d),d}checkBlacklists(){return["Spamhaus ZEN","Spamcop","SORBS","Barracuda","URIBL"].map((i)=>({listName:i,listed:Math.random()>0.95,delistUrl:`https://www.${i.toLowerCase().replace(/\s/g,"")}.org/delist`}))}createWarmupPlan(n){let i=`warmup-${Date.now()}-${this.warmupCounter++}`,s=[],o=(n.targetDailyLimit-n.initialDailyLimit)/n.durationDays;for(let u=0;u<n.durationDays;u++)s.push(Math.floor(n.initialDailyLimit+o*u));let c={id:i,name:n.name,startDate:new Date,currentDay:1,totalDays:n.durationDays,dailyLimits:s,currentLimit:s[0],status:"active"};return this.warmupPlans.set(i,c),c}createAggressiveWarmupPlan(n){return this.createWarmupPlan({name:n.name,initialDailyLimit:500,targetDailyLimit:50000,durationDays:14})}createConservativeWarmupPlan(n){return this.createWarmupPlan({name:n.name,initialDailyLimit:200,targetDailyLimit:50000,durationDays:30})}advanceWarmupPlan(n){let i=this.warmupPlans.get(n);if(!i)throw Error(`Warmup plan not found: ${n}`);if(i.currentDay<i.totalDays)i.currentDay++,i.currentLimit=i.dailyLimits[i.currentDay-1];if(i.currentDay>=i.totalDays)i.status="completed";return i}trackDomainReputation(n){let i=`domain-${Date.now()}-${this.domainCounter++}`,s=n.delivered/n.totalSent*100,o=n.delivered>0?n.opened/n.delivered*100:0,c=n.delivered>0?n.clicked/n.delivered*100:0,u=n.bounced/n.totalSent*100,d=n.delivered>0?n.complained/n.delivered*100:0,p=o*0.4+c*0.6,y=Math.max(0,100-u*10-d*100+p*0.2),h={id:i,domain:n.domain,reputationScore:y,totalSent:n.totalSent,deliveryRate:s,openRate:o,clickRate:c,bounceRate:u,complaintRate:d,engagementScore:p};return this.domainReputations.set(n.domain,h),h}getDomainReputation(n){return this.domainReputations.get(n)}listDomainReputations(){return Array.from(this.domainReputations.values())}getWarmupPlan(n){return this.warmupPlans.get(n)}listWarmupPlans(){return Array.from(this.warmupPlans.values())}clear(){this.dashboards.clear(),this.warmupPlans.clear(),this.domainReputations.clear(),this.dashboardCounter=0,this.warmupCounter=0,this.domainCounter=0}}var bE=new Sf;class If{templates=new Map;versions=new Map;tests=new Map;templateCounter=0;testCounter=0;createTemplate(n){let i=`template-${Date.now()}-${this.templateCounter++}`,s=this.extractVariables(n.subject+n.htmlPart+n.textPart),o={id:i,variables:s,createdAt:new Date,updatedAt:new Date,version:1,...n};return this.templates.set(i,o),this.addVersion({templateId:i,version:1,subject:n.subject,htmlPart:n.htmlPart,textPart:n.textPart,createdBy:"system"}),o}createWelcomeTemplate(n){return this.createTemplate({name:n.name,subject:"Welcome to {{companyName}}!",htmlPart:`
3741
+ COPY . .`,impact:"Improve build time by 60-80% on subsequent builds"});let p={sizeBefore:i.totalSize,sizeAfter:i.totalSize*0.6,timeBefore:300,timeAfter:120},y={id:s,name:`Optimization for ${i.imageId}`,recommendations:o,estimatedSavings:p};return this.optimizations.set(s,y),y}getBuildConfig(n){return this.configs.get(n)}listBuildConfigs(){return Array.from(this.configs.values())}getMultiStageConfig(n){return this.multiStageConfigs.get(n)}listMultiStageConfigs(){return Array.from(this.multiStageConfigs.values())}getOptimization(n){return this.optimizations.get(n)}listOptimizations(){return Array.from(this.optimizations.values())}clear(){this.configs.clear(),this.multiStageConfigs.clear(),this.optimizations.clear(),this.analyses.clear(),this.configCounter=0,this.multiStageCounter=0,this.optimizationCounter=0,this.analysisCounter=0}}var uE=new df;class Ol{registries=new Map;credentials=new Map;registryCounter=0;credentialsCounter=0;createRegistry(n){let i=`registry-${Date.now()}-${this.registryCounter++}`,s={id:i,...n};return this.registries.set(i,s),s}createECRRepository(n){return this.createRegistry({name:n.name,registryType:"ecr",repositoryUri:`123456789012.dkr.ecr.${n.region||"us-east-1"}.amazonaws.com/${n.name}`,region:n.region||"us-east-1",encryption:{encryptionType:n.encryption||"AES256",kmsKeyId:n.kmsKeyId},scanning:{scanOnPush:n.scanOnPush??!0}})}createManagedRepository(n){let i=this.createECRRepository({name:n.name,region:n.region,scanOnPush:!0,encryption:"KMS"});return i.lifecycle={id:`lifecycle-${Date.now()}`,rules:[{rulePriority:1,description:"Keep only last N images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:n.maxImageCount||10},action:{type:"expire"}},{rulePriority:2,description:"Remove images older than N days",selection:{tagStatus:"untagged",countType:"sinceImagePushed",countNumber:n.maxImageAgeDays||30,countUnit:"days"},action:{type:"expire"}}]},i}enableReplication(n,i){let s=this.registries.get(n);if(!s)throw Error(`Registry not found: ${n}`);return s.replication={enabled:!0,destinations:i},s}createCredentials(n){let i=`creds-${Date.now()}-${this.credentialsCounter++}`,s={id:i,...n};return this.credentials.set(i,s),s}getRegistry(n){return this.registries.get(n)}listRegistries(){return Array.from(this.registries.values())}generateECRRepositoryCF(n){return{Type:"AWS::ECR::Repository",Properties:{RepositoryName:n.name,ImageScanningConfiguration:{ScanOnPush:n.scanning?.scanOnPush??!1},EncryptionConfiguration:{EncryptionType:n.encryption?.encryptionType||"AES256",...n.encryption?.kmsKeyId&&{KmsKey:n.encryption.kmsKeyId}},ImageTagMutability:"MUTABLE",...n.lifecycle&&{LifecyclePolicy:{LifecyclePolicyText:JSON.stringify({rules:n.lifecycle.rules})}}}}}generateReplicationConfigCF(n){return{Type:"AWS::ECR::ReplicationConfiguration",Properties:{ReplicationConfiguration:{Rules:n.destinations.map((i)=>({Destinations:[{Region:i.region,...i.registryId&&{RegistryId:i.registryId}}]}))}}}}clear(){this.registries.clear(),this.credentials.clear(),this.registryCounter=0,this.credentialsCounter=0}}var aS=new Ol;class _l{meshes=new Map;virtualNodes=new Map;virtualRouters=new Map;virtualGateways=new Map;meshCounter=0;nodeCounter=0;routerCounter=0;gatewayCounter=0;createMesh(n){let i=`mesh-${Date.now()}-${this.meshCounter++}`,s={id:i,...n};return this.meshes.set(i,s),s}createAppMesh(n){return this.createMesh({name:n.name,meshType:"app_mesh",services:n.services,virtualNodes:[],virtualRouters:[],virtualGateways:[]})}createVirtualNode(n){let i=`vnode-${Date.now()}-${this.nodeCounter++}`,s={id:i,...n};return this.virtualNodes.set(i,s),s}createHTTPVirtualNode(n){return this.createVirtualNode({name:n.name,serviceName:n.serviceName,listeners:[{port:n.port,protocol:"http",healthCheck:{protocol:"http",path:"/health",interval:30,timeout:10,healthyThreshold:2,unhealthyThreshold:3},timeout:{perRequest:15000,idle:300000}}],serviceDiscovery:{type:"aws_cloud_map",namespace:n.namespace,serviceName:n.serviceName}})}createVirtualRouter(n){let i=`vrouter-${Date.now()}-${this.routerCounter++}`,s={id:i,...n};return this.virtualRouters.set(i,s),s}createCanaryRoute(n){return this.createVirtualRouter({name:n.name,listeners:[{port:n.port,protocol:n.protocol}],routes:[{name:"canary-route",match:{prefix:"/"},action:{weightedTargets:[{virtualNode:n.stableTarget,weight:100-n.canaryWeight},{virtualNode:n.canaryTarget,weight:n.canaryWeight}]},retryPolicy:{maxRetries:3,perRetryTimeout:5000,httpRetryEvents:["server-error","gateway-error"],tcpRetryEvents:["connection-error"]}}]})}createVirtualGateway(n){let i=`vgateway-${Date.now()}-${this.gatewayCounter++}`,s={id:i,...n};return this.virtualGateways.set(i,s),s}createIngressGateway(n){let i={port:n.port,protocol:"http",healthCheck:{protocol:"http",path:"/health",interval:30,timeout:10,healthyThreshold:2,unhealthyThreshold:3}};if(n.enableTLS&&n.certificateArn)i.tls={mode:"STRICT",certificate:{acm:n.certificateArn}};return this.createVirtualGateway({name:n.name,listeners:[i],logging:{accessLog:{file:{path:"/dev/stdout"}}}})}getMesh(n){return this.meshes.get(n)}listMeshes(){return Array.from(this.meshes.values())}getVirtualNode(n){return this.virtualNodes.get(n)}listVirtualNodes(){return Array.from(this.virtualNodes.values())}generateMeshCF(n){return{Type:"AWS::AppMesh::Mesh",Properties:{MeshName:n.name,Spec:{EgressFilter:{Type:"ALLOW_ALL"}}}}}generateVirtualNodeCF(n,i){return{Type:"AWS::AppMesh::VirtualNode",Properties:{MeshName:i,VirtualNodeName:n.name,Spec:{Listeners:n.listeners.map((s)=>({PortMapping:{Port:s.port,Protocol:s.protocol},...s.healthCheck&&{HealthCheck:{Protocol:s.healthCheck.protocol,...s.healthCheck.path&&{Path:s.healthCheck.path},IntervalMillis:s.healthCheck.interval*1000,TimeoutMillis:s.healthCheck.timeout*1000,HealthyThreshold:s.healthCheck.healthyThreshold,UnhealthyThreshold:s.healthCheck.unhealthyThreshold}}})),ServiceDiscovery:{AWSCloudMap:{NamespaceName:n.serviceDiscovery.namespace,ServiceName:n.serviceDiscovery.serviceName}}}}}}generateVirtualRouterCF(n,i){return{Type:"AWS::AppMesh::VirtualRouter",Properties:{MeshName:i,VirtualRouterName:n.name,Spec:{Listeners:n.listeners.map((s)=>({PortMapping:{Port:s.port,Protocol:s.protocol}}))}}}}clear(){this.meshes.clear(),this.virtualNodes.clear(),this.virtualRouters.clear(),this.virtualGateways.clear(),this.meshCounter=0,this.nodeCounter=0,this.routerCounter=0,this.gatewayCounter=0}}var cS=new _l;class lf{layers=new Map;versions=new Map;permissions=new Map;layerCounter=0;versionCounter=0;permissionCounter=0;createLayer(n){let i=`layer-${Date.now()}-${this.layerCounter++}`,s=1,o={id:i,layerArn:`arn:aws:lambda:us-east-1:123456789012:layer:${n.layerName}:1`,version:1,...n};return this.layers.set(i,o),o}createNodeDependenciesLayer(n){return this.createLayer({layerName:n.layerName,description:"Node.js dependencies layer",compatibleRuntimes:[`nodejs${n.nodeVersion}`],content:{type:"s3",s3Bucket:n.s3Bucket,s3Key:n.s3Key},size:5242880})}createUtilitiesLayer(n){return this.createLayer({layerName:n.layerName,description:"Shared utilities and helpers",compatibleRuntimes:n.runtimes,content:{type:"s3",s3Bucket:n.s3Bucket,s3Key:n.s3Key},size:1048576})}publishVersion(n){let i=this.layers.get(n);if(!i)throw Error(`Layer not found: ${n}`);let s=`version-${Date.now()}-${this.versionCounter++}`,o=i.version+1,c={id:s,layerName:i.layerName,version:o,createdAt:new Date,compatibleRuntimes:i.compatibleRuntimes,size:i.size,codeHash:this.generateHash()};return this.versions.set(s,c),i.version=o,i.layerArn=`arn:aws:lambda:us-east-1:123456789012:layer:${i.layerName}:${o}`,c}addPermission(n){let i=`permission-${Date.now()}-${this.permissionCounter++}`,s={id:i,layerName:n.layerName,version:n.version,principal:n.principal,action:"lambda:GetLayerVersion",organizationId:n.organizationId};return this.permissions.set(i,s),s}generateHash(){return Math.random().toString(36).substring(2,15)}getLayer(n){return this.layers.get(n)}listLayers(){return Array.from(this.layers.values())}getLayerVersions(n){return Array.from(this.versions.values()).filter((i)=>i.layerName===n)}generateLayerCF(n){return{Type:"AWS::Lambda::LayerVersion",Properties:{LayerName:n.layerName,Description:n.description,Content:n.content.type==="s3"?{S3Bucket:n.content.s3Bucket,S3Key:n.content.s3Key,...n.content.s3ObjectVersion&&{S3ObjectVersion:n.content.s3ObjectVersion}}:{ZipFile:n.content.zipFile},CompatibleRuntimes:n.compatibleRuntimes,...n.licenseInfo&&{LicenseInfo:n.licenseInfo}}}}generateLayerPermissionCF(n){return{Type:"AWS::Lambda::LayerVersionPermission",Properties:{LayerVersionArn:`arn:aws:lambda:us-east-1:123456789012:layer:${n.layerName}:${n.version}`,Action:n.action,Principal:n.principal,...n.organizationId&&{OrganizationId:n.organizationId}}}}clear(){this.layers.clear(),this.versions.clear(),this.permissions.clear(),this.layerCounter=0,this.versionCounter=0,this.permissionCounter=0}}var gE=new lf;class uf{versions=new Map;aliases=new Map;deployments=new Map;versionCounter=0;aliasCounter=0;deploymentCounter=0;publishVersion(n){let i=`version-${Date.now()}-${this.versionCounter++}`,s=this.getNextVersionNumber(n.functionName),o={id:i,functionName:n.functionName,version:s.toString(),functionArn:`arn:aws:lambda:us-east-1:123456789012:function:${n.functionName}:${s}`,codeHash:this.generateHash(),description:n.description,runtime:n.runtime,memorySize:n.memorySize,timeout:n.timeout,publishedAt:new Date};return this.versions.set(i,o),o}getNextVersionNumber(n){let i=Array.from(this.versions.values()).filter((s)=>s.functionName===n).map((s)=>parseInt(s.version));return i.length>0?Math.max(...i)+1:1}createAlias(n){let i=`alias-${Date.now()}-${this.aliasCounter++}`,s={id:i,aliasArn:`arn:aws:lambda:us-east-1:123456789012:function:${n.functionName}:${n.aliasName}`,revisionId:this.generateHash(),...n};return this.aliases.set(i,s),s}createProductionAlias(n){return this.createAlias({functionName:n.functionName,aliasName:"production",functionVersion:n.version,description:"Production alias"})}createStagingAlias(n){return this.createAlias({functionName:n.functionName,aliasName:"staging",functionVersion:n.version,description:"Staging alias"})}updateAlias(n,i){let s=this.aliases.get(n);if(!s)throw Error(`Alias not found: ${n}`);return s.functionVersion=i,s.revisionId=this.generateHash(),s}configureWeightedRouting(n,i){let s=this.aliases.get(n);if(!s)throw Error(`Alias not found: ${n}`);return s.routingConfig={additionalVersionWeights:i},s}createCanaryDeployment(n){let i=`deployment-${Date.now()}-${this.deploymentCounter++}`,s=Array.from(this.aliases.values()).find((c)=>c.functionName===n.functionName&&c.aliasName===n.aliasName);if(!s)s=this.createAlias({functionName:n.functionName,aliasName:n.aliasName,functionVersion:n.fromVersion});this.configureWeightedRouting(s.id,{[n.toVersion]:n.canaryWeight});let o={id:i,functionName:n.functionName,fromVersion:n.fromVersion,toVersion:n.toVersion,aliasName:n.aliasName,strategy:"canary",status:"in_progress",startedAt:new Date};return this.deployments.set(i,o),o}completeDeployment(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);let s=Array.from(this.aliases.values()).find((o)=>o.functionName===i.functionName&&o.aliasName===i.aliasName);if(s)s.functionVersion=i.toVersion,s.routingConfig=void 0;return i.status="completed",i.completedAt=new Date,i}rollbackDeployment(n){let i=this.deployments.get(n);if(!i)throw Error(`Deployment not found: ${n}`);let s=Array.from(this.aliases.values()).find((o)=>o.functionName===i.functionName&&o.aliasName===i.aliasName);if(s)s.functionVersion=i.fromVersion,s.routingConfig=void 0;return i.status="failed",i.completedAt=new Date,i}generateHash(){return Math.random().toString(36).substring(2,15)}getVersion(n){return this.versions.get(n)}listVersions(n){let i=Array.from(this.versions.values());return n?i.filter((s)=>s.functionName===n):i}getAlias(n){return this.aliases.get(n)}listAliases(n){let i=Array.from(this.aliases.values());return n?i.filter((s)=>s.functionName===n):i}generateVersionCF(n){return{Type:"AWS::Lambda::Version",Properties:{FunctionName:n.functionName,Description:n.description}}}generateAliasCF(n){return{Type:"AWS::Lambda::Alias",Properties:{FunctionName:n.functionName,Name:n.aliasName,FunctionVersion:n.functionVersion,Description:n.description,...n.routingConfig&&{RoutingConfig:{AdditionalVersionWeights:Object.entries(n.routingConfig.additionalVersionWeights||{}).map(([i,s])=>({FunctionVersion:i,FunctionWeight:s}))}}}}}clear(){this.versions.clear(),this.aliases.clear(),this.deployments.clear(),this.versionCounter=0,this.aliasCounter=0,this.deploymentCounter=0}}var pE=new uf;class gf{configs=new Map;provisionedConfigs=new Map;schedules=new Map;autoScalingConfigs=new Map;configCounter=0;provisionedCounter=0;scheduleCounter=0;autoScalingCounter=0;setReservedConcurrency(n){let i=`concurrency-${Date.now()}-${this.configCounter++}`,s={id:i,functionName:n.functionName,reservedConcurrency:n.reservedConcurrency};return this.configs.set(i,s),s}setProvisionedConcurrency(n){let i=`provisioned-${Date.now()}-${this.provisionedCounter++}`,s={id:i,functionName:n.functionName,qualifier:n.qualifier,provisionedConcurrentExecutions:n.provisionedConcurrentExecutions,status:"pending",lastModified:new Date};return this.provisionedConfigs.set(i,s),setTimeout(()=>{s.status="ready",s.allocatedConcurrency=n.provisionedConcurrentExecutions,s.availableConcurrency=n.provisionedConcurrentExecutions},100),s}configureWarmPool(n){return this.setProvisionedConcurrency({functionName:n.functionName,qualifier:n.alias,provisionedConcurrentExecutions:n.minInstances})}createSchedule(n){let i=`schedule-${Date.now()}-${this.scheduleCounter++}`,s={id:i,...n};return this.schedules.set(i,s),s}createBusinessHoursSchedule(n){return this.createSchedule({name:`${n.functionName}-business-hours`,functionName:n.functionName,qualifier:n.qualifier,schedule:[{name:"business-hours",cronExpression:"0 8 * * MON-FRI",targetConcurrency:n.businessHoursConcurrency},{name:"off-hours",cronExpression:"0 18 * * MON-FRI",targetConcurrency:n.offHoursConcurrency},{name:"weekend",cronExpression:"0 0 * * SAT",targetConcurrency:n.offHoursConcurrency}]})}configureAutoScaling(n){let i=`autoscaling-${Date.now()}-${this.autoScalingCounter++}`,s={id:i,...n};return this.autoScalingConfigs.set(i,s),s}configurePredictiveScaling(n){return this.configureAutoScaling({functionName:n.functionName,qualifier:n.qualifier,minCapacity:n.baselineCapacity,maxCapacity:n.peakCapacity,targetUtilization:0.7,scaleInCooldown:300,scaleOutCooldown:60})}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getProvisionedConfig(n){return this.provisionedConfigs.get(n)}listProvisionedConfigs(){return Array.from(this.provisionedConfigs.values())}generateReservedConcurrencyCF(n){return{Type:"AWS::Lambda::Function",Properties:{FunctionName:n.functionName,ReservedConcurrentExecutions:n.reservedConcurrency}}}generateProvisionedConcurrencyCF(n){return{Type:"AWS::Lambda::Alias",Properties:{FunctionName:n.functionName,Name:n.qualifier,ProvisionedConcurrencyConfig:{ProvisionedConcurrentExecutions:n.provisionedConcurrentExecutions}}}}generateAutoScalingTargetCF(n){return{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{ServiceNamespace:"lambda",ResourceId:`function:${n.functionName}:${n.qualifier}`,ScalableDimension:"lambda:function:ProvisionedConcurrentExecutions",MinCapacity:n.minCapacity,MaxCapacity:n.maxCapacity}}}generateAutoScalingPolicyCF(n){return{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${n.functionName}-autoscaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:`${n.functionName}AutoScalingTarget`},TargetTrackingScalingPolicyConfiguration:{TargetValue:n.targetUtilization*100,PredefinedMetricSpecification:{PredefinedMetricType:"LambdaProvisionedConcurrencyUtilization"},ScaleInCooldown:n.scaleInCooldown||300,ScaleOutCooldown:n.scaleOutCooldown||60}}}}clear(){this.configs.clear(),this.provisionedConfigs.clear(),this.schedules.clear(),this.autoScalingConfigs.clear(),this.configCounter=0,this.provisionedCounter=0,this.scheduleCounter=0,this.autoScalingCounter=0}}var mE=new gf;class pf{destinations=new Map;records=new Map;eventBridgeDestinations=new Map;destinationCounter=0;recordCounter=0;eventBridgeCounter=0;configureDestinations(n){let i=`destination-${Date.now()}-${this.destinationCounter++}`,s={id:i,...n};return this.destinations.set(i,s),s}configureSQSDestination(n){let i={type:"sqs",arn:n.queueArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureSNSDestination(n){let i={type:"sns",arn:n.topicArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureEventBridgeDestination(n){let i={type:"eventbridge",arn:n.eventBusArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureLambdaDestination(n){let i={type:"lambda",arn:n.destinationFunctionArn};return this.configureDestinations({functionName:n.functionName,successDestination:n.onSuccess?i:void 0,failureDestination:n.onFailure?i:void 0,maxEventAge:21600,maxRetries:2})}configureDLQWithNotification(n){return this.configureDestinations({functionName:n.functionName,failureDestination:{type:"sqs",arn:n.dlqArn},maxEventAge:3600,maxRetries:0})}createEventBridgeIntegration(n){let i=`eventbridge-${Date.now()}-${this.eventBridgeCounter++}`,s={id:i,functionName:n.functionName,eventBusArn:n.eventBusArn,detailType:n.detailType||"Lambda Function Invocation Result",source:n.source||`lambda.${n.functionName}`};return this.eventBridgeDestinations.set(i,s),s}sendToDestination(n){let i=Array.from(this.destinations.values()).find((u)=>u.functionName===n.functionName);if(!i)return null;let s=n.status==="success"?i.successDestination:i.failureDestination;if(!s)return null;let o=`record-${Date.now()}-${this.recordCounter++}`,c={id:o,timestamp:new Date,functionName:n.functionName,requestId:n.requestId,status:n.status,destinationType:s.type,destinationArn:s.arn,payload:n.payload,error:n.error};return this.records.set(o,c),c}getDestination(n){return this.destinations.get(n)}listDestinations(n){let i=Array.from(this.destinations.values());return n?i.filter((s)=>s.functionName===n):i}getDestinationRecords(n){let i=Array.from(this.records.values());return n?i.filter((s)=>s.functionName===n):i}generateEventInvokeConfigCF(n){return{Type:"AWS::Lambda::EventInvokeConfig",Properties:{FunctionName:n.functionName,Qualifier:n.qualifier||"$LATEST",MaximumEventAgeInSeconds:n.maxEventAge||21600,MaximumRetryAttempts:n.maxRetries??2,...n.successDestination&&{DestinationConfig:{OnSuccess:{Destination:n.successDestination.arn}}},...n.failureDestination&&{DestinationConfig:{OnFailure:{Destination:n.failureDestination.arn}}}}}}generateEventBridgeRuleCF(n){return{Type:"AWS::Events::Rule",Properties:{EventBusName:n.eventBusArn.split("/").pop(),EventPattern:{source:[n.source],"detail-type":[n.detailType]},State:"ENABLED",Targets:[{Arn:`arn:aws:lambda:us-east-1:123456789012:function:${n.functionName}`,Id:n.id}]}}}clear(){this.destinations.clear(),this.records.clear(),this.eventBridgeDestinations.clear(),this.destinationCounter=0,this.recordCounter=0,this.eventBridgeCounter=0}}var fE=new pf;class mf{vpcConfigs=new Map;endpoints=new Map;networkInterfaces=new Map;connectivity=new Map;configCounter=0;endpointCounter=0;eniCounter=0;connectivityCounter=0;configureVPC(n){let i=`vpc-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};this.vpcConfigs.set(i,s);for(let o of n.subnetIds)this.createNetworkInterface({functionName:n.functionName,subnetId:o});return s}configurePrivateVPC(n){return this.configureVPC({functionName:n.functionName,vpcId:n.vpcId,subnetIds:n.privateSubnetIds,securityGroupIds:[n.securityGroupId],ipv6Allowed:!1})}configureMultiAZVPC(n){if(n.subnetIds.length<2)throw Error("Multi-AZ configuration requires at least 2 subnets");return this.configureVPC({functionName:n.functionName,vpcId:n.vpcId,subnetIds:n.subnetIds,securityGroupIds:n.securityGroupIds})}createVPCEndpoint(n){let i=`endpoint-${Date.now()}-${this.endpointCounter++}`,s={id:i,...n};return this.endpoints.set(i,s),s}createS3Endpoint(n){return this.createVPCEndpoint({vpcId:n.vpcId,serviceName:"com.amazonaws.us-east-1.s3",endpointType:"Gateway",privateDnsEnabled:!1})}createDynamoDBEndpoint(n){return this.createVPCEndpoint({vpcId:n.vpcId,serviceName:"com.amazonaws.us-east-1.dynamodb",endpointType:"Gateway",privateDnsEnabled:!1})}createSecretsManagerEndpoint(n){return this.createVPCEndpoint({vpcId:n.vpcId,serviceName:"com.amazonaws.us-east-1.secretsmanager",endpointType:"Interface",subnetIds:n.subnetIds,securityGroupIds:n.securityGroupIds,privateDnsEnabled:!0})}createNetworkInterface(n){let i=`eni-${Date.now()}-${this.eniCounter++}`,s={id:i,functionName:n.functionName,networkInterfaceId:`eni-${Math.random().toString(36).substring(2,15)}`,subnetId:n.subnetId,privateIpAddress:`10.0.${Math.floor(Math.random()*255)}.${Math.floor(Math.random()*255)}`,status:"creating",attachedAt:new Date};return this.networkInterfaces.set(i,s),setTimeout(()=>{s.status="available"},100),s}analyzeConnectivity(n){let i=`connectivity-${Date.now()}-${this.connectivityCounter++}`,s=Array.from(this.vpcConfigs.values()).find((y)=>y.functionName===n.functionName),o=Array.from(this.endpoints.values()).filter((y)=>y.vpcId===s?.vpcId).map((y)=>y.serviceName),c=[],u=n.hasNATGateway??!1,d=n.hasInternetGateway??!1;if(!u&&!d)c.push("Add NAT Gateway for internet access");if(!o.includes("com.amazonaws.us-east-1.s3"))c.push("Add S3 VPC endpoint to reduce NAT costs");if(!o.includes("com.amazonaws.us-east-1.dynamodb"))c.push("Add DynamoDB VPC endpoint for private access");let p={id:i,functionName:n.functionName,hasInternetAccess:u||d,hasNATGateway:u,hasVPCEndpoints:o.length>0,endpoints:o,recommendations:c};return this.connectivity.set(i,p),p}getVPCConfig(n){return this.vpcConfigs.get(n)}listVPCConfigs(n){let i=Array.from(this.vpcConfigs.values());return n?i.filter((s)=>s.functionName===n):i}getNetworkInterfaces(n){return Array.from(this.networkInterfaces.values()).filter((i)=>i.functionName===n)}listVPCEndpoints(n){let i=Array.from(this.endpoints.values());return n?i.filter((s)=>s.vpcId===n):i}generateVPCConfigCF(n){return{VpcConfig:{SubnetIds:n.subnetIds,SecurityGroupIds:n.securityGroupIds,...n.ipv6Allowed&&{Ipv6AllowedForDualStack:!0}}}}generateVPCEndpointCF(n){return{Type:"AWS::EC2::VPCEndpoint",Properties:{VpcId:n.vpcId,ServiceName:n.serviceName,VpcEndpointType:n.endpointType,...n.subnetIds&&{SubnetIds:n.subnetIds},...n.securityGroupIds&&{SecurityGroupIds:n.securityGroupIds},...n.privateDnsEnabled!==void 0&&{PrivateDnsEnabled:n.privateDnsEnabled}}}}generateSecurityGroupCF(n){return{Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:n.groupName,GroupDescription:`Security group for Lambda ${n.groupName}`,VpcId:n.vpcId,...n.ingressRules&&{SecurityGroupIngress:n.ingressRules.map((i)=>({IpProtocol:i.protocol,FromPort:i.fromPort,ToPort:i.toPort,...i.cidrIp&&{CidrIp:i.cidrIp},...i.sourceSecurityGroupId&&{SourceSecurityGroupId:i.sourceSecurityGroupId}}))},...n.egressRules&&{SecurityGroupEgress:n.egressRules.map((i)=>({IpProtocol:i.protocol,FromPort:i.fromPort,ToPort:i.toPort,CidrIp:i.cidrIp||"0.0.0.0/0"}))}}}}clear(){this.vpcConfigs.clear(),this.endpoints.clear(),this.networkInterfaces.clear(),this.connectivity.clear(),this.configCounter=0,this.endpointCounter=0,this.eniCounter=0,this.connectivityCounter=0}}var hE=new mf;class ff{dlqConfigs=new Map;messages=new Map;alarms=new Map;reprocessing=new Map;configCounter=0;messageCounter=0;alarmCounter=0;reprocessCounter=0;configureDLQ(n){let i=`dlq-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.dlqConfigs.set(i,s),s}configureSQSDLQ(n){return this.configureDLQ({functionName:n.functionName,targetArn:n.queueArn,targetType:"sqs",maxReceiveCount:n.maxReceiveCount||3,retentionPeriod:n.retentionPeriod||1209600})}configureSNSDLQ(n){return this.configureDLQ({functionName:n.functionName,targetArn:n.topicArn,targetType:"sns"})}configureDLQWithAlarm(n){let i=this.configureSQSDLQ({functionName:n.functionName,queueArn:n.queueArn});return this.createDLQAlarm({dlqConfigId:i.id,alarmName:`${n.functionName}-dlq-alarm`,threshold:n.alarmThreshold,evaluationPeriods:1,notificationTopicArn:n.notificationTopicArn,enabled:!0}),i}sendToDLQ(n){let i=`message-${Date.now()}-${this.messageCounter++}`,s={id:i,timestamp:new Date,...n};return this.messages.set(i,s),s}createDLQAlarm(n){let i=`alarm-${Date.now()}-${this.alarmCounter++}`,s={id:i,...n};return this.alarms.set(i,s),s}createAgeAlarm(n){let i=this.dlqConfigs.get(n.dlqConfigId);if(!i)throw Error(`DLQ config not found: ${n.dlqConfigId}`);return this.createDLQAlarm({dlqConfigId:n.dlqConfigId,alarmName:`${i.functionName}-dlq-age-alarm`,threshold:n.maxAgeSeconds,evaluationPeriods:1,notificationTopicArn:n.notificationTopicArn,enabled:!0})}async reprocessMessage(n){let i=this.messages.get(n);if(!i)throw Error(`Message not found: ${n}`);let s=Array.from(this.dlqConfigs.values()).find((u)=>u.functionName===i.functionName);if(!s)throw Error(`DLQ config not found for function: ${i.functionName}`);let o=`reprocess-${Date.now()}-${this.reprocessCounter++}`,c={id:o,dlqConfigId:s.id,messageId:n,status:"pending",startedAt:new Date};return this.reprocessing.set(o,c),setTimeout(()=>{c.status="processing",setTimeout(()=>{let u=Math.random()>0.3;if(c.status=u?"success":"failed",c.completedAt=new Date,!u)c.error="Reprocessing failed - same error occurred";else this.messages.delete(n)},100)},50),c}async batchReprocess(n){let i=this.dlqConfigs.get(n.dlqConfigId);if(!i)throw Error(`DLQ config not found: ${n.dlqConfigId}`);let o=Array.from(this.messages.values()).filter((c)=>c.functionName===i.functionName).slice(0,n.maxMessages||10).map((c)=>this.reprocessMessage(c.id));return Promise.all(o)}getDLQStats(n){let i=this.dlqConfigs.get(n);if(!i)throw Error(`DLQ config not found: ${n}`);let s=Array.from(this.messages.values()).filter((d)=>d.functionName===i.functionName),o={},c=0;for(let d of s)o[d.errorType]=(o[d.errorType]||0)+1,c+=d.attemptCount;let u=s.map((d)=>d.timestamp);return{totalMessages:s.length,oldestMessage:u.length>0?new Date(Math.min(...u.map((d)=>d.getTime()))):void 0,newestMessage:u.length>0?new Date(Math.max(...u.map((d)=>d.getTime()))):void 0,averageAttempts:s.length>0?c/s.length:0,errorTypes:o}}getDLQConfig(n){return this.dlqConfigs.get(n)}listDLQConfigs(){return Array.from(this.dlqConfigs.values())}getDLQMessages(n){let i=this.dlqConfigs.get(n);if(!i)return[];return Array.from(this.messages.values()).filter((s)=>s.functionName===i.functionName)}generateDLQCF(n){return{DeadLetterConfig:{TargetArn:n.targetArn}}}generateSQSDLQCF(n){return{Type:"AWS::SQS::Queue",Properties:{QueueName:`${n.functionName}-dlq`,MessageRetentionPeriod:n.retentionPeriod||1209600,...n.maxReceiveCount&&{RedrivePolicy:{deadLetterTargetArn:n.targetArn,maxReceiveCount:n.maxReceiveCount}}}}}generateDLQAlarmCF(n){let i=this.dlqConfigs.get(n.dlqConfigId);if(!i)throw Error(`DLQ config not found: ${n.dlqConfigId}`);return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:n.alarmName,AlarmDescription:`DLQ alarm for ${i.functionName}`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Sum",Period:300,EvaluationPeriods:n.evaluationPeriods,Threshold:n.threshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:i.targetArn.split(":").pop()}],...n.notificationTopicArn&&{AlarmActions:[n.notificationTopicArn]}}}}clear(){this.dlqConfigs.clear(),this.messages.clear(),this.alarms.clear(),this.reprocessing.clear(),this.configCounter=0,this.messageCounter=0,this.alarmCounter=0,this.reprocessCounter=0}}var AE=new ff;class Ll{policies=new Map;healthChecks=new Map;trafficPolicies=new Map;policyCounter=0;healthCheckCounter=0;trafficPolicyCounter=0;createWeightedPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"weighted",...n};return this.policies.set(i,s),s}createLatencyPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"latency",...n};return this.policies.set(i,s),s}createFailoverPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"failover",...n};return this.policies.set(i,s),s}createGeolocationPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"geolocation",...n};return this.policies.set(i,s),s}createGeoproximityPolicy(n){let i=`policy-${Date.now()}-${this.policyCounter++}`,s={id:i,type:"geoproximity",...n};return this.policies.set(i,s),s}createHTTPHealthCheck(n){let i=`health-check-${Date.now()}-${this.healthCheckCounter++}`,s={id:i,type:n.port===443?"https":"http",requestInterval:n.requestInterval||30,failureThreshold:n.failureThreshold||3,healthCheckStatus:"Unknown",port:n.port||(n.port===443?443:80),...n};return this.healthChecks.set(i,s),setTimeout(()=>{s.healthCheckStatus=Math.random()>0.2?"Healthy":"Unhealthy"},100),s}createTCPHealthCheck(n){let i=`health-check-${Date.now()}-${this.healthCheckCounter++}`,s={id:i,type:"tcp",fullyQualifiedDomainName:n.ipAddress,requestInterval:n.requestInterval||30,failureThreshold:n.failureThreshold||3,healthCheckStatus:"Unknown",...n};return this.healthChecks.set(i,s),setTimeout(()=>{s.healthCheckStatus=Math.random()>0.1?"Healthy":"Unhealthy"},100),s}createCalculatedHealthCheck(n){let i=`health-check-${Date.now()}-${this.healthCheckCounter++}`,s={id:i,type:"calculated",requestInterval:30,failureThreshold:0,healthCheckStatus:"Unknown",...n};return this.healthChecks.set(i,s),setTimeout(()=>{let c=n.childHealthChecks.filter((u)=>this.healthChecks.get(u)?.healthCheckStatus==="Healthy").length;s.healthCheckStatus=c>=n.healthThreshold?"Healthy":"Unhealthy"},150),s}createTrafficPolicy(n){let i=`traffic-policy-${Date.now()}-${this.trafficPolicyCounter++}`,s={id:i,version:1,...n};return this.trafficPolicies.set(i,s),s}createFailoverTrafficPolicy(n){return this.createTrafficPolicy({name:n.name,document:{recordType:n.recordType||"A",startRule:"failover",endpoints:{primary:{type:"value",value:n.primaryEndpoint},secondary:{type:"value",value:n.secondaryEndpoint}},rules:{failover:{ruleType:"failover",primary:"primary",secondary:"secondary"}}}})}createGeoproximityTrafficPolicy(n){let i={},s=[];return n.locations.forEach((o,c)=>{let u=`endpoint${c}`;i[u]={type:"value",value:o.endpoint},s.push({endpointReference:u,region:o.region,latitude:o.latitude,longitude:o.longitude,bias:o.bias})}),this.createTrafficPolicy({name:n.name,document:{recordType:"A",startRule:"geoproximity",endpoints:i,rules:{geoproximity:{ruleType:"geoproximity",locations:s}}}})}getPolicy(n){return this.policies.get(n)}listPolicies(){return Array.from(this.policies.values())}getHealthCheck(n){return this.healthChecks.get(n)}listHealthChecks(){return Array.from(this.healthChecks.values())}getHealthCheckStatus(n){return this.healthChecks.get(n)?.healthCheckStatus||"Unknown"}generateHealthCheckCF(n){let i={Type:"AWS::Route53::HealthCheck",Properties:{HealthCheckConfig:{Type:n.type.toUpperCase(),RequestInterval:n.requestInterval,FailureThreshold:n.failureThreshold,...n.measureLatency&&{MeasureLatency:!0}},HealthCheckTags:[{Key:"Name",Value:n.name}]}};if(n.type==="calculated"){let s=n;i.Properties.HealthCheckConfig.ChildHealthChecks=s.childHealthChecks,i.Properties.HealthCheckConfig.HealthThreshold=s.healthThreshold}else{if(n.ipAddress)i.Properties.HealthCheckConfig.IPAddress=n.ipAddress;if(n.fullyQualifiedDomainName)i.Properties.HealthCheckConfig.FullyQualifiedDomainName=n.fullyQualifiedDomainName;if(n.port)i.Properties.HealthCheckConfig.Port=n.port;if(n.resourcePath)i.Properties.HealthCheckConfig.ResourcePath=n.resourcePath;if(n.enableSNI)i.Properties.HealthCheckConfig.EnableSNI=!0}return i}generateWeightedRecordSetCF(n){return{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.hostedZoneId,Name:n.name,Type:n.type,TTL:n.ttl,ResourceRecords:n.resourceRecords,Weight:n.weight,SetIdentifier:n.setIdentifier,...n.healthCheckId&&{HealthCheckId:n.healthCheckId}}}}generateFailoverRecordSetCF(n){return{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n.hostedZoneId,Name:n.name,Type:n.type,TTL:n.ttl,ResourceRecords:n.resourceRecords,Failover:n.failover,SetIdentifier:n.setIdentifier,...n.healthCheckId&&{HealthCheckId:n.healthCheckId}}}}clear(){this.policies.clear(),this.healthChecks.clear(),this.trafficPolicies.clear(),this.policyCounter=0,this.healthCheckCounter=0,this.trafficPolicyCounter=0}}var dS=new Ll;class hf{configs=new Map;ksks=new Map;validations=new Map;configCounter=0;kskCounter=0;validationCounter=0;enableDNSSEC(n){let i=`dnssec-${Date.now()}-${this.configCounter++}`,s={id:i,hostedZoneId:n.hostedZoneId,status:"SIGNING",signingStatus:"Initializing DNSSEC signing"};if(this.configs.set(i,s),n.kmsKeyArn)this.createKSK({name:`ksk-${n.hostedZoneId}`,hostedZoneId:n.hostedZoneId,kmsKeyArn:n.kmsKeyArn});return setTimeout(()=>{s.status="SIGNED",s.signingStatus="DNSSEC signing complete"},100),s}disableDNSSEC(n){let i=this.configs.get(n);if(!i)throw Error(`DNSSEC config not found: ${n}`);return i.status="DELETING",i.signingStatus="Removing DNSSEC signing",setTimeout(()=>{i.status="NOT_SIGNING",i.signingStatus="DNSSEC signing removed"},100),i}createKSK(n){let i=`ksk-${Date.now()}-${this.kskCounter++}`,s={id:i,status:"ACTIVE",flag:257,keyManagementServiceArn:n.kmsKeyArn,digestAlgorithm:2,keyTag:Math.floor(Math.random()*65535),publicKey:this.generatePublicKey(),...n};s.dnskeyRecord=`${s.flag} 3 8 ${s.publicKey}`;let o=this.generateDigest(s.dnskeyRecord);return s.digestValue=o,s.dsRecord=`${s.keyTag} 8 ${s.digestAlgorithm} ${o}`,this.ksks.set(i,s),s}deactivateKSK(n){let i=this.ksks.get(n);if(!i)throw Error(`KSK not found: ${n}`);return i.status="INACTIVE",i}validateDNSSEC(n){let i=`validation-${Date.now()}-${this.validationCounter++}`,s=n.checkDNSKEY!==!1?Math.random()>0.1:!1,o=n.checkRRSIG!==!1?Math.random()>0.1:!1,c=s&&o,u=[];if(!s)u.push("DNSKEY record not found");if(!o)u.push("RRSIG record not found");let d;if(!s&&!o)d="INSECURE";else if(s&&o&&c)d="VALID";else if(s||o)d="BOGUS",u.push("Invalid signature or incomplete DNSSEC chain");else d="INVALID";let p={id:i,domain:n.domain,validationStatus:d,dnskeyPresent:s,rrsigPresent:o,validSignature:c,errors:u};return this.validations.set(i,p),p}getDNSSECConfig(n){return this.configs.get(n)}listDNSSECConfigs(){return Array.from(this.configs.values())}getKSK(n){return this.ksks.get(n)}listKSKs(n){let i=Array.from(this.ksks.values());return n?i.filter((s)=>s.hostedZoneId===n):i}getDSRecord(n){let i=this.ksks.get(n);if(!i||!i.dsRecord)throw Error("DS record not available");return i.dsRecord}generatePublicKey(){let i="";for(let s=0;s<256;s++)i+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(Math.floor(Math.random()*64));return i}generateDigest(n){let s="";for(let o=0;o<64;o++)s+="0123456789ABCDEF".charAt(Math.floor(Math.random()*16));return s}generateDNSSECCF(n){return{Type:"AWS::Route53::DNSSEC",Properties:{HostedZoneId:n.hostedZoneId}}}generateKSKCF(n){return{Type:"AWS::Route53::KeySigningKey",Properties:{Name:n.name,HostedZoneId:n.hostedZoneId,KeyManagementServiceArn:n.keyManagementServiceArn,Status:n.status}}}clear(){this.configs.clear(),this.ksks.clear(),this.validations.clear(),this.configCounter=0,this.kskCounter=0,this.validationCounter=0}}var yE=new hf;class Af{endpoints=new Map;rules=new Map;firewalls=new Map;ruleGroups=new Map;domainLists=new Map;endpointCounter=0;ruleCounter=0;firewallCounter=0;ruleGroupCounter=0;domainListCounter=0;createResolverEndpoint(n){let i=`endpoint-${Date.now()}-${this.endpointCounter++}`,s={id:i,status:"CREATING",...n};return this.endpoints.set(i,s),setTimeout(()=>{s.status="OPERATIONAL",s.ipAddresses.forEach((o)=>{if(!o.ip)o.ip=`10.0.${Math.floor(Math.random()*255)}.${Math.floor(Math.random()*255)}`})},100),s}createInboundEndpoint(n){return this.createResolverEndpoint({name:n.name,direction:"INBOUND",ipAddresses:n.subnetIds.map((i)=>({subnetId:i})),securityGroupIds:n.securityGroupIds})}createOutboundEndpoint(n){return this.createResolverEndpoint({name:n.name,direction:"OUTBOUND",ipAddresses:n.subnetIds.map((i)=>({subnetId:i})),securityGroupIds:n.securityGroupIds})}createResolverRule(n){let i=`rule-${Date.now()}-${this.ruleCounter++}`,s={id:i,status:"CREATING",...n};return this.rules.set(i,s),setTimeout(()=>{s.status="COMPLETE"},100),s}createForwardRule(n){return this.createResolverRule({name:n.name,ruleType:"FORWARD",domainName:n.domainName,targetIps:n.targetIps,resolverEndpointId:n.resolverEndpointId})}createSystemRule(n){return this.createResolverRule({name:n.name,ruleType:"SYSTEM",domainName:n.domainName})}createFirewallDomainList(n){let i=`domain-list-${Date.now()}-${this.domainListCounter++}`,s={id:i,status:"CREATING",...n};return this.domainLists.set(i,s),setTimeout(()=>{s.status="COMPLETE"},100),s}createFirewallRuleGroup(n){let i=`rule-group-${Date.now()}-${this.ruleGroupCounter++}`,s={id:i,name:n.name,rules:n.rules.map((o,c)=>({id:`rule-${i}-${c}`,...o})),shareStatus:"NOT_SHARED"};return this.ruleGroups.set(i,s),s}createBlockRule(n){return this.createFirewallRuleGroup({name:n.name,rules:[{name:n.name,priority:n.priority,action:"BLOCK",blockResponse:n.blockResponse||"NODATA",blockOverrideDomain:n.blockOverrideDomain,firewallDomainListId:n.domainListId}]})}createAllowRule(n){return this.createFirewallRuleGroup({name:n.name,rules:[{name:n.name,priority:n.priority,action:"ALLOW",firewallDomainListId:n.domainListId}]})}createDNSFirewall(n){let i=`firewall-${Date.now()}-${this.firewallCounter++}`,s={id:i,name:n.name,firewallRuleGroupAssociations:n.ruleGroupAssociations.map((o,c)=>({id:`assoc-${i}-${c}`,vpcId:n.vpcId,firewallRuleGroupId:o.firewallRuleGroupId,priority:o.priority,mutationProtection:o.mutationProtection||"DISABLED",status:"COMPLETE"}))};return this.firewalls.set(i,s),s}createMalwareProtectionFirewall(n){let i=this.createFirewallDomainList({name:`${n.name}-malware-domains`,domains:n.maliciousDomains}),s=this.createBlockRule({name:`${n.name}-block-malware`,priority:100,domainListId:i.id,blockResponse:"NXDOMAIN"});return this.createDNSFirewall({name:n.name,vpcId:n.vpcId,ruleGroupAssociations:[{firewallRuleGroupId:s.id,priority:100,mutationProtection:"ENABLED"}]})}getEndpoint(n){return this.endpoints.get(n)}listEndpoints(n){let i=Array.from(this.endpoints.values());return n?i.filter((s)=>s.direction===n):i}getRule(n){return this.rules.get(n)}listRules(){return Array.from(this.rules.values())}getFirewall(n){return this.firewalls.get(n)}listFirewalls(){return Array.from(this.firewalls.values())}generateResolverEndpointCF(n){return{Type:"AWS::Route53Resolver::ResolverEndpoint",Properties:{Name:n.name,Direction:n.direction,IpAddresses:n.ipAddresses.map((i)=>({SubnetId:i.subnetId,...i.ip&&{Ip:i.ip}})),SecurityGroupIds:n.securityGroupIds}}}generateResolverRuleCF(n){return{Type:"AWS::Route53Resolver::ResolverRule",Properties:{Name:n.name,RuleType:n.ruleType,DomainName:n.domainName,...n.targetIps&&{TargetIps:n.targetIps.map((i)=>({Ip:i.ip,Port:i.port||53}))},...n.resolverEndpointId&&{ResolverEndpointId:n.resolverEndpointId}}}}generateFirewallRuleGroupCF(n){return{Type:"AWS::Route53Resolver::FirewallRuleGroup",Properties:{Name:n.name,FirewallRules:n.rules.map((i)=>({Name:i.name,Priority:i.priority,Action:i.action,FirewallDomainListId:i.firewallDomainListId,...i.blockResponse&&{BlockResponse:i.blockResponse},...i.blockOverrideDomain&&{BlockOverrideDomain:i.blockOverrideDomain},...i.blockOverrideTTL&&{BlockOverrideTtl:i.blockOverrideTTL}}))}}}clear(){this.endpoints.clear(),this.rules.clear(),this.firewalls.clear(),this.ruleGroups.clear(),this.domainLists.clear(),this.endpointCounter=0,this.ruleCounter=0,this.firewallCounter=0,this.ruleGroupCounter=0,this.domainListCounter=0}}var SE=new Af;class yf{bounces=new Map;complaints=new Map;handlers=new Map;suppressionList=new Map;metrics=new Map;bounceCounter=0;complaintCounter=0;handlerCounter=0;suppressionCounter=0;metricsCounter=0;recordBounce(n){let i=`bounce-${Date.now()}-${this.bounceCounter++}`,s={id:i,...n};if(this.bounces.set(i,s),n.bounceType==="Permanent")this.addToSuppressionList({emailAddress:n.recipient,reason:"BOUNCE"});return s}recordComplaint(n){let i=`complaint-${Date.now()}-${this.complaintCounter++}`,s={id:i,...n};this.complaints.set(i,s);for(let o of n.recipients)this.addToSuppressionList({emailAddress:o,reason:"COMPLAINT"});return s}createBounceHandler(n){let i=`handler-${Date.now()}-${this.handlerCounter++}`,s={id:i,...n};return this.handlers.set(i,s),s}createAutomaticBounceHandler(n){return this.createBounceHandler({name:n.name,bounceThreshold:5,complaintThreshold:0.1,suppressionDuration:2592000,autoSuppress:!0,notificationTopicArn:n.notificationTopicArn})}addToSuppressionList(n){let i=`suppression-${Date.now()}-${this.suppressionCounter++}`,s=n.expirationDays?new Date(Date.now()+n.expirationDays*24*60*60*1000):void 0,o={id:i,emailAddress:n.emailAddress,reason:n.reason,suppressedAt:new Date,expiresAt:s,bounceCount:n.reason==="BOUNCE"?1:0,complaintCount:n.reason==="COMPLAINT"?1:0};return this.suppressionList.set(n.emailAddress,o),o}removeFromSuppressionList(n){return this.suppressionList.delete(n)}isSuppressed(n){let i=this.suppressionList.get(n);if(!i)return!1;if(i.expiresAt&&i.expiresAt<new Date)return this.suppressionList.delete(n),!1;return!0}getBounceStatistics(n,i){let s=Array.from(this.bounces.values()).filter((b)=>b.timestamp>=n&&b.timestamp<=i),o=s.length,c=s.filter((b)=>b.bounceType==="Permanent").length,u=s.filter((b)=>b.bounceType==="Transient").length,d=o*10,p=o/d*100,y=new Map;for(let b of s)y.set(b.recipient,(y.get(b.recipient)||0)+1);let h=Array.from(y.entries()).map(([b,v])=>({email:b,count:v})).sort((b,v)=>v.count-b.count).slice(0,10);return{totalBounces:o,permanentBounces:c,transientBounces:u,bounceRate:p,topRecipients:h}}getComplaintStatistics(n,i){let s=Array.from(this.complaints.values()).filter((y)=>y.timestamp>=n&&y.timestamp<=i),o=s.length,c=new Set;for(let y of s)for(let h of y.recipients)c.add(h);let u=c.size,d=o*1000,p=o/d*100;return{totalComplaints:o,uniqueComplainters:u,complaintRate:p}}calculateReputationMetrics(){let n=`metrics-${Date.now()}-${this.metricsCounter++}`,i=new Date,s=new Date(i.getTime()-86400000),o=this.getBounceStatistics(s,i),c=this.getComplaintStatistics(s,i),u;if(o.bounceRate>10||c.complaintRate>0.5)u="Shutdown";else if(o.bounceRate>5||c.complaintRate>0.1)u="Probation";else if(o.bounceRate>2||c.complaintRate>0.05)u="Warning";else u="Good";let d={id:n,timestamp:i,bounceRate:o.bounceRate,complaintRate:c.complaintRate,sendingQuota:50000,maxSendRate:14,sentLast24Hours:o.totalBounces*10,reputationStatus:u};return this.metrics.set(n,d),d}getBounces(n){let i=Array.from(this.bounces.values());return n?i.filter((s)=>s.messageId===n):i}getComplaints(n){let i=Array.from(this.complaints.values());return n?i.filter((s)=>s.messageId===n):i}listSuppressionList(n){let i=Array.from(this.suppressionList.values());return n?i.filter((s)=>s.reason===n):i}generateSNSSubscriptionCF(n){return{Type:"AWS::SNS::Subscription",Properties:{TopicArn:n.topicArn,Endpoint:n.endpoint,Protocol:n.protocol}}}generateEventDestinationCF(n){return{Type:"AWS::SES::ConfigurationSetEventDestination",Properties:{ConfigurationSetName:n.configurationSetName,EventDestination:{Name:n.eventDestinationName,Enabled:!0,MatchingEventTypes:n.eventTypes,...n.snsTopicArn&&{SnsDestination:{TopicARN:n.snsTopicArn}},...n.cloudWatchDestination&&{CloudWatchDestination:n.cloudWatchDestination}}}}}clear(){this.bounces.clear(),this.complaints.clear(),this.handlers.clear(),this.suppressionList.clear(),this.metrics.clear(),this.bounceCounter=0,this.complaintCounter=0,this.handlerCounter=0,this.suppressionCounter=0,this.metricsCounter=0}}var IE=new yf;class Sf{events=new Map;campaigns=new Map;reports=new Map;abTests=new Map;eventCounter=0;campaignCounter=0;reportCounter=0;abTestCounter=0;trackEvent(n){let i=`event-${Date.now()}-${this.eventCounter++}`,s={id:i,...n};if(this.events.set(i,s),n.tags?.campaignId)this.updateCampaignStats(n.tags.campaignId,n.eventType);return s}trackOpen(n){return this.trackEvent({...n,eventType:"open",timestamp:new Date})}trackClick(n){return this.trackEvent({...n,eventType:"click",timestamp:new Date})}createCampaign(n){let i=`campaign-${Date.now()}-${this.campaignCounter++}`,s={id:i,sentCount:0,deliveredCount:0,openCount:0,clickCount:0,bounceCount:0,complaintCount:0,createdAt:new Date,...n};return this.campaigns.set(i,s),s}updateCampaignStats(n,i){let s=this.campaigns.get(n);if(!s)return;switch(i){case"send":s.sentCount++;break;case"delivery":s.deliveredCount++;break;case"open":s.openCount++;break;case"click":s.clickCount++;break;case"bounce":s.bounceCount++;break;case"complaint":s.complaintCount++;break}}generateReport(n){let i=`report-${Date.now()}-${this.reportCounter++}`,s=Array.from(this.events.values()).filter((N)=>{let O=N.timestamp>=n.startDate&&N.timestamp<=n.endDate,B=!n.campaignId||N.tags?.campaignId===n.campaignId;return O&&B}),o=s.filter((N)=>N.eventType==="send").length,c=s.filter((N)=>N.eventType==="delivery").length,u=s.filter((N)=>N.eventType==="open").length,d=s.filter((N)=>N.eventType==="click").length,p=s.filter((N)=>N.eventType==="bounce").length,y=s.filter((N)=>N.eventType==="complaint").length,h=o>0?c/o*100:0,b=c>0?u/c*100:0,v=c>0?d/c*100:0,A=u>0?d/u*100:0,T=o>0?p/o*100:0,R=c>0?y/c*100:0,P=new Map;for(let N of s)if(N.eventType==="click"){let O=N;P.set(O.link,(P.get(O.link)||0)+1)}let I=Array.from(P.entries()).map(([N,O])=>({link:N,clicks:O})).sort((N,O)=>O.clicks-N.clicks).slice(0,10),M={desktop:0,mobile:0,tablet:0,unknown:0};for(let N of s)if(N.eventType==="open"||N.eventType==="click"){let O=N.userAgent.toLowerCase();if(O.includes("mobile"))M.mobile++;else if(O.includes("tablet"))M.tablet++;else if(O.includes("mozilla"))M.desktop++;else M.unknown++}let L={id:i,campaignId:n.campaignId,startDate:n.startDate,endDate:n.endDate,totalSent:o,totalDelivered:c,totalOpened:u,totalClicked:d,totalBounced:p,totalComplaints:y,deliveryRate:h,openRate:b,clickRate:v,clickToOpenRate:A,bounceRate:T,complaintRate:R,topLinks:I,deviceBreakdown:M,locationBreakdown:{}};return this.reports.set(i,L),L}createABTest(n){let i=`abtest-${Date.now()}-${this.abTestCounter++}`,s={id:i,name:n.name,variants:n.variants.map((o,c)=>({id:`variant-${i}-${c}`,sentCount:0,openCount:0,clickCount:0,conversionCount:0,...o})),status:"draft"};return this.abTests.set(i,s),s}startABTest(n){let i=this.abTests.get(n);if(!i)throw Error(`A/B test not found: ${n}`);return i.status="running",i.startedAt=new Date,i}completeABTest(n){let i=this.abTests.get(n);if(!i)throw Error(`A/B test not found: ${n}`);let s=i.variants[0],o=0;for(let c of i.variants){let u=c.sentCount>0?c.openCount/c.sentCount:0;if(u>o)o=u,s=c}return i.status="completed",i.completedAt=new Date,i.winner=s.id,i}getCampaign(n){return this.campaigns.get(n)}listCampaigns(){return Array.from(this.campaigns.values())}getEvents(n){let i=Array.from(this.events.values());if(n?.messageId)i=i.filter((s)=>s.messageId===n.messageId);if(n?.eventType)i=i.filter((s)=>s.eventType===n.eventType);if(n?.startDate)i=i.filter((s)=>s.timestamp>=n.startDate);if(n?.endDate)i=i.filter((s)=>s.timestamp<=n.endDate);return i}generateTrackingConfigurationCF(n){return{Type:"AWS::SES::ConfigurationSet",Properties:{Name:n.configurationSetName,...n.openTracking&&{TrackingOptions:{CustomRedirectDomain:"tracking.example.com"}}}}}clear(){this.events.clear(),this.campaigns.clear(),this.reports.clear(),this.abTests.clear(),this.eventCounter=0,this.campaignCounter=0,this.reportCounter=0,this.abTestCounter=0}}var bE=new Sf;class If{dashboards=new Map;warmupPlans=new Map;domainReputations=new Map;dashboardCounter=0;warmupCounter=0;domainCounter=0;getReputationDashboard(){let n=`dashboard-${Date.now()}-${this.dashboardCounter++}`,i=Math.random()*5,s=Math.random()*0.5,o=Math.floor(Math.random()*10),c=Math.max(0,100-i*10-s*100-o*2),u=[];if(i>2)u.push("Reduce bounce rate by cleaning email list");if(s>0.1)u.push("Review email content and unsubscribe process");if(o>5)u.push("Improve email relevance and targeting");let d={id:n,timestamp:new Date,overallScore:c,bounceRate:i,complaintRate:s,spamReports:o,blacklistStatus:this.checkBlacklists(),dkimStatus:"VERIFIED",spfStatus:"PASS",dmarcStatus:"PASS",sendingLimits:{maxSendRate:14,max24HourSend:50000,sentLast24Hours:12000,remainingQuota:38000,quotaResetTime:new Date(Date.now()+86400000)},recommendations:u};return this.dashboards.set(n,d),d}checkBlacklists(){return["Spamhaus ZEN","Spamcop","SORBS","Barracuda","URIBL"].map((i)=>({listName:i,listed:Math.random()>0.95,delistUrl:`https://www.${i.toLowerCase().replace(/\s/g,"")}.org/delist`}))}createWarmupPlan(n){let i=`warmup-${Date.now()}-${this.warmupCounter++}`,s=[],o=(n.targetDailyLimit-n.initialDailyLimit)/n.durationDays;for(let u=0;u<n.durationDays;u++)s.push(Math.floor(n.initialDailyLimit+o*u));let c={id:i,name:n.name,startDate:new Date,currentDay:1,totalDays:n.durationDays,dailyLimits:s,currentLimit:s[0],status:"active"};return this.warmupPlans.set(i,c),c}createAggressiveWarmupPlan(n){return this.createWarmupPlan({name:n.name,initialDailyLimit:500,targetDailyLimit:50000,durationDays:14})}createConservativeWarmupPlan(n){return this.createWarmupPlan({name:n.name,initialDailyLimit:200,targetDailyLimit:50000,durationDays:30})}advanceWarmupPlan(n){let i=this.warmupPlans.get(n);if(!i)throw Error(`Warmup plan not found: ${n}`);if(i.currentDay<i.totalDays)i.currentDay++,i.currentLimit=i.dailyLimits[i.currentDay-1];if(i.currentDay>=i.totalDays)i.status="completed";return i}trackDomainReputation(n){let i=`domain-${Date.now()}-${this.domainCounter++}`,s=n.delivered/n.totalSent*100,o=n.delivered>0?n.opened/n.delivered*100:0,c=n.delivered>0?n.clicked/n.delivered*100:0,u=n.bounced/n.totalSent*100,d=n.delivered>0?n.complained/n.delivered*100:0,p=o*0.4+c*0.6,y=Math.max(0,100-u*10-d*100+p*0.2),h={id:i,domain:n.domain,reputationScore:y,totalSent:n.totalSent,deliveryRate:s,openRate:o,clickRate:c,bounceRate:u,complaintRate:d,engagementScore:p};return this.domainReputations.set(n.domain,h),h}getDomainReputation(n){return this.domainReputations.get(n)}listDomainReputations(){return Array.from(this.domainReputations.values())}getWarmupPlan(n){return this.warmupPlans.get(n)}listWarmupPlans(){return Array.from(this.warmupPlans.values())}clear(){this.dashboards.clear(),this.warmupPlans.clear(),this.domainReputations.clear(),this.dashboardCounter=0,this.warmupCounter=0,this.domainCounter=0}}var CE=new If;class bf{templates=new Map;versions=new Map;tests=new Map;templateCounter=0;testCounter=0;createTemplate(n){let i=`template-${Date.now()}-${this.templateCounter++}`,s=this.extractVariables(n.subject+n.htmlPart+n.textPart),o={id:i,variables:s,createdAt:new Date,updatedAt:new Date,version:1,...n};return this.templates.set(i,o),this.addVersion({templateId:i,version:1,subject:n.subject,htmlPart:n.htmlPart,textPart:n.textPart,createdBy:"system"}),o}createWelcomeTemplate(n){return this.createTemplate({name:n.name,subject:"Welcome to {{companyName}}!",htmlPart:`
3742
3742
  <html>
3743
3743
  <body>
3744
3744
  <h1>Welcome, {{userName}}!</h1>
@@ -3758,7 +3758,7 @@ COPY . .`,impact:"Improve build time by 60-80% on subsequent builds"});let p={si
3758
3758
  <p>If you didn't request this, please ignore this email.</p>
3759
3759
  </body>
3760
3760
  </html>
3761
- `,textPart:"Hi {{userName}}, reset your password at: {{resetUrl}}. This link expires in {{expirationHours}} hours."})}updateTemplate(n,i,s){let o=this.templates.get(n);if(!o)throw Error(`Template not found: ${n}`);if(i.subject)o.subject=i.subject;if(i.htmlPart)o.htmlPart=i.htmlPart;if(i.textPart)o.textPart=i.textPart;return o.version++,o.updatedAt=new Date,o.variables=this.extractVariables(o.subject+o.htmlPart+o.textPart),this.addVersion({templateId:n,version:o.version,subject:o.subject,htmlPart:o.htmlPart,textPart:o.textPart,createdBy:"system",changelog:s}),o}addVersion(n){let s={id:`version-${n.templateId}-${n.version}`,createdAt:new Date,...n},o=this.versions.get(n.templateId)||[];return o.push(s),this.versions.set(n.templateId,o),s}extractVariables(n){let i=/\{\{([^}]+)\}\}/g,s=new Set,o;while((o=i.exec(n))!==null)s.add(o[1].trim());return Array.from(s)}renderTemplate(n,i){let s=this.templates.get(n);if(!s)throw Error(`Template not found: ${n}`);let o=(c)=>c.replace(/\{\{([^}]+)\}\}/g,(u,d)=>{let p=d.trim();return i[p]!==void 0?String(i[p]):u});return{subject:o(s.subject),html:o(s.htmlPart),text:o(s.textPart)}}testTemplate(n,i){let s=`test-${Date.now()}-${this.testCounter++}`,o=this.renderTemplate(n,i),c={id:s,templateId:n,testData:i,renderedSubject:o.subject,renderedHtml:o.html,renderedText:o.text,timestamp:new Date};return this.tests.set(s,c),c}getTemplate(n){return this.templates.get(n)}listTemplates(){return Array.from(this.templates.values())}getTemplateVersions(n){return this.versions.get(n)||[]}revertToVersion(n,i){let s=this.templates.get(n);if(!s)throw Error(`Template not found: ${n}`);let c=(this.versions.get(n)||[]).find((u)=>u.version===i);if(!c)throw Error(`Version ${i} not found for template ${n}`);return s.subject=c.subject,s.htmlPart=c.htmlPart,s.textPart=c.textPart,s.version++,s.updatedAt=new Date,this.addVersion({templateId:n,version:s.version,subject:s.subject,htmlPart:s.htmlPart,textPart:s.textPart,createdBy:"system",changelog:`Reverted to version ${i}`}),s}generateTemplateCF(n){return{Type:"AWS::SES::Template",Properties:{Template:{TemplateName:n.name,SubjectPart:n.subject,HtmlPart:n.htmlPart,TextPart:n.textPart}}}}clear(){this.templates.clear(),this.versions.clear(),this.tests.clear(),this.templateCounter=0,this.testCounter=0}}var CE=new If;class Gt{static createSearchDomain(n){let{slug:i,environment:s,domainName:o,instanceType:c="t3.small.search",instanceCount:u=1,ebsVolumeSize:d=10,masterUserName:p="admin",masterUserPassword:y}=n,h=o||`${i}-${s}-email-search`;return{[`${i}EmailSearchDomain`]:{Type:"AWS::OpenSearchService::Domain",Properties:{DomainName:h,EngineVersion:"OpenSearch_2.11",ClusterConfig:{InstanceType:c,InstanceCount:u,DedicatedMasterEnabled:!1,ZoneAwarenessEnabled:!1},EBSOptions:{EBSEnabled:!0,VolumeType:"gp3",VolumeSize:d},NodeToNodeEncryptionOptions:{Enabled:!0},EncryptionAtRestOptions:{Enabled:!0},DomainEndpointOptions:{EnforceHTTPS:!0},AdvancedSecurityOptions:{Enabled:!0,InternalUserDatabaseEnabled:!0,MasterUserOptions:{MasterUserName:p,MasterUserPassword:y||`${i}-search-${Date.now()}`}},AccessPolicies:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:`arn:aws:es:*:*:domain/${h}/*`}]}}}}}static createIndexerLambda(n){return{[`${n.slug}EmailIndexerLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-email-indexer`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:60,MemorySize:512,Code:{ZipFile:Gt.IndexerLambdaCode},Environment:{Variables:{OPENSEARCH_ENDPOINT:n.searchDomainEndpoint,EMAIL_BUCKET:n.emailBucket}}}}}}static IndexerLambdaCode=`
3761
+ `,textPart:"Hi {{userName}}, reset your password at: {{resetUrl}}. This link expires in {{expirationHours}} hours."})}updateTemplate(n,i,s){let o=this.templates.get(n);if(!o)throw Error(`Template not found: ${n}`);if(i.subject)o.subject=i.subject;if(i.htmlPart)o.htmlPart=i.htmlPart;if(i.textPart)o.textPart=i.textPart;return o.version++,o.updatedAt=new Date,o.variables=this.extractVariables(o.subject+o.htmlPart+o.textPart),this.addVersion({templateId:n,version:o.version,subject:o.subject,htmlPart:o.htmlPart,textPart:o.textPart,createdBy:"system",changelog:s}),o}addVersion(n){let s={id:`version-${n.templateId}-${n.version}`,createdAt:new Date,...n},o=this.versions.get(n.templateId)||[];return o.push(s),this.versions.set(n.templateId,o),s}extractVariables(n){let i=/\{\{([^}]+)\}\}/g,s=new Set,o;while((o=i.exec(n))!==null)s.add(o[1].trim());return Array.from(s)}renderTemplate(n,i){let s=this.templates.get(n);if(!s)throw Error(`Template not found: ${n}`);let o=(c)=>c.replace(/\{\{([^}]+)\}\}/g,(u,d)=>{let p=d.trim();return i[p]!==void 0?String(i[p]):u});return{subject:o(s.subject),html:o(s.htmlPart),text:o(s.textPart)}}testTemplate(n,i){let s=`test-${Date.now()}-${this.testCounter++}`,o=this.renderTemplate(n,i),c={id:s,templateId:n,testData:i,renderedSubject:o.subject,renderedHtml:o.html,renderedText:o.text,timestamp:new Date};return this.tests.set(s,c),c}getTemplate(n){return this.templates.get(n)}listTemplates(){return Array.from(this.templates.values())}getTemplateVersions(n){return this.versions.get(n)||[]}revertToVersion(n,i){let s=this.templates.get(n);if(!s)throw Error(`Template not found: ${n}`);let c=(this.versions.get(n)||[]).find((u)=>u.version===i);if(!c)throw Error(`Version ${i} not found for template ${n}`);return s.subject=c.subject,s.htmlPart=c.htmlPart,s.textPart=c.textPart,s.version++,s.updatedAt=new Date,this.addVersion({templateId:n,version:s.version,subject:s.subject,htmlPart:s.htmlPart,textPart:s.textPart,createdBy:"system",changelog:`Reverted to version ${i}`}),s}generateTemplateCF(n){return{Type:"AWS::SES::Template",Properties:{Template:{TemplateName:n.name,SubjectPart:n.subject,HtmlPart:n.htmlPart,TextPart:n.textPart}}}}clear(){this.templates.clear(),this.versions.clear(),this.tests.clear(),this.templateCounter=0,this.testCounter=0}}var EE=new bf;class Gt{static createSearchDomain(n){let{slug:i,environment:s,domainName:o,instanceType:c="t3.small.search",instanceCount:u=1,ebsVolumeSize:d=10,masterUserName:p="admin",masterUserPassword:y}=n,h=o||`${i}-${s}-email-search`;return{[`${i}EmailSearchDomain`]:{Type:"AWS::OpenSearchService::Domain",Properties:{DomainName:h,EngineVersion:"OpenSearch_2.11",ClusterConfig:{InstanceType:c,InstanceCount:u,DedicatedMasterEnabled:!1,ZoneAwarenessEnabled:!1},EBSOptions:{EBSEnabled:!0,VolumeType:"gp3",VolumeSize:d},NodeToNodeEncryptionOptions:{Enabled:!0},EncryptionAtRestOptions:{Enabled:!0},DomainEndpointOptions:{EnforceHTTPS:!0},AdvancedSecurityOptions:{Enabled:!0,InternalUserDatabaseEnabled:!0,MasterUserOptions:{MasterUserName:p,MasterUserPassword:y||`${i}-search-${Date.now()}`}},AccessPolicies:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:`arn:aws:es:*:*:domain/${h}/*`}]}}}}}static createIndexerLambda(n){return{[`${n.slug}EmailIndexerLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-email-indexer`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:60,MemorySize:512,Code:{ZipFile:Gt.IndexerLambdaCode},Environment:{Variables:{OPENSEARCH_ENDPOINT:n.searchDomainEndpoint,EMAIL_BUCKET:n.emailBucket}}}}}}static IndexerLambdaCode=`
3762
3762
  const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');
3763
3763
  const https = require('https');
3764
3764
 
@@ -7226,7 +7226,7 @@ function unmarshallTest(item) {
7226
7226
 
7227
7227
  return test;
7228
7228
  }
7229
- `;static createAbTestsTable(n){return{[`${n.slug}AbTestsTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${n.slug}-ab-tests`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"id",AttributeType:"S"}],KeySchema:[{AttributeName:"id",KeyType:"HASH"}]}}}}static createAbTestManagerLambda(n){return{[`${n.slug}AbTestManagerLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-ab-test-manager`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:Ee.AbTestManagerCode},Environment:{Variables:{AB_TESTS_TABLE:n.abTestsTable}}}}}}static selectVariant(n,i){let o=Ee.hashString(i+n.id)%100,c=0;for(let u=0;u<n.variants.length;u++)if(c+=n.trafficSplit[u],o<c)return n.variants[u];return n.variants[n.variants.length-1]}static determineWinner(n){if(n.variants.length===0)return null;let i=n.winningCriteria,s=n.variants[0],o=Ee.getMetricValue(s,i);for(let c of n.variants.slice(1)){let u=Ee.getMetricValue(c,i);if(u>o)o=u,s=c}return s}static calculateSignificance(n,i,s){let o=n.stats.sent,c=i.stats.sent;if(o<30||c<30)return 0;let u=Ee.getMetricValue(n,s)/100,d=Ee.getMetricValue(i,s)/100,p=(u*o+d*c)/(o+c),y=Math.sqrt(p*(1-p)*(1/o+1/c));if(y===0)return 0;let h=Math.abs(u-d)/y;if(h>=2.576)return 99;if(h>=1.96)return 95;if(h>=1.645)return 90;if(h>=1.28)return 80;return Math.round(h*30)}static getMetricValue(n,i){switch(i){case"delivery_rate":return n.stats.deliveryRate;case"click_rate":return n.stats.clickRate;case"reply_rate":return n.stats.replyRate;case"conversion_rate":return n.stats.conversionRate;default:return n.stats.deliveryRate}}static hashString(n){let i=0;for(let s=0;s<n.length;s++){let o=n.charCodeAt(s);i=(i<<5)-i+o,i=i&i}return Math.abs(i)}}class Tf{queues=new Map;messageGroups=new Map;deduplicationConfigs=new Map;messages=new Map;queueCounter=0;groupCounter=0;deduplicationCounter=0;messageCounter=0;sequenceCounter=0;createFIFOQueue(n){let i=`fifo-queue-${Date.now()}-${this.queueCounter++}`,s=n.name.endsWith(".fifo")?n.name:`${n.name}.fifo`,{name:o,...c}=n,u={id:i,name:s,queueUrl:`https://sqs.us-east-1.amazonaws.com/123456789012/${s}`,...c};return this.queues.set(i,u),this.createDeduplicationConfig({queueId:i,contentBasedDeduplication:n.contentBasedDeduplication,deduplicationInterval:300}),u}createHighThroughputFIFO(n){return this.createFIFOQueue({name:n.name,contentBasedDeduplication:n.contentBasedDeduplication??!0,deduplicationScope:"messageGroup",fifoThroughputLimit:"perMessageGroupId",messageRetentionPeriod:345600,visibilityTimeout:30,receiveMessageWaitTime:0})}createStandardFIFO(n){return this.createFIFOQueue({name:n.name,contentBasedDeduplication:n.contentBasedDeduplication??!1,deduplicationScope:"queue",fifoThroughputLimit:"perQueue",messageRetentionPeriod:345600,visibilityTimeout:30,receiveMessageWaitTime:0})}createDeduplicationConfig(n){let s={id:`dedup-${Date.now()}-${this.deduplicationCounter++}`,deduplicationHashes:new Map,...n};return this.deduplicationConfigs.set(n.queueId,s),s}sendMessage(n){let i=this.queues.get(n.queueId);if(!i)throw Error(`Queue not found: ${n.queueId}`);let s=this.deduplicationConfigs.get(n.queueId);if(s){let d=n.messageDeduplicationId||(i.contentBasedDeduplication?this.generateHash(n.messageBody):void 0);if(d&&this.isDuplicate(s,d))return null;if(d)s.deduplicationHashes.set(d,new Date)}let o=`msg-${Date.now()}-${this.messageCounter++}`,c=this.generateSequenceNumber(),u={id:o,messageId:o,messageGroupId:n.messageGroupId,messageDeduplicationId:n.messageDeduplicationId,body:n.messageBody,attributes:n.messageAttributes||{},sentTimestamp:new Date,sequenceNumber:c};return this.messages.set(o,u),this.updateMessageGroup(n.queueId,n.messageGroupId),u}isDuplicate(n,i){let s=n.deduplicationHashes.get(i);if(!s)return!1;if((Date.now()-s.getTime())/1000>n.deduplicationInterval)return n.deduplicationHashes.delete(i),!1;return!0}generateHash(n){let i=0;for(let s=0;s<n.length;s++){let o=n.charCodeAt(s);i=(i<<5)-i+o,i=i&i}return Math.abs(i).toString(36)}generateSequenceNumber(){return`${Date.now()}${this.sequenceCounter++}`.padStart(20,"0")}updateMessageGroup(n,i){let s=`${n}-${i}`,o=this.messageGroups.get(s);if(!o)o={id:`group-${Date.now()}-${this.groupCounter++}`,messageGroupId:i,queueId:n,messagesInFlight:0},this.messageGroups.set(s,o);o.messagesInFlight++,o.lastMessageTimestamp=new Date}getMessageGroups(n){return Array.from(this.messageGroups.values()).filter((i)=>i.queueId===n)}getQueue(n){return this.queues.get(n)}listQueues(){return Array.from(this.queues.values())}getMessages(n,i){let s=Array.from(this.messages.values());if(i)s=s.filter((o)=>o.messageGroupId===i);return s.sort((o,c)=>o.sequenceNumber.localeCompare(c.sequenceNumber))}generateFIFOQueueCF(n){return{Type:"AWS::SQS::Queue",Properties:{QueueName:n.name,FifoQueue:!0,ContentBasedDeduplication:n.contentBasedDeduplication,DeduplicationScope:n.deduplicationScope,FifoThroughputLimit:n.fifoThroughputLimit,MessageRetentionPeriod:n.messageRetentionPeriod,VisibilityTimeout:n.visibilityTimeout,ReceiveMessageWaitTimeSeconds:n.receiveMessageWaitTime,...n.deadLetterTargetArn&&{RedrivePolicy:{deadLetterTargetArn:n.deadLetterTargetArn,maxReceiveCount:n.maxReceiveCount||3}}}}}clear(){this.queues.clear(),this.messageGroups.clear(),this.deduplicationConfigs.clear(),this.messages.clear(),this.queueCounter=0,this.groupCounter=0,this.deduplicationCounter=0,this.messageCounter=0,this.sequenceCounter=0}}var EE=new Tf;class wf{monitors=new Map;metrics=new Map;alerts=new Map;reprocessJobs=new Map;monitorCounter=0;metricsCounter=0;alertCounter=0;jobCounter=0;createDLQMonitor(n){let i=`dlq-monitor-${Date.now()}-${this.monitorCounter++}`,s={id:i,...n};return this.monitors.set(i,s),s}createAutomatedMonitor(n){return this.createDLQMonitor({name:n.name,queueUrl:n.queueUrl,sourceQueues:n.sourceQueues,maxReceiveCount:3,alarmThreshold:10,autoReprocess:!0,reprocessStrategy:"scheduled",notificationTopicArn:n.notificationTopicArn})}collectMetrics(n){let s={id:`metrics-${Date.now()}-${this.metricsCounter++}`,queueUrl:n,timestamp:new Date,approximateNumberOfMessages:Math.floor(Math.random()*100),approximateAgeOfOldestMessage:Math.floor(Math.random()*86400),messagesReceived:Math.floor(Math.random()*50),messagesDeleted:Math.floor(Math.random()*30),messagesReprocessed:Math.floor(Math.random()*20)},o=this.metrics.get(n)||[];return o.push(s),this.metrics.set(n,o),this.checkForAlerts(n,s),s}checkForAlerts(n,i){let s=Array.from(this.monitors.values()).find((c)=>c.queueUrl===n);if(!s)return;if(i.approximateNumberOfMessages>=s.alarmThreshold)this.createAlert({monitorId:s.id,alertType:"threshold_exceeded",severity:"high",message:`DLQ ${s.name} has ${i.approximateNumberOfMessages} messages (threshold: ${s.alarmThreshold})`});let o=3600;if(i.approximateAgeOfOldestMessage>o)this.createAlert({monitorId:s.id,alertType:"old_message",severity:"medium",message:`DLQ ${s.name} has messages older than ${o} seconds`})}createAlert(n){let i=`alert-${Date.now()}-${this.alertCounter++}`,s={id:i,timestamp:new Date,acknowledged:!1,...n};return this.alerts.set(i,s),s}acknowledgeAlert(n){let i=this.alerts.get(n);if(!i)throw Error(`Alert not found: ${n}`);return i.acknowledged=!0,i}createReprocessJob(n){let i=`reprocess-${Date.now()}-${this.jobCounter++}`,s={id:i,queueUrl:n.queueUrl,messageId:n.messageId,attempts:0,status:"pending"};return this.reprocessJobs.set(i,s),s}async executeReprocessJob(n){let i=this.reprocessJobs.get(n);if(!i)throw Error(`Reprocess job not found: ${n}`);i.status="processing",i.startedAt=new Date,i.attempts++,await new Promise((o)=>setTimeout(o,100));let s=Math.random()>0.3;if(i.status=s?"success":"failed",i.completedAt=new Date,!s)i.error="Reprocessing failed - original error still present";return i}async batchReprocess(n){let i=[];for(let s=0;s<n.maxMessages;s++){let o=this.createReprocessJob({queueUrl:n.queueUrl,messageId:`msg-${s}`});await this.executeReprocessJob(o.id),i.push(o)}return i}getDLQStatistics(n,i=24){let s=new Date(Date.now()-i*60*60*1000),o=(this.metrics.get(n)||[]).filter((b)=>b.timestamp>=s);if(o.length===0)return{totalMessages:0,avgAge:0,messagesReceived:0,messagesDeleted:0,messagesReprocessed:0,successRate:0};let c=o[o.length-1],u=o.reduce((b,v)=>b+v.messagesReceived,0),d=o.reduce((b,v)=>b+v.messagesDeleted,0),p=o.reduce((b,v)=>b+v.messagesReprocessed,0),y=o.reduce((b,v)=>b+v.approximateAgeOfOldestMessage,0)/o.length,h=p>0?d/p*100:0;return{totalMessages:c.approximateNumberOfMessages,avgAge:y,messagesReceived:u,messagesDeleted:d,messagesReprocessed:p,successRate:h}}getMonitor(n){return this.monitors.get(n)}listMonitors(){return Array.from(this.monitors.values())}getAlerts(n,i){let s=Array.from(this.alerts.values());if(n)s=s.filter((o)=>o.monitorId===n);if(i!==void 0)s=s.filter((o)=>o.acknowledged===i);return s.sort((o,c)=>c.timestamp.getTime()-o.timestamp.getTime())}getReprocessJobs(n){let i=Array.from(this.reprocessJobs.values());if(n)i=i.filter((s)=>s.queueUrl===n);return i}generateDLQAlarmCF(n){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${n.name}-messages-alarm`,AlarmDescription:`Alert when DLQ ${n.name} exceeds threshold`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Average",Period:300,EvaluationPeriods:1,Threshold:n.alarmThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:n.queueUrl.split("/").pop()}],...n.notificationTopicArn&&{AlarmActions:[n.notificationTopicArn]}}}}clear(){this.monitors.clear(),this.metrics.clear(),this.alerts.clear(),this.reprocessJobs.clear(),this.monitorCounter=0,this.metricsCounter=0,this.alertCounter=0,this.jobCounter=0}}var vE=new wf;class Rf{configs=new Map;jobs=new Map;metrics=new Map;configCounter=0;jobCounter=0;metricsCounter=0;createBatchConfig(n){let i=`batch-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}createHighThroughputConfig(n){return this.createBatchConfig({queueUrl:n.queueUrl,batchSize:10,maxWaitTime:100,parallelProcessors:10,retryAttempts:3,visibilityTimeout:30})}createLowLatencyConfig(n){return this.createBatchConfig({queueUrl:n.queueUrl,batchSize:1,maxWaitTime:0,parallelProcessors:5,retryAttempts:2,visibilityTimeout:10})}createBatchJob(n){let i=`batch-job-${Date.now()}-${this.jobCounter++}`;if(!this.configs.get(n.configId))throw Error(`Batch config not found: ${n.configId}`);let o=[];for(let u=0;u<n.messageCount;u++)o.push({id:`msg-${i}-${u}`,messageId:`${i}-${u}`,body:`Message ${u}`,receiptHandle:`receipt-${i}-${u}`,attributes:{},status:"pending"});let c={id:i,configId:n.configId,messages:o,status:"pending",processedCount:0,failedCount:0};return this.jobs.set(i,c),c}async processBatchJob(n){let i=this.jobs.get(n);if(!i)throw Error(`Batch job not found: ${n}`);let s=this.configs.get(i.configId);if(!s)throw Error(`Batch config not found: ${i.configId}`);i.status="processing",i.startedAt=new Date;let o=this.chunkArray(i.messages,s.batchSize);for(let c of o)await this.processBatch(c,s);return i.processedCount=i.messages.filter((c)=>c.status==="success").length,i.failedCount=i.messages.filter((c)=>c.status==="failed").length,i.status=i.failedCount===0?"completed":"failed",i.completedAt=new Date,this.collectProcessorMetrics(s.id,i),i}async processBatch(n,i){let s=n.map((o)=>this.processMessage(o,i));await Promise.all(s)}async processMessage(n,i){n.status="processing";let s=Date.now();await new Promise((u)=>setTimeout(u,Math.random()*100));let o=Date.now()-s;if(n.processingTime=o,Math.random()>0.1)n.status="success";else n.status="failed",n.error="Processing error"}chunkArray(n,i){let s=[];for(let o=0;o<n.length;o+=i)s.push(n.slice(o,o+i));return s}collectProcessorMetrics(n,i){let s=`metrics-${Date.now()}-${this.metricsCounter++}`,c=i.messages.filter((v)=>v.status==="success").map((v)=>v.processingTime||0).filter((v)=>v>0),u=c.length>0?c.reduce((v,A)=>v+A,0)/c.length:0,d=i.completedAt&&i.startedAt?(i.completedAt.getTime()-i.startedAt.getTime())/1000:1,p=i.processedCount/d,y=i.messages.length>0?i.failedCount/i.messages.length*100:0,h={id:s,configId:n,timestamp:new Date,messagesProcessed:i.processedCount,averageProcessingTime:u,throughput:p,errorRate:y},b=this.metrics.get(n)||[];b.push(h),this.metrics.set(n,b)}getBatchStatistics(n){let i=this.metrics.get(n)||[];if(i.length===0)return{totalJobsProcessed:0,totalMessagesProcessed:0,averageThroughput:0,averageErrorRate:0,averageProcessingTime:0};let s=i.reduce((d,p)=>d+p.messagesProcessed,0),o=i.reduce((d,p)=>d+p.throughput,0)/i.length,c=i.reduce((d,p)=>d+p.errorRate,0)/i.length,u=i.reduce((d,p)=>d+p.averageProcessingTime,0)/i.length;return{totalJobsProcessed:i.length,totalMessagesProcessed:s,averageThroughput:o,averageErrorRate:c,averageProcessingTime:u}}optimizeBatchConfig(n){let i=this.configs.get(n);if(!i)throw Error(`Batch config not found: ${n}`);let s=this.getBatchStatistics(n);if(s.averageErrorRate<5&&i.batchSize<10)i.batchSize=Math.min(10,i.batchSize+1);if(s.averageErrorRate>20&&i.batchSize>1)i.batchSize=Math.max(1,i.batchSize-1);if(s.averageThroughput<5&&i.parallelProcessors<20)i.parallelProcessors++;return i}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getJob(n){return this.jobs.get(n)}listJobs(n){let i=Array.from(this.jobs.values());if(n)i=i.filter((s)=>s.configId===n);return i}generateBatchProcessorCF(n){return{Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:`arn:aws:sqs:us-east-1:123456789012:${n.queueUrl.split("/").pop()}`,FunctionName:"batch-processor-function",BatchSize:n.batchSize,MaximumBatchingWindowInSeconds:n.maxWaitTime/1000,FunctionResponseTypes:["ReportBatchItemFailures"]}}}clear(){this.configs.clear(),this.jobs.clear(),this.metrics.clear(),this.configCounter=0,this.jobCounter=0,this.metricsCounter=0}}var TE=new Rf;class Df{queues=new Map;retentionPolicies=new Map;delayQueues=new Map;purgeOperations=new Map;metrics=new Map;queueCounter=0;retentionCounter=0;delayCounter=0;purgeCounter=0;metricsCounter=0;createQueue(n){let i=`queue-${Date.now()}-${this.queueCounter++}`,s={id:i,purgeInProgress:!1,...n};return this.queues.set(i,s),s}createStandardQueue(n){return this.createQueue({queueUrl:`https://sqs.us-east-1.amazonaws.com/123456789012/${n.queueName}`,queueName:n.queueName,messageRetentionPeriod:(n.messageRetentionDays||4)*24*60*60,delaySeconds:0,maximumMessageSize:262144,receiveMessageWaitTime:0})}createLongPollingQueue(n){return this.createQueue({queueUrl:`https://sqs.us-east-1.amazonaws.com/123456789012/${n.queueName}`,queueName:n.queueName,messageRetentionPeriod:345600,delaySeconds:0,maximumMessageSize:262144,receiveMessageWaitTime:n.waitTimeSeconds||20})}createRetentionPolicy(n){let i=`retention-${Date.now()}-${this.retentionCounter++}`,s={id:i,...n};this.retentionPolicies.set(i,s);let o=this.queues.get(n.queueId);if(o)o.messageRetentionPeriod=n.retentionPeriod;return s}createShortRetentionPolicy(n){return this.createRetentionPolicy({queueId:n.queueId,retentionPeriod:n.retentionHours*60*60,autoCleanup:!0,archiveExpiredMessages:!1})}createArchivalRetentionPolicy(n){return this.createRetentionPolicy({queueId:n.queueId,retentionPeriod:n.retentionDays*24*60*60,autoCleanup:!0,cleanupSchedule:"cron(0 0 * * ? *)",archiveExpiredMessages:!0,archiveS3Bucket:n.s3Bucket})}createDelayQueue(n){let i=`delay-${Date.now()}-${this.delayCounter++}`,s={id:i,...n};this.delayQueues.set(i,s);let o=Array.from(this.queues.values()).find((c)=>c.queueUrl===n.queueUrl);if(o)o.delaySeconds=n.defaultDelay;return s}createScheduledDelayQueue(n){return this.createDelayQueue({queueUrl:n.queueUrl,defaultDelay:n.delayMinutes*60,perMessageDelay:!1,maxDelay:900})}async purgeQueue(n){let i=this.queues.get(n);if(!i)throw Error(`Queue not found: ${n}`);if(i.purgeInProgress)throw Error("Purge already in progress for this queue");let s=`purge-${Date.now()}-${this.purgeCounter++}`,o={id:s,queueUrl:i.queueUrl,status:"in_progress",startedAt:new Date};return this.purgeOperations.set(s,o),i.purgeInProgress=!0,setTimeout(()=>{o.status="completed",o.completedAt=new Date,o.messagesPurged=Math.floor(Math.random()*1000),i.purgeInProgress=!1},100),o}collectQueueMetrics(n){let s={id:`metrics-${Date.now()}-${this.metricsCounter++}`,queueUrl:n,timestamp:new Date,approximateNumberOfMessages:Math.floor(Math.random()*1000),approximateNumberOfMessagesNotVisible:Math.floor(Math.random()*100),approximateNumberOfMessagesDelayed:Math.floor(Math.random()*50),oldestMessageAge:Math.floor(Math.random()*86400)},o=this.metrics.get(n)||[];return o.push(s),this.metrics.set(n,o),s}getQueueHealth(n){let i=this.metrics.get(n)||[];if(i.length===0)return{status:"healthy",issues:[],recommendations:[]};let s=i[i.length-1],o=[],c=[],u="healthy";if(s.approximateNumberOfMessages>1e4)u="critical",o.push("Large message backlog detected"),c.push("Increase consumer capacity");else if(s.approximateNumberOfMessages>1000)u="warning",o.push("Growing message backlog"),c.push("Monitor consumer performance");if(s.oldestMessageAge&&s.oldestMessageAge>3600){if(u!=="critical")u="warning";o.push("Old messages in queue"),c.push("Review message processing")}if(s.approximateNumberOfMessagesDelayed>100){if(u!=="critical")u="warning";o.push("High number of delayed messages")}return{status:u,issues:o,recommendations:c}}getQueue(n){return this.queues.get(n)}listQueues(){return Array.from(this.queues.values())}getRetentionPolicy(n){return this.retentionPolicies.get(n)}listRetentionPolicies(){return Array.from(this.retentionPolicies.values())}getPurgeOperations(n){let i=Array.from(this.purgeOperations.values());if(n)i=i.filter((s)=>s.queueUrl===n);return i}generateQueueCF(n){return{Type:"AWS::SQS::Queue",Properties:{QueueName:n.queueName,MessageRetentionPeriod:n.messageRetentionPeriod,DelaySeconds:n.delaySeconds,MaximumMessageSize:n.maximumMessageSize,ReceiveMessageWaitTimeSeconds:n.receiveMessageWaitTime}}}generateCleanupRuleCF(n){return{Type:"AWS::Events::Rule",Properties:{Name:`${n.id}-cleanup`,Description:"Automated queue cleanup",ScheduleExpression:n.cleanupSchedule||"cron(0 0 * * ? *)",State:"ENABLED",Targets:[{Arn:"arn:aws:lambda:us-east-1:123456789012:function:queue-cleanup",Id:n.id,Input:JSON.stringify({queueId:n.queueId,archiveBucket:n.archiveS3Bucket})}]}}}clear(){this.queues.clear(),this.retentionPolicies.clear(),this.delayQueues.clear(),this.purgeOperations.clear(),this.metrics.clear(),this.queueCounter=0,this.retentionCounter=0,this.delayCounter=0,this.purgeCounter=0,this.metricsCounter=0}}var wE=new Df;import{deflateRawSync as Mi}from"node:zlib";var Li=(()=>{let n=[];for(let i=0;i<256;i++){let s=i;for(let o=0;o<8;o++)s=s&1?3988292384^s>>>1:s>>>1;n[i]=s>>>0}return n})();function Oi(n){let i=4294967295;for(let s=0;s<n.length;s++)i=Li[(i^n[s])&255]^i>>>8;return(i^4294967295)>>>0}function $i(n){if(typeof n==="string")return Buffer.from(n,"utf-8");if(Buffer.isBuffer(n))return n;return Buffer.from(n)}function Bi(n){let i=Math.max(1980,n.getFullYear()),s=(n.getHours()<<11|n.getMinutes()<<5|n.getSeconds()>>1)&65535,o=(i-1980<<9|n.getMonth()+1<<5|n.getDate())&65535;return{time:s,date:o}}function rt(n){let i=[],s=[],o=0;for(let d of n){let p=$i(d.data),y=Mi(p),h=Oi(p),b=Buffer.from(d.name.replace(/\\/g,"/"),"utf-8"),{time:v,date:A}=Bi(d.date??new Date(0)),T=d.mode??420,R=Buffer.alloc(30+b.length);R.writeUInt32LE(67324752,0),R.writeUInt16LE(20,4),R.writeUInt16LE(0,6),R.writeUInt16LE(8,8),R.writeUInt16LE(v,10),R.writeUInt16LE(A,12),R.writeUInt32LE(h,14),R.writeUInt32LE(y.length,18),R.writeUInt32LE(p.length,22),R.writeUInt16LE(b.length,26),R.writeUInt16LE(0,28),b.copy(R,30);let P=Buffer.alloc(46+b.length);P.writeUInt32LE(33639248,0),P.writeUInt16LE(798,4),P.writeUInt16LE(20,6),P.writeUInt16LE(0,8),P.writeUInt16LE(8,10),P.writeUInt16LE(v,12),P.writeUInt16LE(A,14),P.writeUInt32LE(h,16),P.writeUInt32LE(y.length,20),P.writeUInt32LE(p.length,24),P.writeUInt16LE(b.length,28),P.writeUInt16LE(0,30),P.writeUInt16LE(0,32),P.writeUInt16LE(0,34),P.writeUInt16LE(0,36),P.writeUInt32LE((T&65535)<<16,38),P.writeUInt32LE(o,42),b.copy(P,46),i.push(R,y),s.push(P),o+=R.length+y.length}let c=Buffer.concat(s),u=Buffer.alloc(22);return u.writeUInt32LE(101010256,0),u.writeUInt16LE(0,4),u.writeUInt16LE(0,6),u.writeUInt16LE(n.length,8),u.writeUInt16LE(n.length,10),u.writeUInt32LE(c.length,12),u.writeUInt32LE(o,16),u.writeUInt16LE(0,20),Buffer.concat([...i,c,u])}function Pf(n){let i=n.adapterImport??"./adapter",s=n.entryImport.replace(/\\/g,"/");return`// Generated by ts-cloud — serverless app bootstrap. Do not edit.
7229
+ `;static createAbTestsTable(n){return{[`${n.slug}AbTestsTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${n.slug}-ab-tests`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"id",AttributeType:"S"}],KeySchema:[{AttributeName:"id",KeyType:"HASH"}]}}}}static createAbTestManagerLambda(n){return{[`${n.slug}AbTestManagerLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${n.slug}-ab-test-manager`,Runtime:"nodejs20.x",Handler:"index.handler",Role:n.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:Ee.AbTestManagerCode},Environment:{Variables:{AB_TESTS_TABLE:n.abTestsTable}}}}}}static selectVariant(n,i){let o=Ee.hashString(i+n.id)%100,c=0;for(let u=0;u<n.variants.length;u++)if(c+=n.trafficSplit[u],o<c)return n.variants[u];return n.variants[n.variants.length-1]}static determineWinner(n){if(n.variants.length===0)return null;let i=n.winningCriteria,s=n.variants[0],o=Ee.getMetricValue(s,i);for(let c of n.variants.slice(1)){let u=Ee.getMetricValue(c,i);if(u>o)o=u,s=c}return s}static calculateSignificance(n,i,s){let o=n.stats.sent,c=i.stats.sent;if(o<30||c<30)return 0;let u=Ee.getMetricValue(n,s)/100,d=Ee.getMetricValue(i,s)/100,p=(u*o+d*c)/(o+c),y=Math.sqrt(p*(1-p)*(1/o+1/c));if(y===0)return 0;let h=Math.abs(u-d)/y;if(h>=2.576)return 99;if(h>=1.96)return 95;if(h>=1.645)return 90;if(h>=1.28)return 80;return Math.round(h*30)}static getMetricValue(n,i){switch(i){case"delivery_rate":return n.stats.deliveryRate;case"click_rate":return n.stats.clickRate;case"reply_rate":return n.stats.replyRate;case"conversion_rate":return n.stats.conversionRate;default:return n.stats.deliveryRate}}static hashString(n){let i=0;for(let s=0;s<n.length;s++){let o=n.charCodeAt(s);i=(i<<5)-i+o,i=i&i}return Math.abs(i)}}class wf{queues=new Map;messageGroups=new Map;deduplicationConfigs=new Map;messages=new Map;queueCounter=0;groupCounter=0;deduplicationCounter=0;messageCounter=0;sequenceCounter=0;createFIFOQueue(n){let i=`fifo-queue-${Date.now()}-${this.queueCounter++}`,s=n.name.endsWith(".fifo")?n.name:`${n.name}.fifo`,{name:o,...c}=n,u={id:i,name:s,queueUrl:`https://sqs.us-east-1.amazonaws.com/123456789012/${s}`,...c};return this.queues.set(i,u),this.createDeduplicationConfig({queueId:i,contentBasedDeduplication:n.contentBasedDeduplication,deduplicationInterval:300}),u}createHighThroughputFIFO(n){return this.createFIFOQueue({name:n.name,contentBasedDeduplication:n.contentBasedDeduplication??!0,deduplicationScope:"messageGroup",fifoThroughputLimit:"perMessageGroupId",messageRetentionPeriod:345600,visibilityTimeout:30,receiveMessageWaitTime:0})}createStandardFIFO(n){return this.createFIFOQueue({name:n.name,contentBasedDeduplication:n.contentBasedDeduplication??!1,deduplicationScope:"queue",fifoThroughputLimit:"perQueue",messageRetentionPeriod:345600,visibilityTimeout:30,receiveMessageWaitTime:0})}createDeduplicationConfig(n){let s={id:`dedup-${Date.now()}-${this.deduplicationCounter++}`,deduplicationHashes:new Map,...n};return this.deduplicationConfigs.set(n.queueId,s),s}sendMessage(n){let i=this.queues.get(n.queueId);if(!i)throw Error(`Queue not found: ${n.queueId}`);let s=this.deduplicationConfigs.get(n.queueId);if(s){let d=n.messageDeduplicationId||(i.contentBasedDeduplication?this.generateHash(n.messageBody):void 0);if(d&&this.isDuplicate(s,d))return null;if(d)s.deduplicationHashes.set(d,new Date)}let o=`msg-${Date.now()}-${this.messageCounter++}`,c=this.generateSequenceNumber(),u={id:o,messageId:o,messageGroupId:n.messageGroupId,messageDeduplicationId:n.messageDeduplicationId,body:n.messageBody,attributes:n.messageAttributes||{},sentTimestamp:new Date,sequenceNumber:c};return this.messages.set(o,u),this.updateMessageGroup(n.queueId,n.messageGroupId),u}isDuplicate(n,i){let s=n.deduplicationHashes.get(i);if(!s)return!1;if((Date.now()-s.getTime())/1000>n.deduplicationInterval)return n.deduplicationHashes.delete(i),!1;return!0}generateHash(n){let i=0;for(let s=0;s<n.length;s++){let o=n.charCodeAt(s);i=(i<<5)-i+o,i=i&i}return Math.abs(i).toString(36)}generateSequenceNumber(){return`${Date.now()}${this.sequenceCounter++}`.padStart(20,"0")}updateMessageGroup(n,i){let s=`${n}-${i}`,o=this.messageGroups.get(s);if(!o)o={id:`group-${Date.now()}-${this.groupCounter++}`,messageGroupId:i,queueId:n,messagesInFlight:0},this.messageGroups.set(s,o);o.messagesInFlight++,o.lastMessageTimestamp=new Date}getMessageGroups(n){return Array.from(this.messageGroups.values()).filter((i)=>i.queueId===n)}getQueue(n){return this.queues.get(n)}listQueues(){return Array.from(this.queues.values())}getMessages(n,i){let s=Array.from(this.messages.values());if(i)s=s.filter((o)=>o.messageGroupId===i);return s.sort((o,c)=>o.sequenceNumber.localeCompare(c.sequenceNumber))}generateFIFOQueueCF(n){return{Type:"AWS::SQS::Queue",Properties:{QueueName:n.name,FifoQueue:!0,ContentBasedDeduplication:n.contentBasedDeduplication,DeduplicationScope:n.deduplicationScope,FifoThroughputLimit:n.fifoThroughputLimit,MessageRetentionPeriod:n.messageRetentionPeriod,VisibilityTimeout:n.visibilityTimeout,ReceiveMessageWaitTimeSeconds:n.receiveMessageWaitTime,...n.deadLetterTargetArn&&{RedrivePolicy:{deadLetterTargetArn:n.deadLetterTargetArn,maxReceiveCount:n.maxReceiveCount||3}}}}}clear(){this.queues.clear(),this.messageGroups.clear(),this.deduplicationConfigs.clear(),this.messages.clear(),this.queueCounter=0,this.groupCounter=0,this.deduplicationCounter=0,this.messageCounter=0,this.sequenceCounter=0}}var vE=new wf;class Rf{monitors=new Map;metrics=new Map;alerts=new Map;reprocessJobs=new Map;monitorCounter=0;metricsCounter=0;alertCounter=0;jobCounter=0;createDLQMonitor(n){let i=`dlq-monitor-${Date.now()}-${this.monitorCounter++}`,s={id:i,...n};return this.monitors.set(i,s),s}createAutomatedMonitor(n){return this.createDLQMonitor({name:n.name,queueUrl:n.queueUrl,sourceQueues:n.sourceQueues,maxReceiveCount:3,alarmThreshold:10,autoReprocess:!0,reprocessStrategy:"scheduled",notificationTopicArn:n.notificationTopicArn})}collectMetrics(n){let s={id:`metrics-${Date.now()}-${this.metricsCounter++}`,queueUrl:n,timestamp:new Date,approximateNumberOfMessages:Math.floor(Math.random()*100),approximateAgeOfOldestMessage:Math.floor(Math.random()*86400),messagesReceived:Math.floor(Math.random()*50),messagesDeleted:Math.floor(Math.random()*30),messagesReprocessed:Math.floor(Math.random()*20)},o=this.metrics.get(n)||[];return o.push(s),this.metrics.set(n,o),this.checkForAlerts(n,s),s}checkForAlerts(n,i){let s=Array.from(this.monitors.values()).find((c)=>c.queueUrl===n);if(!s)return;if(i.approximateNumberOfMessages>=s.alarmThreshold)this.createAlert({monitorId:s.id,alertType:"threshold_exceeded",severity:"high",message:`DLQ ${s.name} has ${i.approximateNumberOfMessages} messages (threshold: ${s.alarmThreshold})`});let o=3600;if(i.approximateAgeOfOldestMessage>o)this.createAlert({monitorId:s.id,alertType:"old_message",severity:"medium",message:`DLQ ${s.name} has messages older than ${o} seconds`})}createAlert(n){let i=`alert-${Date.now()}-${this.alertCounter++}`,s={id:i,timestamp:new Date,acknowledged:!1,...n};return this.alerts.set(i,s),s}acknowledgeAlert(n){let i=this.alerts.get(n);if(!i)throw Error(`Alert not found: ${n}`);return i.acknowledged=!0,i}createReprocessJob(n){let i=`reprocess-${Date.now()}-${this.jobCounter++}`,s={id:i,queueUrl:n.queueUrl,messageId:n.messageId,attempts:0,status:"pending"};return this.reprocessJobs.set(i,s),s}async executeReprocessJob(n){let i=this.reprocessJobs.get(n);if(!i)throw Error(`Reprocess job not found: ${n}`);i.status="processing",i.startedAt=new Date,i.attempts++,await new Promise((o)=>setTimeout(o,100));let s=Math.random()>0.3;if(i.status=s?"success":"failed",i.completedAt=new Date,!s)i.error="Reprocessing failed - original error still present";return i}async batchReprocess(n){let i=[];for(let s=0;s<n.maxMessages;s++){let o=this.createReprocessJob({queueUrl:n.queueUrl,messageId:`msg-${s}`});await this.executeReprocessJob(o.id),i.push(o)}return i}getDLQStatistics(n,i=24){let s=new Date(Date.now()-i*60*60*1000),o=(this.metrics.get(n)||[]).filter((b)=>b.timestamp>=s);if(o.length===0)return{totalMessages:0,avgAge:0,messagesReceived:0,messagesDeleted:0,messagesReprocessed:0,successRate:0};let c=o[o.length-1],u=o.reduce((b,v)=>b+v.messagesReceived,0),d=o.reduce((b,v)=>b+v.messagesDeleted,0),p=o.reduce((b,v)=>b+v.messagesReprocessed,0),y=o.reduce((b,v)=>b+v.approximateAgeOfOldestMessage,0)/o.length,h=p>0?d/p*100:0;return{totalMessages:c.approximateNumberOfMessages,avgAge:y,messagesReceived:u,messagesDeleted:d,messagesReprocessed:p,successRate:h}}getMonitor(n){return this.monitors.get(n)}listMonitors(){return Array.from(this.monitors.values())}getAlerts(n,i){let s=Array.from(this.alerts.values());if(n)s=s.filter((o)=>o.monitorId===n);if(i!==void 0)s=s.filter((o)=>o.acknowledged===i);return s.sort((o,c)=>c.timestamp.getTime()-o.timestamp.getTime())}getReprocessJobs(n){let i=Array.from(this.reprocessJobs.values());if(n)i=i.filter((s)=>s.queueUrl===n);return i}generateDLQAlarmCF(n){return{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${n.name}-messages-alarm`,AlarmDescription:`Alert when DLQ ${n.name} exceeds threshold`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Average",Period:300,EvaluationPeriods:1,Threshold:n.alarmThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:n.queueUrl.split("/").pop()}],...n.notificationTopicArn&&{AlarmActions:[n.notificationTopicArn]}}}}clear(){this.monitors.clear(),this.metrics.clear(),this.alerts.clear(),this.reprocessJobs.clear(),this.monitorCounter=0,this.metricsCounter=0,this.alertCounter=0,this.jobCounter=0}}var TE=new Rf;class Df{configs=new Map;jobs=new Map;metrics=new Map;configCounter=0;jobCounter=0;metricsCounter=0;createBatchConfig(n){let i=`batch-config-${Date.now()}-${this.configCounter++}`,s={id:i,...n};return this.configs.set(i,s),s}createHighThroughputConfig(n){return this.createBatchConfig({queueUrl:n.queueUrl,batchSize:10,maxWaitTime:100,parallelProcessors:10,retryAttempts:3,visibilityTimeout:30})}createLowLatencyConfig(n){return this.createBatchConfig({queueUrl:n.queueUrl,batchSize:1,maxWaitTime:0,parallelProcessors:5,retryAttempts:2,visibilityTimeout:10})}createBatchJob(n){let i=`batch-job-${Date.now()}-${this.jobCounter++}`;if(!this.configs.get(n.configId))throw Error(`Batch config not found: ${n.configId}`);let o=[];for(let u=0;u<n.messageCount;u++)o.push({id:`msg-${i}-${u}`,messageId:`${i}-${u}`,body:`Message ${u}`,receiptHandle:`receipt-${i}-${u}`,attributes:{},status:"pending"});let c={id:i,configId:n.configId,messages:o,status:"pending",processedCount:0,failedCount:0};return this.jobs.set(i,c),c}async processBatchJob(n){let i=this.jobs.get(n);if(!i)throw Error(`Batch job not found: ${n}`);let s=this.configs.get(i.configId);if(!s)throw Error(`Batch config not found: ${i.configId}`);i.status="processing",i.startedAt=new Date;let o=this.chunkArray(i.messages,s.batchSize);for(let c of o)await this.processBatch(c,s);return i.processedCount=i.messages.filter((c)=>c.status==="success").length,i.failedCount=i.messages.filter((c)=>c.status==="failed").length,i.status=i.failedCount===0?"completed":"failed",i.completedAt=new Date,this.collectProcessorMetrics(s.id,i),i}async processBatch(n,i){let s=n.map((o)=>this.processMessage(o,i));await Promise.all(s)}async processMessage(n,i){n.status="processing";let s=Date.now();await new Promise((u)=>setTimeout(u,Math.random()*100));let o=Date.now()-s;if(n.processingTime=o,Math.random()>0.1)n.status="success";else n.status="failed",n.error="Processing error"}chunkArray(n,i){let s=[];for(let o=0;o<n.length;o+=i)s.push(n.slice(o,o+i));return s}collectProcessorMetrics(n,i){let s=`metrics-${Date.now()}-${this.metricsCounter++}`,c=i.messages.filter((v)=>v.status==="success").map((v)=>v.processingTime||0).filter((v)=>v>0),u=c.length>0?c.reduce((v,A)=>v+A,0)/c.length:0,d=i.completedAt&&i.startedAt?(i.completedAt.getTime()-i.startedAt.getTime())/1000:1,p=i.processedCount/d,y=i.messages.length>0?i.failedCount/i.messages.length*100:0,h={id:s,configId:n,timestamp:new Date,messagesProcessed:i.processedCount,averageProcessingTime:u,throughput:p,errorRate:y},b=this.metrics.get(n)||[];b.push(h),this.metrics.set(n,b)}getBatchStatistics(n){let i=this.metrics.get(n)||[];if(i.length===0)return{totalJobsProcessed:0,totalMessagesProcessed:0,averageThroughput:0,averageErrorRate:0,averageProcessingTime:0};let s=i.reduce((d,p)=>d+p.messagesProcessed,0),o=i.reduce((d,p)=>d+p.throughput,0)/i.length,c=i.reduce((d,p)=>d+p.errorRate,0)/i.length,u=i.reduce((d,p)=>d+p.averageProcessingTime,0)/i.length;return{totalJobsProcessed:i.length,totalMessagesProcessed:s,averageThroughput:o,averageErrorRate:c,averageProcessingTime:u}}optimizeBatchConfig(n){let i=this.configs.get(n);if(!i)throw Error(`Batch config not found: ${n}`);let s=this.getBatchStatistics(n);if(s.averageErrorRate<5&&i.batchSize<10)i.batchSize=Math.min(10,i.batchSize+1);if(s.averageErrorRate>20&&i.batchSize>1)i.batchSize=Math.max(1,i.batchSize-1);if(s.averageThroughput<5&&i.parallelProcessors<20)i.parallelProcessors++;return i}getConfig(n){return this.configs.get(n)}listConfigs(){return Array.from(this.configs.values())}getJob(n){return this.jobs.get(n)}listJobs(n){let i=Array.from(this.jobs.values());if(n)i=i.filter((s)=>s.configId===n);return i}generateBatchProcessorCF(n){return{Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:`arn:aws:sqs:us-east-1:123456789012:${n.queueUrl.split("/").pop()}`,FunctionName:"batch-processor-function",BatchSize:n.batchSize,MaximumBatchingWindowInSeconds:n.maxWaitTime/1000,FunctionResponseTypes:["ReportBatchItemFailures"]}}}clear(){this.configs.clear(),this.jobs.clear(),this.metrics.clear(),this.configCounter=0,this.jobCounter=0,this.metricsCounter=0}}var wE=new Df;class Pf{queues=new Map;retentionPolicies=new Map;delayQueues=new Map;purgeOperations=new Map;metrics=new Map;queueCounter=0;retentionCounter=0;delayCounter=0;purgeCounter=0;metricsCounter=0;createQueue(n){let i=`queue-${Date.now()}-${this.queueCounter++}`,s={id:i,purgeInProgress:!1,...n};return this.queues.set(i,s),s}createStandardQueue(n){return this.createQueue({queueUrl:`https://sqs.us-east-1.amazonaws.com/123456789012/${n.queueName}`,queueName:n.queueName,messageRetentionPeriod:(n.messageRetentionDays||4)*24*60*60,delaySeconds:0,maximumMessageSize:262144,receiveMessageWaitTime:0})}createLongPollingQueue(n){return this.createQueue({queueUrl:`https://sqs.us-east-1.amazonaws.com/123456789012/${n.queueName}`,queueName:n.queueName,messageRetentionPeriod:345600,delaySeconds:0,maximumMessageSize:262144,receiveMessageWaitTime:n.waitTimeSeconds||20})}createRetentionPolicy(n){let i=`retention-${Date.now()}-${this.retentionCounter++}`,s={id:i,...n};this.retentionPolicies.set(i,s);let o=this.queues.get(n.queueId);if(o)o.messageRetentionPeriod=n.retentionPeriod;return s}createShortRetentionPolicy(n){return this.createRetentionPolicy({queueId:n.queueId,retentionPeriod:n.retentionHours*60*60,autoCleanup:!0,archiveExpiredMessages:!1})}createArchivalRetentionPolicy(n){return this.createRetentionPolicy({queueId:n.queueId,retentionPeriod:n.retentionDays*24*60*60,autoCleanup:!0,cleanupSchedule:"cron(0 0 * * ? *)",archiveExpiredMessages:!0,archiveS3Bucket:n.s3Bucket})}createDelayQueue(n){let i=`delay-${Date.now()}-${this.delayCounter++}`,s={id:i,...n};this.delayQueues.set(i,s);let o=Array.from(this.queues.values()).find((c)=>c.queueUrl===n.queueUrl);if(o)o.delaySeconds=n.defaultDelay;return s}createScheduledDelayQueue(n){return this.createDelayQueue({queueUrl:n.queueUrl,defaultDelay:n.delayMinutes*60,perMessageDelay:!1,maxDelay:900})}async purgeQueue(n){let i=this.queues.get(n);if(!i)throw Error(`Queue not found: ${n}`);if(i.purgeInProgress)throw Error("Purge already in progress for this queue");let s=`purge-${Date.now()}-${this.purgeCounter++}`,o={id:s,queueUrl:i.queueUrl,status:"in_progress",startedAt:new Date};return this.purgeOperations.set(s,o),i.purgeInProgress=!0,setTimeout(()=>{o.status="completed",o.completedAt=new Date,o.messagesPurged=Math.floor(Math.random()*1000),i.purgeInProgress=!1},100),o}collectQueueMetrics(n){let s={id:`metrics-${Date.now()}-${this.metricsCounter++}`,queueUrl:n,timestamp:new Date,approximateNumberOfMessages:Math.floor(Math.random()*1000),approximateNumberOfMessagesNotVisible:Math.floor(Math.random()*100),approximateNumberOfMessagesDelayed:Math.floor(Math.random()*50),oldestMessageAge:Math.floor(Math.random()*86400)},o=this.metrics.get(n)||[];return o.push(s),this.metrics.set(n,o),s}getQueueHealth(n){let i=this.metrics.get(n)||[];if(i.length===0)return{status:"healthy",issues:[],recommendations:[]};let s=i[i.length-1],o=[],c=[],u="healthy";if(s.approximateNumberOfMessages>1e4)u="critical",o.push("Large message backlog detected"),c.push("Increase consumer capacity");else if(s.approximateNumberOfMessages>1000)u="warning",o.push("Growing message backlog"),c.push("Monitor consumer performance");if(s.oldestMessageAge&&s.oldestMessageAge>3600){if(u!=="critical")u="warning";o.push("Old messages in queue"),c.push("Review message processing")}if(s.approximateNumberOfMessagesDelayed>100){if(u!=="critical")u="warning";o.push("High number of delayed messages")}return{status:u,issues:o,recommendations:c}}getQueue(n){return this.queues.get(n)}listQueues(){return Array.from(this.queues.values())}getRetentionPolicy(n){return this.retentionPolicies.get(n)}listRetentionPolicies(){return Array.from(this.retentionPolicies.values())}getPurgeOperations(n){let i=Array.from(this.purgeOperations.values());if(n)i=i.filter((s)=>s.queueUrl===n);return i}generateQueueCF(n){return{Type:"AWS::SQS::Queue",Properties:{QueueName:n.queueName,MessageRetentionPeriod:n.messageRetentionPeriod,DelaySeconds:n.delaySeconds,MaximumMessageSize:n.maximumMessageSize,ReceiveMessageWaitTimeSeconds:n.receiveMessageWaitTime}}}generateCleanupRuleCF(n){return{Type:"AWS::Events::Rule",Properties:{Name:`${n.id}-cleanup`,Description:"Automated queue cleanup",ScheduleExpression:n.cleanupSchedule||"cron(0 0 * * ? *)",State:"ENABLED",Targets:[{Arn:"arn:aws:lambda:us-east-1:123456789012:function:queue-cleanup",Id:n.id,Input:JSON.stringify({queueId:n.queueId,archiveBucket:n.archiveS3Bucket})}]}}}clear(){this.queues.clear(),this.retentionPolicies.clear(),this.delayQueues.clear(),this.purgeOperations.clear(),this.metrics.clear(),this.queueCounter=0,this.retentionCounter=0,this.delayCounter=0,this.purgeCounter=0,this.metricsCounter=0}}var RE=new Pf;import{deflateRawSync as Mi}from"node:zlib";var Li=(()=>{let n=[];for(let i=0;i<256;i++){let s=i;for(let o=0;o<8;o++)s=s&1?3988292384^s>>>1:s>>>1;n[i]=s>>>0}return n})();function Oi(n){let i=4294967295;for(let s=0;s<n.length;s++)i=Li[(i^n[s])&255]^i>>>8;return(i^4294967295)>>>0}function $i(n){if(typeof n==="string")return Buffer.from(n,"utf-8");if(Buffer.isBuffer(n))return n;return Buffer.from(n)}function Bi(n){let i=Math.max(1980,n.getFullYear()),s=(n.getHours()<<11|n.getMinutes()<<5|n.getSeconds()>>1)&65535,o=(i-1980<<9|n.getMonth()+1<<5|n.getDate())&65535;return{time:s,date:o}}function rt(n){let i=[],s=[],o=0;for(let d of n){let p=$i(d.data),y=Mi(p),h=Oi(p),b=Buffer.from(d.name.replace(/\\/g,"/"),"utf-8"),{time:v,date:A}=Bi(d.date??new Date(0)),T=d.mode??420,R=Buffer.alloc(30+b.length);R.writeUInt32LE(67324752,0),R.writeUInt16LE(20,4),R.writeUInt16LE(0,6),R.writeUInt16LE(8,8),R.writeUInt16LE(v,10),R.writeUInt16LE(A,12),R.writeUInt32LE(h,14),R.writeUInt32LE(y.length,18),R.writeUInt32LE(p.length,22),R.writeUInt16LE(b.length,26),R.writeUInt16LE(0,28),b.copy(R,30);let P=Buffer.alloc(46+b.length);P.writeUInt32LE(33639248,0),P.writeUInt16LE(798,4),P.writeUInt16LE(20,6),P.writeUInt16LE(0,8),P.writeUInt16LE(8,10),P.writeUInt16LE(v,12),P.writeUInt16LE(A,14),P.writeUInt32LE(h,16),P.writeUInt32LE(y.length,20),P.writeUInt32LE(p.length,24),P.writeUInt16LE(b.length,28),P.writeUInt16LE(0,30),P.writeUInt16LE(0,32),P.writeUInt16LE(0,34),P.writeUInt16LE(0,36),P.writeUInt32LE((T&65535)<<16,38),P.writeUInt32LE(o,42),b.copy(P,46),i.push(R,y),s.push(P),o+=R.length+y.length}let c=Buffer.concat(s),u=Buffer.alloc(22);return u.writeUInt32LE(101010256,0),u.writeUInt16LE(0,4),u.writeUInt16LE(0,6),u.writeUInt16LE(n.length,8),u.writeUInt16LE(n.length,10),u.writeUInt32LE(c.length,12),u.writeUInt32LE(o,16),u.writeUInt16LE(0,20),Buffer.concat([...i,c,u])}function kf(n){let i=n.adapterImport??"./adapter",s=n.entryImport.replace(/\\/g,"/");return`// Generated by ts-cloud — serverless app bootstrap. Do not edit.
7230
7230
  import * as __userModule from ${JSON.stringify(s)}
7231
7231
  import { resolveApp, createHandlers } from ${JSON.stringify(i)}
7232
7232
 
@@ -7236,9 +7236,9 @@ const __handlers = createHandlers(__app)
7236
7236
  export const http = __handlers.http
7237
7237
  export const queue = __handlers.queue
7238
7238
  export const cli = __handlers.cli
7239
- `}import{execSync as Fi}from"node:child_process";import{createHash as Gi}from"node:crypto";import{cpSync as _i,mkdtempSync as Wi,rmSync as Vi,writeFileSync as Ui}from"node:fs";import{tmpdir as Hi}from"node:os";import{dirname as ji,isAbsolute as Ki,join as Fe,resolve as qi}from"node:path";import{fileURLToPath as zi}from"node:url";var Qi=["adapter.ts","recursion.ts","auto-recursion.ts"];function na(){return Fe(ji(zi(import.meta.url)),"runtime")}function dS(n,i,s){for(let o of n??[])s?.(`build: ${o}`),Fi(o,{stdio:"inherit",cwd:i})}function Ko(n){return Gi("sha256").update(n).digest("hex")}function $l(n,i,s){return`deployments/${n}/${i}/${s}.zip`}async function pn(n){let i=qi(n.projectRoot??process.cwd()),{app:s}=n;if(!n.skipBuild)dS(s.build,i,n.onStep);let o=s.entry;if(!o)throw Error("serverless app: `entry` is required to package a Node/Bun application");let c=Ki(o)?o:Fe(i,o),u=Wi(Fe(Hi(),"tscloud-pkg-"));try{for(let A of Qi)_i(Fe(na(),A),Fe(u,A));let d=Fe(u,"bootstrap.ts");Ui(d,Pf({entryImport:c,adapterImport:"./adapter"})),n.onStep?.("bundling application");let p=await Bun.build({entrypoints:[d],target:s.kind==="bun"?"bun":"node",format:"esm",minify:!1,sourcemap:"none"});if(!p.success){let A=p.logs.map((T)=>String(T)).join(`
7239
+ `}import{execSync as Fi}from"node:child_process";import{createHash as Gi}from"node:crypto";import{cpSync as _i,mkdtempSync as Wi,rmSync as Vi,writeFileSync as Ui}from"node:fs";import{tmpdir as Hi}from"node:os";import{dirname as ji,isAbsolute as Ki,join as Fe,resolve as qi}from"node:path";import{fileURLToPath as zi}from"node:url";var Qi=["adapter.ts","recursion.ts","auto-recursion.ts"];function na(){return Fe(ji(zi(import.meta.url)),"runtime")}function lS(n,i,s){for(let o of n??[])s?.(`build: ${o}`),Fi(o,{stdio:"inherit",cwd:i})}function Ko(n){return Gi("sha256").update(n).digest("hex")}function $l(n,i,s){return`deployments/${n}/${i}/${s}.zip`}async function pn(n){let i=qi(n.projectRoot??process.cwd()),{app:s}=n;if(!n.skipBuild)lS(s.build,i,n.onStep);let o=s.entry;if(!o)throw Error("serverless app: `entry` is required to package a Node/Bun application");let c=Ki(o)?o:Fe(i,o),u=Wi(Fe(Hi(),"tscloud-pkg-"));try{for(let A of Qi)_i(Fe(na(),A),Fe(u,A));let d=Fe(u,"bootstrap.ts");Ui(d,kf({entryImport:c,adapterImport:"./adapter"})),n.onStep?.("bundling application");let p=await Bun.build({entrypoints:[d],target:s.kind==="bun"?"bun":"node",format:"esm",minify:!1,sourcemap:"none"});if(!p.success){let A=p.logs.map((T)=>String(T)).join(`
7240
7240
  `);throw Error(`serverless app bundle failed:
7241
- ${A}`)}let y=p.outputs[0],h=Buffer.from(await y.arrayBuffer()),b="index",v=rt([{name:`${b}.mjs`,data:h}]);return{zip:v,bundle:h,sha256:Ko(v),handlerFile:b,handlers:{http:s.handlers?.http??`${b}.http`,queue:s.handlers?.queue??`${b}.queue`,cli:s.handlers?.cli??`${b}.cli`},bundleBytes:h.length}}finally{Vi(u,{recursive:!0,force:!0})}}var lS=["18","20","22"];function ia(n){if(!n)return"22";let i=String(n).match(/(\d+)/);return i?i[1]:"22"}function ns(n){let i=n.kind??"node";if(i==="php")return{lambdaRuntime:"provided.al2023",kind:"php",version:n.phpVersion??"8.3",usesLayer:!0,layerKind:"php",layerEnvVar:"TSCLOUD_PHP_LAYER_ARN"};if(i==="bun")return{lambdaRuntime:"provided.al2023",kind:"bun",version:n.runtimeVersion??"latest",usesLayer:!0,layerKind:"bun",layerEnvVar:"TSCLOUD_BUN_LAYER_ARN"};let s=ia(n.runtimeVersion);if(n.runtime!=="provided.al2023"&&lS.includes(s))return{lambdaRuntime:n.runtime&&n.runtime.startsWith("nodejs")?n.runtime:`nodejs${s}.x`,kind:"node",version:s,usesLayer:!1};return{lambdaRuntime:"provided.al2023",kind:"node",version:s,usesLayer:!0,layerKind:"node",layerEnvVar:"TSCLOUD_NODE_LAYER_ARN"}}function hr(n,i,s){if(n.queues===!1)return[];if(n.queues===void 0||n.queues===!0)return[{name:`${i}-${s}-default`}];return n.queues.map((o)=>{if(typeof o==="string")return{name:`${i}-${s}-${o}`};let[c,u]=Object.entries(o)[0];return{name:`${i}-${s}-${c}`,concurrency:u}})}function Ml(n,i,s){return hr(n,i,s).map((o)=>o.name)}function Fl(n){let{app:i,environment:s,handlers:o}=n,c=n.config.project.slug,u=ns(i).lambdaRuntime,d=i.architecture??"x86_64",p=n.config.project.region,y={http:`${c}-${s}-http`,queue:`${c}-${s}-queue`,cli:`${c}-${s}-cli`};if(i.gatewayVersion===1)throw Error("serverless app: `gatewayVersion: 1` (REST API) is not supported — ts-cloud uses API Gateway HTTP API (v2). Remove `gatewayVersion` or set it to 2.");let h=hr(i,c,s),b=h.map((G)=>G.name),v=b.length>0,A=i.logRetention??14,T=i.packaging==="image";if(T&&i.lambdaInsights)throw Error("serverless app: `lambdaInsights` layer attachment is only supported for zip packaging. Container images must install the Lambda Insights extension in the image.");let R=(i.scheduler??"on")!=="off",P=(i.cache?.driver??"dynamodb")==="dynamodb",I=Boolean(i.assets),M=Xi(c,s),L=i.tmpStorage??512,N={},O={},B=[{PolicyName:"tscloud-serverless-app",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],Resource:e.sub("arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*")},{Effect:"Allow",Action:["lambda:InvokeFunction"],Resource:e.sub(`arn:aws:lambda:\${AWS::Region}:\${AWS::AccountId}:function:${c}-${s}-*`)},{Effect:"Allow",Action:["secretsmanager:GetSecretValue","ssm:GetParameter","ssm:GetParameters","ssm:GetParametersByPath"],Resource:[e.sub(`arn:aws:secretsmanager:\${AWS::Region}:\${AWS::AccountId}:secret:${c}/${s}/*`),e.sub(`arn:aws:ssm:\${AWS::Region}:\${AWS::AccountId}:parameter/${c}/${s}/*`)]},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucket"],Resource:[e.sub(`arn:aws:s3:::${M}`),e.sub(`arn:aws:s3:::${M}/*`),...i.storage?.bucket?[e.sub(`arn:aws:s3:::${i.storage.bucket}`),e.sub(`arn:aws:s3:::${i.storage.bucket}/*`)]:[]]}]}}];if(v)B[0].PolicyDocument.Statement.push({Effect:"Allow",Action:["sqs:SendMessage","sqs:ReceiveMessage","sqs:DeleteMessage","sqs:GetQueueAttributes","sqs:GetQueueUrl"],Resource:e.sub(`arn:aws:sqs:\${AWS::Region}:\${AWS::AccountId}:${c}-${s}-*`)});if(P)B[0].PolicyDocument.Statement.push({Effect:"Allow",Action:["dynamodb:GetItem","dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:DeleteItem","dynamodb:Query","dynamodb:Scan","dynamodb:BatchGetItem","dynamodb:BatchWriteItem"],Resource:e.sub(`arn:aws:dynamodb:\${AWS::Region}:\${AWS::AccountId}:table/${c}-${s}-cache*`)});let F=["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"];if(i.vpc?.subnets?.length)F.push("arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole");if(i.lambdaInsights)F.push("arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy");N.AppRole={Type:"AWS::IAM::Role",Properties:{RoleName:`${c}-${s}-app-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:F,Policies:B}};let U=(G)=>({TSCLOUD_LAMBDA_MODE:G,TSCLOUD_ENV:s,...i.octane?{TSCLOUD_OCTANE:"1"}:{},...i.scheduler==="sub-minute"?{TSCLOUD_SCHEDULER:"sub-minute"}:{},...P?{TSCLOUD_CACHE_TABLE:`${c}-${s}-cache`}:{},...v?{TSCLOUD_QUEUE:b[0]}:{},...i.env??{}}),j=Boolean(i.efs),H=typeof i.efs==="object"?i.efs:{},z=H.mountPath??"/mnt/local",ae=j&&!H.accessPointArn,Te=H.accessPointArn??(ae?e.getAtt("EfsAccessPoint","Arn"):void 0),oe=i.vpc?.subnets??[],pe=oe.length>0,se=i.cache?.driver==="elasticache"||i.database?.connection==="aurora-serverless"||Boolean(i.rdsProxy)||j;if(se&&!pe)throw Error("serverless app: elasticache / aurora-serverless / rdsProxy / efs require app.vpc.subnets (private subnets) to be set.");let me=pe?{VpcConfig:{SubnetIds:oe,SecurityGroupIds:[...i.vpc?.securityGroups??[],...se?[e.getAtt("DataSecurityGroup","GroupId")]:[]]}}:{},Ie=ae?oe.map((G,ne)=>`EfsMountTarget${ne}`):[],Le=j?{FileSystemConfigs:[{Arn:Te,LocalMountPath:z}]}:{};if(j)B[0].PolicyDocument.Statement.push({Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:ClientRootAccess","elasticfilesystem:DescribeMountTargets"],Resource:"*"});function fe(G,ne,ie,re,ye,ht,Ve,Ne=L){N[`${G}LogGroup`]={Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:`/aws/lambda/${ne}`,RetentionInDays:A}};let Ue=[...n.runtimeLayers??[],...i.lambdaInsights?[i.lambdaInsights.layerArn]:[]],en=T?{PackageType:"Image",Code:{ImageUri:e.ref("ImageUri")},...i.kind==="php"?{}:{ImageConfig:{Command:[ie]}}}:{Runtime:u,Handler:ie,Code:{S3Bucket:e.ref("ArtifactBucket"),S3Key:e.ref("ArtifactKey")},...Ue.length?{Layers:[...new Set(Ue)]}:{}};N[G]={Type:"AWS::Lambda::Function",DependsOn:[`${G}LogGroup`,...Ie],Properties:{FunctionName:ne,Architectures:[d],MemorySize:ye,Timeout:ht,Role:e.getAtt("AppRole","Arn"),Environment:{Variables:U(re)},EphemeralStorage:{Size:Ne},...en,...Ve!==void 0?{ReservedConcurrentExecutions:Ve}:{},...me,...Le}}}if(fe("HttpFunction",y.http,o.http,"http",i.memory??1024,i.timeout??28,i.concurrency,L),fe("CliFunction",y.cli,o.cli,"cli",i.cliMemory??1024,i.cliTimeout??900,void 0,i.cliTmpStorage??L),v)fe("QueueFunction",y.queue,o.queue,"queue",i.queueMemory??1024,i.queueTimeout??120,void 0,i.queueTmpStorage??L);let ge=(i.provisionedConcurrency??0)>0?i.provisionedConcurrency:0,he=["HttpFunction","CliFunction",...v?["QueueFunction"]:[]];if(ge)for(let G of he)N[`${G}Version`]={Type:"AWS::Lambda::Version",DeletionPolicy:"Retain",Properties:{FunctionName:e.ref(G)}},N[`${G}Alias`]={Type:"AWS::Lambda::Alias",Properties:{FunctionName:e.ref(G),Name:"live",FunctionVersion:e.getAtt(`${G}Version`,"Version"),ProvisionedConcurrencyConfig:{ProvisionedConcurrentExecutions:ge}}};let De=(G)=>ge?e.ref(`${G}Alias`):e.getAtt(G,"Arn"),Se=(G)=>ge?e.ref(`${G}Alias`):e.ref(G);N.HttpApi={Type:"AWS::ApiGatewayV2::Api",Properties:{Name:`${c}-${s}`,ProtocolType:"HTTP"}},N.HttpIntegration={Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:e.ref("HttpApi"),IntegrationType:"AWS_PROXY",IntegrationUri:De("HttpFunction"),PayloadFormatVersion:"2.0"}},N.HttpRoute={Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:e.ref("HttpApi"),RouteKey:"$default",Target:e.join("/",["integrations",e.ref("HttpIntegration")])}},N.HttpStage={Type:"AWS::ApiGatewayV2::Stage",Properties:{ApiId:e.ref("HttpApi"),StageName:"$default",AutoDeploy:!0}},N.HttpPermission={Type:"AWS::Lambda::Permission",Properties:{FunctionName:Se("HttpFunction"),Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:e.sub("arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${HttpApi}/*/*")}},O.HttpApiEndpoint={Description:"HTTP API endpoint",Value:e.getAtt("HttpApi","ApiEndpoint")},O.HttpApiId={Description:"HTTP API id",Value:e.ref("HttpApi")};let Re=(Array.isArray(i.domain)?i.domain:i.domain?[i.domain]:[]).filter(Boolean);if(Re.length){if(!i.certificateArn&&!i.hostedZoneId)throw Error("serverless app: a custom `domain` needs either `certificateArn` (pre-issued, regional) or `hostedZoneId` (to auto-issue + validate an ACM cert).");let G=i.certificateArn;if(!G)N.HttpCertificate={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:Re[0],...Re.length>1?{SubjectAlternativeNames:Re.slice(1)}:{},ValidationMethod:"DNS",DomainValidationOptions:Re.map((ne)=>({DomainName:ne,HostedZoneId:i.hostedZoneId}))}},G=e.ref("HttpCertificate");Re.forEach((ne,ie)=>{let re=`HttpDomain${ie}`;if(N[re]={Type:"AWS::ApiGatewayV2::DomainName",Properties:{DomainName:ne,DomainNameConfigurations:[{CertificateArn:G,EndpointType:"REGIONAL"}]}},N[`HttpApiMapping${ie}`]={Type:"AWS::ApiGatewayV2::ApiMapping",DependsOn:["HttpStage"],Properties:{ApiId:e.ref("HttpApi"),DomainName:e.ref(re),Stage:"$default"}},i.hostedZoneId)N[`HttpDomainRecord${ie}`]={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i.hostedZoneId,Name:ne,Type:"A",AliasTarget:{DNSName:e.getAtt(re,"RegionalDomainName"),HostedZoneId:e.getAtt(re,"RegionalHostedZoneId")}}};O[`CustomDomain${ie}`]={Description:`Custom domain ${ne}`,Value:ne},O[`CustomDomainTarget${ie}`]={Description:`Point ${ne} (CNAME/alias) at this APIGW regional domain`,Value:e.getAtt(re,"RegionalDomainName")}})}if(v)N.AppQueueDlq={Type:"AWS::SQS::Queue",Properties:{QueueName:`${c}-${s}-dlq`,MessageRetentionPeriod:1209600}},h.forEach((G,ne)=>{let ie=`AppQueue${ne}`,re=i.queueTimeout??120;N[ie]={Type:"AWS::SQS::Queue",Properties:{QueueName:G.name,VisibilityTimeout:Math.min(43200,re*6),RedrivePolicy:{deadLetterTargetArn:e.getAtt("AppQueueDlq","Arn"),maxReceiveCount:i.queueTries??3}}};let ye=G.concurrency??i.queueConcurrency;N[`${ie}Mapping`]={Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:e.getAtt(ie,"Arn"),FunctionName:Se("QueueFunction"),BatchSize:1,FunctionResponseTypes:["ReportBatchItemFailures"],...ye?{ScalingConfig:{MaximumConcurrency:Math.max(2,ye)}}:{}}},O[`QueueUrl${ne}`]={Description:`Queue URL: ${G.name}`,Value:e.ref(ie)}});if(R)N.SchedulerRule={Type:"AWS::Events::Rule",Properties:{Name:`${c}-${s}-scheduler`,ScheduleExpression:"rate(1 minute)",State:"ENABLED",Targets:[{Id:"cli",Arn:De("CliFunction"),Input:JSON.stringify({command:"schedule:run"})}]}},N.SchedulerPermission={Type:"AWS::Lambda::Permission",Properties:{FunctionName:Se("CliFunction"),Action:"lambda:InvokeFunction",Principal:"events.amazonaws.com",SourceArn:e.getAtt("SchedulerRule","Arn")}};if(i.warm&&i.warm>0){let ne={http:"HttpFunction",queue:"QueueFunction",cli:"CliFunction"},ie=(i.warmFunctions??["http"]).filter((re)=>re!=="queue"||v);for(let re of ie){let ye=re.charAt(0).toUpperCase()+re.slice(1),ht=Math.ceil(i.warm/5),Ve=0;for(let Ne=0;Ne<ht;Ne++){let Ue=Math.min(5,i.warm-Ve);N[`Warmer${ye}Rule${Ne}`]={Type:"AWS::Events::Rule",Properties:{Name:`${c}-${s}-warmer-${re}-${Ne}`,ScheduleExpression:"rate(5 minutes)",State:"ENABLED",Targets:Array.from({length:Ue},(en,ar)=>({Id:`warm-${re}-${Ne}-${ar}`,Arn:e.getAtt(ne[re],"Arn"),Input:JSON.stringify({warmer:!0})}))}},Ve+=Ue}N[`Warmer${ye}Permission`]={Type:"AWS::Lambda::Permission",Properties:{FunctionName:e.ref(ne[re]),Action:"lambda:InvokeFunction",Principal:"events.amazonaws.com",SourceArn:e.sub(`arn:aws:events:\${AWS::Region}:\${AWS::AccountId}:rule/${c}-${s}-warmer-${re}-*`)}}}}if(P)N.CacheTable={Type:"AWS::DynamoDB::Table",Properties:{TableName:`${c}-${s}-cache`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"key",AttributeType:"S"}],KeySchema:[{AttributeName:"key",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"expires_at",Enabled:!0}}},O.CacheTableName={Description:"DynamoDB cache table",Value:e.ref("CacheTable")};if(I){if(N.AssetsBucket={Type:"AWS::S3::Bucket",Properties:{BucketName:M,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0}}},N.AssetsOAC={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${c}-${s}-assets-oac`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},N.AssetsDistribution={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,DefaultCacheBehavior:{TargetOriginId:"assets",ViewerProtocolPolicy:"redirect-to-https",Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"},Origins:[{Id:"assets",DomainName:e.getAtt("AssetsBucket","RegionalDomainName"),OriginAccessControlId:e.ref("AssetsOAC"),S3OriginConfig:{OriginAccessIdentity:""}}],...i.assetDomain?{Aliases:[i.assetDomain],ViewerCertificate:{AcmCertificateArn:i.assetCertificateArn??e.ref("AssetsCertificate"),SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}}:{}}}},i.assetDomain){if(!i.assetCertificateArn){if(!i.hostedZoneId)throw Error("serverless app: `assetDomain` requires either `assetCertificateArn` (a us-east-1 ACM cert) or `hostedZoneId` (to auto-issue + validate one). CloudFront only accepts certs from us-east-1.");if(p!=="us-east-1")throw Error(`serverless app: auto-issuing an asset-domain cert needs a us-east-1 app (CloudFront certs must be us-east-1); this app is in ${p}. Supply a pre-issued us-east-1 \`assetCertificateArn\` instead.`);N.AssetsCertificate={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:i.assetDomain,ValidationMethod:"DNS",DomainValidationOptions:[{DomainName:i.assetDomain,HostedZoneId:i.hostedZoneId}]}}}if(i.hostedZoneId)N.AssetsDomainRecord={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i.hostedZoneId,Name:i.assetDomain,Type:"A",AliasTarget:{DNSName:e.getAtt("AssetsDistribution","DomainName"),HostedZoneId:"Z2FDTNDATAQYW2"}}};O.AssetDomain={Description:"Custom asset CDN host",Value:i.assetDomain}}N.AssetsBucketPolicy={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:e.ref("AssetsBucket"),PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:e.sub(`arn:aws:s3:::${M}/*`),Condition:{StringEquals:{"AWS:SourceArn":e.sub("arn:aws:cloudfront::${AWS::AccountId}:distribution/${AssetsDistribution}")}}}]}}},O.AssetsBucketName={Description:"Assets bucket",Value:e.ref("AssetsBucket")},O.AssetsCdnDomain={Description:"Assets CloudFront domain",Value:e.getAtt("AssetsDistribution","DomainName")}}if(i.firewall?.enabled){let G=[],ne=0;if(i.firewall.rateLimit)G.push({Name:"rate-limit",Priority:ne++,Action:{Block:{}},Statement:{RateBasedStatement:{Limit:i.firewall.rateLimit,AggregateKeyType:"IP"}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${c}-${s}-rate`}});let ie={sqlInjection:"AWSManagedRulesSQLiRuleSet",xss:"AWSManagedRulesCommonRuleSet",common:"AWSManagedRulesCommonRuleSet",botControl:"AWSManagedRulesBotControlRuleSet",ipReputation:"AWSManagedRulesAmazonIpReputationList"};for(let re of i.firewall.rules??[]){let ye=ie[re];if(!ye)continue;G.push({Name:`managed-${re}`,Priority:ne++,OverrideAction:{None:{}},Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:ye}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${c}-${s}-${re}`}})}N.WebAcl={Type:"AWS::WAFv2::WebACL",Properties:{Name:`${c}-${s}-waf`,Scope:"REGIONAL",DefaultAction:{Allow:{}},Rules:G,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${c}-${s}-waf`}}},O.WafAclArn={Description:"WAF web ACL ARN. Attach to a CloudFront distribution fronting the API to enforce (HTTP API v2 stages do not support direct WAF association).",Value:e.getAtt("WebAcl","Arn")}}if(pe&&se){if(!i.vpc?.id)throw Error("serverless app: data services (elasticache / aurora-serverless / rdsProxy / efs) need app.vpc.id (the VPC id) so the managed security group is created in the right VPC.");N.DataSecurityGroup={Type:"AWS::EC2::SecurityGroup",Properties:{VpcId:i.vpc.id,GroupDescription:`${c}-${s} serverless data access`,SecurityGroupIngress:[{IpProtocol:"-1",CidrIp:"10.0.0.0/8"}]}}}if(ae)N.EfsFileSystem={Type:"AWS::EFS::FileSystem",Properties:{Encrypted:!0,FileSystemTags:[{Key:"Name",Value:`${c}-${s}-efs`}]}},oe.forEach((G,ne)=>{N[`EfsMountTarget${ne}`]={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:e.ref("EfsFileSystem"),SubnetId:G,SecurityGroups:[e.getAtt("DataSecurityGroup","GroupId")]}}}),N.EfsAccessPoint={Type:"AWS::EFS::AccessPoint",Properties:{FileSystemId:e.ref("EfsFileSystem"),PosixUser:{Uid:1001,Gid:1001},RootDirectory:{Path:"/lambda",CreationInfo:{OwnerUid:1001,OwnerGid:1001,Permissions:"0755"}}}},O.EfsFileSystemId={Description:"EFS file system id",Value:e.ref("EfsFileSystem")};if(i.cache?.driver==="elasticache")N.CacheSubnetGroup={Type:"AWS::ElastiCache::SubnetGroup",Properties:{Description:`${c}-${s} cache subnets`,SubnetIds:oe}},N.CacheCluster={Type:"AWS::ElastiCache::ReplicationGroup",Properties:{ReplicationGroupId:`${c}-${s}-cache`,ReplicationGroupDescription:`${c}-${s} redis`,Engine:"redis",CacheNodeType:"cache.t4g.micro",NumCacheClusters:1,AutomaticFailoverEnabled:!1,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),SecurityGroupIds:[e.getAtt("DataSecurityGroup","GroupId")],TransitEncryptionEnabled:!1}},O.CacheEndpoint={Description:"Redis primary endpoint",Value:e.getAtt("CacheCluster","PrimaryEndPoint.Address")};if(i.database?.connection==="aurora-serverless")N.DbSubnetGroup={Type:"AWS::RDS::DBSubnetGroup",Properties:{DBSubnetGroupDescription:`${c}-${s} db subnets`,SubnetIds:oe}},N.DbSecret={Type:"AWS::SecretsManager::Secret",Properties:{Name:`${c}/${s}/db`,GenerateSecretString:{SecretStringTemplate:JSON.stringify({username:"app"}),GenerateStringKey:"password",PasswordLength:32,ExcludePunctuation:!0}}},N.DbCluster={Type:"AWS::RDS::DBCluster",Properties:{Engine:"aurora-mysql",EngineMode:"provisioned",DBClusterIdentifier:`${c}-${s}-db`,DatabaseName:"app",MasterUsername:e.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:username}}"),MasterUserPassword:e.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:password}}"),ServerlessV2ScalingConfiguration:{MinCapacity:i.database?.minCapacity??0.5,MaxCapacity:i.database?.maxCapacity??4},DBSubnetGroupName:e.ref("DbSubnetGroup"),VpcSecurityGroupIds:[e.getAtt("DataSecurityGroup","GroupId")]}},N.DbInstance={Type:"AWS::RDS::DBInstance",Properties:{Engine:"aurora-mysql",DBInstanceClass:"db.serverless",DBClusterIdentifier:e.ref("DbCluster")}},O.DbEndpoint={Description:"Aurora cluster endpoint",Value:e.getAtt("DbCluster","Endpoint.Address")};if(i.rdsProxy&&i.database?.connection==="aurora-serverless")N.DbProxyRole={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"rds.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"read-db-secret",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue"],Resource:e.ref("DbSecret")}]}}]}},N.DbProxy={Type:"AWS::RDS::DBProxy",Properties:{DBProxyName:typeof i.rdsProxy==="object"&&i.rdsProxy.name?i.rdsProxy.name:`${c}-${s}-proxy`,EngineFamily:"MYSQL",RoleArn:e.getAtt("DbProxyRole","Arn"),Auth:[{AuthScheme:"SECRETS",SecretArn:e.ref("DbSecret"),IAMAuth:"DISABLED"}],VpcSubnetIds:oe,VpcSecurityGroupIds:[e.getAtt("DataSecurityGroup","GroupId")],RequireTLS:!1}},N.DbProxyTargetGroup={Type:"AWS::RDS::DBProxyTargetGroup",DependsOn:["DbInstance"],Properties:{DBProxyName:e.ref("DbProxy"),TargetGroupName:"default",DBClusterIdentifiers:[e.ref("DbCluster")]}},O.DbProxyEndpoint={Description:"RDS Proxy endpoint",Value:e.getAtt("DbProxy","Endpoint")};if(O.HttpFunctionName={Description:"HTTP function name",Value:e.ref("HttpFunction")},O.CliFunctionName={Description:"CLI function name",Value:e.ref("CliFunction")},v)O.QueueFunctionName={Description:"Queue function name",Value:e.ref("QueueFunction")};let $e={AWSTemplateFormatVersion:"2010-09-09",Description:`Serverless application for ${n.config.project.name} (${c}-${s})`,Parameters:T?{ImageUri:{Type:"String",Description:"ECR image URI of the deployment artifact"}}:{ArtifactBucket:{Type:"String",Description:"S3 bucket holding the deployment artifact"},ArtifactKey:{Type:"String",Description:"S3 key of the deployment artifact (zip)"}},Resources:N,Outputs:O},We={};for(let G of Object.values(N))We[G.Type]=(We[G.Type]??0)+1;return{template:$e,functionNames:y,queueNames:b,resourceSummary:We}}var uS=["cli","fpm","curl","mbstring","xml","pdo","mysqlnd","gd","bcmath","intl","opcache","sodium","process","pecl-redis6","pecl-apcu","pgsql"];function gS(n){let i=`php${n.replace(".","")}`;return uS.map((s)=>`${i}-php-${s}`)}function Ul(n,i){let s=`php${n.replace(".","")}`,o=gS(n).join(" \\\n "),c=`/opt/remi/${s}/root`,u=`/etc/opt/remi/${s}`;return`${i?`FROM almalinux:9 AS ${i}`:"FROM almalinux:9"}
7241
+ ${A}`)}let y=p.outputs[0],h=Buffer.from(await y.arrayBuffer()),b="index",v=rt([{name:`${b}.mjs`,data:h}]);return{zip:v,bundle:h,sha256:Ko(v),handlerFile:b,handlers:{http:s.handlers?.http??`${b}.http`,queue:s.handlers?.queue??`${b}.queue`,cli:s.handlers?.cli??`${b}.cli`},bundleBytes:h.length}}finally{Vi(u,{recursive:!0,force:!0})}}var uS=["18","20","22"];function ia(n){if(!n)return"22";let i=String(n).match(/(\d+)/);return i?i[1]:"22"}function ns(n){let i=n.kind??"node";if(i==="php")return{lambdaRuntime:"provided.al2023",kind:"php",version:n.phpVersion??"8.3",usesLayer:!0,layerKind:"php",layerEnvVar:"TSCLOUD_PHP_LAYER_ARN"};if(i==="bun")return{lambdaRuntime:"provided.al2023",kind:"bun",version:n.runtimeVersion??"latest",usesLayer:!0,layerKind:"bun",layerEnvVar:"TSCLOUD_BUN_LAYER_ARN"};let s=ia(n.runtimeVersion);if(n.runtime!=="provided.al2023"&&uS.includes(s))return{lambdaRuntime:n.runtime&&n.runtime.startsWith("nodejs")?n.runtime:`nodejs${s}.x`,kind:"node",version:s,usesLayer:!1};return{lambdaRuntime:"provided.al2023",kind:"node",version:s,usesLayer:!0,layerKind:"node",layerEnvVar:"TSCLOUD_NODE_LAYER_ARN"}}function hr(n,i,s){if(n.queues===!1)return[];if(n.queues===void 0||n.queues===!0)return[{name:`${i}-${s}-default`}];return n.queues.map((o)=>{if(typeof o==="string")return{name:`${i}-${s}-${o}`};let[c,u]=Object.entries(o)[0];return{name:`${i}-${s}-${c}`,concurrency:u}})}function Ml(n,i,s){return hr(n,i,s).map((o)=>o.name)}function Fl(n){let{app:i,environment:s,handlers:o}=n,c=n.config.project.slug,u=ns(i).lambdaRuntime,d=i.architecture??"x86_64",p=n.config.project.region,y={http:`${c}-${s}-http`,queue:`${c}-${s}-queue`,cli:`${c}-${s}-cli`};if(i.gatewayVersion===1)throw Error("serverless app: `gatewayVersion: 1` (REST API) is not supported — ts-cloud uses API Gateway HTTP API (v2). Remove `gatewayVersion` or set it to 2.");let h=hr(i,c,s),b=h.map((G)=>G.name),v=b.length>0,A=i.logRetention??14,T=i.packaging==="image";if(T&&i.lambdaInsights)throw Error("serverless app: `lambdaInsights` layer attachment is only supported for zip packaging. Container images must install the Lambda Insights extension in the image.");let R=(i.scheduler??"on")!=="off",P=(i.cache?.driver??"dynamodb")==="dynamodb",I=Boolean(i.assets),M=Xi(c,s),L=i.tmpStorage??512,N={},O={},B=[{PolicyName:"tscloud-serverless-app",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],Resource:e.sub("arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*")},{Effect:"Allow",Action:["lambda:InvokeFunction"],Resource:e.sub(`arn:aws:lambda:\${AWS::Region}:\${AWS::AccountId}:function:${c}-${s}-*`)},{Effect:"Allow",Action:["secretsmanager:GetSecretValue","ssm:GetParameter","ssm:GetParameters","ssm:GetParametersByPath"],Resource:[e.sub(`arn:aws:secretsmanager:\${AWS::Region}:\${AWS::AccountId}:secret:${c}/${s}/*`),e.sub(`arn:aws:ssm:\${AWS::Region}:\${AWS::AccountId}:parameter/${c}/${s}/*`)]},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucket"],Resource:[e.sub(`arn:aws:s3:::${M}`),e.sub(`arn:aws:s3:::${M}/*`),...i.storage?.bucket?[e.sub(`arn:aws:s3:::${i.storage.bucket}`),e.sub(`arn:aws:s3:::${i.storage.bucket}/*`)]:[]]}]}}];if(v)B[0].PolicyDocument.Statement.push({Effect:"Allow",Action:["sqs:SendMessage","sqs:ReceiveMessage","sqs:DeleteMessage","sqs:GetQueueAttributes","sqs:GetQueueUrl"],Resource:e.sub(`arn:aws:sqs:\${AWS::Region}:\${AWS::AccountId}:${c}-${s}-*`)});if(P)B[0].PolicyDocument.Statement.push({Effect:"Allow",Action:["dynamodb:GetItem","dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:DeleteItem","dynamodb:Query","dynamodb:Scan","dynamodb:BatchGetItem","dynamodb:BatchWriteItem"],Resource:e.sub(`arn:aws:dynamodb:\${AWS::Region}:\${AWS::AccountId}:table/${c}-${s}-cache*`)});let F=["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"];if(i.vpc?.subnets?.length)F.push("arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole");if(i.lambdaInsights)F.push("arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy");N.AppRole={Type:"AWS::IAM::Role",Properties:{RoleName:`${c}-${s}-app-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:F,Policies:B}};let U=(G)=>({TSCLOUD_LAMBDA_MODE:G,TSCLOUD_ENV:s,...i.octane?{TSCLOUD_OCTANE:"1"}:{},...i.scheduler==="sub-minute"?{TSCLOUD_SCHEDULER:"sub-minute"}:{},...P?{TSCLOUD_CACHE_TABLE:`${c}-${s}-cache`}:{},...v?{TSCLOUD_QUEUE:b[0]}:{},...i.env??{}}),j=Boolean(i.efs),H=typeof i.efs==="object"?i.efs:{},z=H.mountPath??"/mnt/local",ae=j&&!H.accessPointArn,Te=H.accessPointArn??(ae?e.getAtt("EfsAccessPoint","Arn"):void 0),oe=i.vpc?.subnets??[],pe=oe.length>0,se=i.cache?.driver==="elasticache"||i.database?.connection==="aurora-serverless"||Boolean(i.rdsProxy)||j;if(se&&!pe)throw Error("serverless app: elasticache / aurora-serverless / rdsProxy / efs require app.vpc.subnets (private subnets) to be set.");let me=pe?{VpcConfig:{SubnetIds:oe,SecurityGroupIds:[...i.vpc?.securityGroups??[],...se?[e.getAtt("DataSecurityGroup","GroupId")]:[]]}}:{},Ie=ae?oe.map((G,ne)=>`EfsMountTarget${ne}`):[],Le=j?{FileSystemConfigs:[{Arn:Te,LocalMountPath:z}]}:{};if(j)B[0].PolicyDocument.Statement.push({Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:ClientRootAccess","elasticfilesystem:DescribeMountTargets"],Resource:"*"});function fe(G,ne,ie,re,ye,ht,Ve,Ne=L){N[`${G}LogGroup`]={Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:`/aws/lambda/${ne}`,RetentionInDays:A}};let Ue=[...n.runtimeLayers??[],...i.lambdaInsights?[i.lambdaInsights.layerArn]:[]],en=T?{PackageType:"Image",Code:{ImageUri:e.ref("ImageUri")},...i.kind==="php"?{}:{ImageConfig:{Command:[ie]}}}:{Runtime:u,Handler:ie,Code:{S3Bucket:e.ref("ArtifactBucket"),S3Key:e.ref("ArtifactKey")},...Ue.length?{Layers:[...new Set(Ue)]}:{}};N[G]={Type:"AWS::Lambda::Function",DependsOn:[`${G}LogGroup`,...Ie],Properties:{FunctionName:ne,Architectures:[d],MemorySize:ye,Timeout:ht,Role:e.getAtt("AppRole","Arn"),Environment:{Variables:U(re)},EphemeralStorage:{Size:Ne},...en,...Ve!==void 0?{ReservedConcurrentExecutions:Ve}:{},...me,...Le}}}if(fe("HttpFunction",y.http,o.http,"http",i.memory??1024,i.timeout??28,i.concurrency,L),fe("CliFunction",y.cli,o.cli,"cli",i.cliMemory??1024,i.cliTimeout??900,void 0,i.cliTmpStorage??L),v)fe("QueueFunction",y.queue,o.queue,"queue",i.queueMemory??1024,i.queueTimeout??120,void 0,i.queueTmpStorage??L);let ge=(i.provisionedConcurrency??0)>0?i.provisionedConcurrency:0,he=["HttpFunction","CliFunction",...v?["QueueFunction"]:[]];if(ge)for(let G of he)N[`${G}Version`]={Type:"AWS::Lambda::Version",DeletionPolicy:"Retain",Properties:{FunctionName:e.ref(G)}},N[`${G}Alias`]={Type:"AWS::Lambda::Alias",Properties:{FunctionName:e.ref(G),Name:"live",FunctionVersion:e.getAtt(`${G}Version`,"Version"),ProvisionedConcurrencyConfig:{ProvisionedConcurrentExecutions:ge}}};let De=(G)=>ge?e.ref(`${G}Alias`):e.getAtt(G,"Arn"),Se=(G)=>ge?e.ref(`${G}Alias`):e.ref(G);N.HttpApi={Type:"AWS::ApiGatewayV2::Api",Properties:{Name:`${c}-${s}`,ProtocolType:"HTTP"}},N.HttpIntegration={Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:e.ref("HttpApi"),IntegrationType:"AWS_PROXY",IntegrationUri:De("HttpFunction"),PayloadFormatVersion:"2.0"}},N.HttpRoute={Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:e.ref("HttpApi"),RouteKey:"$default",Target:e.join("/",["integrations",e.ref("HttpIntegration")])}},N.HttpStage={Type:"AWS::ApiGatewayV2::Stage",Properties:{ApiId:e.ref("HttpApi"),StageName:"$default",AutoDeploy:!0}},N.HttpPermission={Type:"AWS::Lambda::Permission",Properties:{FunctionName:Se("HttpFunction"),Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:e.sub("arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${HttpApi}/*/*")}},O.HttpApiEndpoint={Description:"HTTP API endpoint",Value:e.getAtt("HttpApi","ApiEndpoint")},O.HttpApiId={Description:"HTTP API id",Value:e.ref("HttpApi")};let Re=(Array.isArray(i.domain)?i.domain:i.domain?[i.domain]:[]).filter(Boolean);if(Re.length){if(!i.certificateArn&&!i.hostedZoneId)throw Error("serverless app: a custom `domain` needs either `certificateArn` (pre-issued, regional) or `hostedZoneId` (to auto-issue + validate an ACM cert).");let G=i.certificateArn;if(!G)N.HttpCertificate={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:Re[0],...Re.length>1?{SubjectAlternativeNames:Re.slice(1)}:{},ValidationMethod:"DNS",DomainValidationOptions:Re.map((ne)=>({DomainName:ne,HostedZoneId:i.hostedZoneId}))}},G=e.ref("HttpCertificate");Re.forEach((ne,ie)=>{let re=`HttpDomain${ie}`;if(N[re]={Type:"AWS::ApiGatewayV2::DomainName",Properties:{DomainName:ne,DomainNameConfigurations:[{CertificateArn:G,EndpointType:"REGIONAL"}]}},N[`HttpApiMapping${ie}`]={Type:"AWS::ApiGatewayV2::ApiMapping",DependsOn:["HttpStage"],Properties:{ApiId:e.ref("HttpApi"),DomainName:e.ref(re),Stage:"$default"}},i.hostedZoneId)N[`HttpDomainRecord${ie}`]={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i.hostedZoneId,Name:ne,Type:"A",AliasTarget:{DNSName:e.getAtt(re,"RegionalDomainName"),HostedZoneId:e.getAtt(re,"RegionalHostedZoneId")}}};O[`CustomDomain${ie}`]={Description:`Custom domain ${ne}`,Value:ne},O[`CustomDomainTarget${ie}`]={Description:`Point ${ne} (CNAME/alias) at this APIGW regional domain`,Value:e.getAtt(re,"RegionalDomainName")}})}if(v)N.AppQueueDlq={Type:"AWS::SQS::Queue",Properties:{QueueName:`${c}-${s}-dlq`,MessageRetentionPeriod:1209600}},h.forEach((G,ne)=>{let ie=`AppQueue${ne}`,re=i.queueTimeout??120;N[ie]={Type:"AWS::SQS::Queue",Properties:{QueueName:G.name,VisibilityTimeout:Math.min(43200,re*6),RedrivePolicy:{deadLetterTargetArn:e.getAtt("AppQueueDlq","Arn"),maxReceiveCount:i.queueTries??3}}};let ye=G.concurrency??i.queueConcurrency;N[`${ie}Mapping`]={Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:e.getAtt(ie,"Arn"),FunctionName:Se("QueueFunction"),BatchSize:1,FunctionResponseTypes:["ReportBatchItemFailures"],...ye?{ScalingConfig:{MaximumConcurrency:Math.max(2,ye)}}:{}}},O[`QueueUrl${ne}`]={Description:`Queue URL: ${G.name}`,Value:e.ref(ie)}});if(R)N.SchedulerRule={Type:"AWS::Events::Rule",Properties:{Name:`${c}-${s}-scheduler`,ScheduleExpression:"rate(1 minute)",State:"ENABLED",Targets:[{Id:"cli",Arn:De("CliFunction"),Input:JSON.stringify({command:"schedule:run"})}]}},N.SchedulerPermission={Type:"AWS::Lambda::Permission",Properties:{FunctionName:Se("CliFunction"),Action:"lambda:InvokeFunction",Principal:"events.amazonaws.com",SourceArn:e.getAtt("SchedulerRule","Arn")}};if(i.warm&&i.warm>0){let ne={http:"HttpFunction",queue:"QueueFunction",cli:"CliFunction"},ie=(i.warmFunctions??["http"]).filter((re)=>re!=="queue"||v);for(let re of ie){let ye=re.charAt(0).toUpperCase()+re.slice(1),ht=Math.ceil(i.warm/5),Ve=0;for(let Ne=0;Ne<ht;Ne++){let Ue=Math.min(5,i.warm-Ve);N[`Warmer${ye}Rule${Ne}`]={Type:"AWS::Events::Rule",Properties:{Name:`${c}-${s}-warmer-${re}-${Ne}`,ScheduleExpression:"rate(5 minutes)",State:"ENABLED",Targets:Array.from({length:Ue},(en,ar)=>({Id:`warm-${re}-${Ne}-${ar}`,Arn:e.getAtt(ne[re],"Arn"),Input:JSON.stringify({warmer:!0})}))}},Ve+=Ue}N[`Warmer${ye}Permission`]={Type:"AWS::Lambda::Permission",Properties:{FunctionName:e.ref(ne[re]),Action:"lambda:InvokeFunction",Principal:"events.amazonaws.com",SourceArn:e.sub(`arn:aws:events:\${AWS::Region}:\${AWS::AccountId}:rule/${c}-${s}-warmer-${re}-*`)}}}}if(P)N.CacheTable={Type:"AWS::DynamoDB::Table",Properties:{TableName:`${c}-${s}-cache`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"key",AttributeType:"S"}],KeySchema:[{AttributeName:"key",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"expires_at",Enabled:!0}}},O.CacheTableName={Description:"DynamoDB cache table",Value:e.ref("CacheTable")};if(I){if(N.AssetsBucket={Type:"AWS::S3::Bucket",Properties:{BucketName:M,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0}}},N.AssetsOAC={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${c}-${s}-assets-oac`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},N.AssetsDistribution={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,DefaultCacheBehavior:{TargetOriginId:"assets",ViewerProtocolPolicy:"redirect-to-https",Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"},Origins:[{Id:"assets",DomainName:e.getAtt("AssetsBucket","RegionalDomainName"),OriginAccessControlId:e.ref("AssetsOAC"),S3OriginConfig:{OriginAccessIdentity:""}}],...i.assetDomain?{Aliases:[i.assetDomain],ViewerCertificate:{AcmCertificateArn:i.assetCertificateArn??e.ref("AssetsCertificate"),SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}}:{}}}},i.assetDomain){if(!i.assetCertificateArn){if(!i.hostedZoneId)throw Error("serverless app: `assetDomain` requires either `assetCertificateArn` (a us-east-1 ACM cert) or `hostedZoneId` (to auto-issue + validate one). CloudFront only accepts certs from us-east-1.");if(p!=="us-east-1")throw Error(`serverless app: auto-issuing an asset-domain cert needs a us-east-1 app (CloudFront certs must be us-east-1); this app is in ${p}. Supply a pre-issued us-east-1 \`assetCertificateArn\` instead.`);N.AssetsCertificate={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:i.assetDomain,ValidationMethod:"DNS",DomainValidationOptions:[{DomainName:i.assetDomain,HostedZoneId:i.hostedZoneId}]}}}if(i.hostedZoneId)N.AssetsDomainRecord={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i.hostedZoneId,Name:i.assetDomain,Type:"A",AliasTarget:{DNSName:e.getAtt("AssetsDistribution","DomainName"),HostedZoneId:"Z2FDTNDATAQYW2"}}};O.AssetDomain={Description:"Custom asset CDN host",Value:i.assetDomain}}N.AssetsBucketPolicy={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:e.ref("AssetsBucket"),PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:e.sub(`arn:aws:s3:::${M}/*`),Condition:{StringEquals:{"AWS:SourceArn":e.sub("arn:aws:cloudfront::${AWS::AccountId}:distribution/${AssetsDistribution}")}}}]}}},O.AssetsBucketName={Description:"Assets bucket",Value:e.ref("AssetsBucket")},O.AssetsCdnDomain={Description:"Assets CloudFront domain",Value:e.getAtt("AssetsDistribution","DomainName")}}if(i.firewall?.enabled){let G=[],ne=0;if(i.firewall.rateLimit)G.push({Name:"rate-limit",Priority:ne++,Action:{Block:{}},Statement:{RateBasedStatement:{Limit:i.firewall.rateLimit,AggregateKeyType:"IP"}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${c}-${s}-rate`}});let ie={sqlInjection:"AWSManagedRulesSQLiRuleSet",xss:"AWSManagedRulesCommonRuleSet",common:"AWSManagedRulesCommonRuleSet",botControl:"AWSManagedRulesBotControlRuleSet",ipReputation:"AWSManagedRulesAmazonIpReputationList"};for(let re of i.firewall.rules??[]){let ye=ie[re];if(!ye)continue;G.push({Name:`managed-${re}`,Priority:ne++,OverrideAction:{None:{}},Statement:{ManagedRuleGroupStatement:{VendorName:"AWS",Name:ye}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${c}-${s}-${re}`}})}N.WebAcl={Type:"AWS::WAFv2::WebACL",Properties:{Name:`${c}-${s}-waf`,Scope:"REGIONAL",DefaultAction:{Allow:{}},Rules:G,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${c}-${s}-waf`}}},O.WafAclArn={Description:"WAF web ACL ARN. Attach to a CloudFront distribution fronting the API to enforce (HTTP API v2 stages do not support direct WAF association).",Value:e.getAtt("WebAcl","Arn")}}if(pe&&se){if(!i.vpc?.id)throw Error("serverless app: data services (elasticache / aurora-serverless / rdsProxy / efs) need app.vpc.id (the VPC id) so the managed security group is created in the right VPC.");N.DataSecurityGroup={Type:"AWS::EC2::SecurityGroup",Properties:{VpcId:i.vpc.id,GroupDescription:`${c}-${s} serverless data access`,SecurityGroupIngress:[{IpProtocol:"-1",CidrIp:"10.0.0.0/8"}]}}}if(ae)N.EfsFileSystem={Type:"AWS::EFS::FileSystem",Properties:{Encrypted:!0,FileSystemTags:[{Key:"Name",Value:`${c}-${s}-efs`}]}},oe.forEach((G,ne)=>{N[`EfsMountTarget${ne}`]={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:e.ref("EfsFileSystem"),SubnetId:G,SecurityGroups:[e.getAtt("DataSecurityGroup","GroupId")]}}}),N.EfsAccessPoint={Type:"AWS::EFS::AccessPoint",Properties:{FileSystemId:e.ref("EfsFileSystem"),PosixUser:{Uid:1001,Gid:1001},RootDirectory:{Path:"/lambda",CreationInfo:{OwnerUid:1001,OwnerGid:1001,Permissions:"0755"}}}},O.EfsFileSystemId={Description:"EFS file system id",Value:e.ref("EfsFileSystem")};if(i.cache?.driver==="elasticache")N.CacheSubnetGroup={Type:"AWS::ElastiCache::SubnetGroup",Properties:{Description:`${c}-${s} cache subnets`,SubnetIds:oe}},N.CacheCluster={Type:"AWS::ElastiCache::ReplicationGroup",Properties:{ReplicationGroupId:`${c}-${s}-cache`,ReplicationGroupDescription:`${c}-${s} redis`,Engine:"redis",CacheNodeType:"cache.t4g.micro",NumCacheClusters:1,AutomaticFailoverEnabled:!1,CacheSubnetGroupName:e.ref("CacheSubnetGroup"),SecurityGroupIds:[e.getAtt("DataSecurityGroup","GroupId")],TransitEncryptionEnabled:!1}},O.CacheEndpoint={Description:"Redis primary endpoint",Value:e.getAtt("CacheCluster","PrimaryEndPoint.Address")};if(i.database?.connection==="aurora-serverless")N.DbSubnetGroup={Type:"AWS::RDS::DBSubnetGroup",Properties:{DBSubnetGroupDescription:`${c}-${s} db subnets`,SubnetIds:oe}},N.DbSecret={Type:"AWS::SecretsManager::Secret",Properties:{Name:`${c}/${s}/db`,GenerateSecretString:{SecretStringTemplate:JSON.stringify({username:"app"}),GenerateStringKey:"password",PasswordLength:32,ExcludePunctuation:!0}}},N.DbCluster={Type:"AWS::RDS::DBCluster",Properties:{Engine:"aurora-mysql",EngineMode:"provisioned",DBClusterIdentifier:`${c}-${s}-db`,DatabaseName:"app",MasterUsername:e.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:username}}"),MasterUserPassword:e.sub("{{resolve:secretsmanager:${DbSecret}:SecretString:password}}"),ServerlessV2ScalingConfiguration:{MinCapacity:i.database?.minCapacity??0.5,MaxCapacity:i.database?.maxCapacity??4},DBSubnetGroupName:e.ref("DbSubnetGroup"),VpcSecurityGroupIds:[e.getAtt("DataSecurityGroup","GroupId")]}},N.DbInstance={Type:"AWS::RDS::DBInstance",Properties:{Engine:"aurora-mysql",DBInstanceClass:"db.serverless",DBClusterIdentifier:e.ref("DbCluster")}},O.DbEndpoint={Description:"Aurora cluster endpoint",Value:e.getAtt("DbCluster","Endpoint.Address")};if(i.rdsProxy&&i.database?.connection==="aurora-serverless")N.DbProxyRole={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"rds.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"read-db-secret",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue"],Resource:e.ref("DbSecret")}]}}]}},N.DbProxy={Type:"AWS::RDS::DBProxy",Properties:{DBProxyName:typeof i.rdsProxy==="object"&&i.rdsProxy.name?i.rdsProxy.name:`${c}-${s}-proxy`,EngineFamily:"MYSQL",RoleArn:e.getAtt("DbProxyRole","Arn"),Auth:[{AuthScheme:"SECRETS",SecretArn:e.ref("DbSecret"),IAMAuth:"DISABLED"}],VpcSubnetIds:oe,VpcSecurityGroupIds:[e.getAtt("DataSecurityGroup","GroupId")],RequireTLS:!1}},N.DbProxyTargetGroup={Type:"AWS::RDS::DBProxyTargetGroup",DependsOn:["DbInstance"],Properties:{DBProxyName:e.ref("DbProxy"),TargetGroupName:"default",DBClusterIdentifiers:[e.ref("DbCluster")]}},O.DbProxyEndpoint={Description:"RDS Proxy endpoint",Value:e.getAtt("DbProxy","Endpoint")};if(O.HttpFunctionName={Description:"HTTP function name",Value:e.ref("HttpFunction")},O.CliFunctionName={Description:"CLI function name",Value:e.ref("CliFunction")},v)O.QueueFunctionName={Description:"Queue function name",Value:e.ref("QueueFunction")};let $e={AWSTemplateFormatVersion:"2010-09-09",Description:`Serverless application for ${n.config.project.name} (${c}-${s})`,Parameters:T?{ImageUri:{Type:"String",Description:"ECR image URI of the deployment artifact"}}:{ArtifactBucket:{Type:"String",Description:"S3 bucket holding the deployment artifact"},ArtifactKey:{Type:"String",Description:"S3 key of the deployment artifact (zip)"}},Resources:N,Outputs:O},We={};for(let G of Object.values(N))We[G.Type]=(We[G.Type]??0)+1;return{template:$e,functionNames:y,queueNames:b,resourceSummary:We}}var gS=["cli","fpm","curl","mbstring","xml","pdo","mysqlnd","gd","bcmath","intl","opcache","sodium","process","pecl-redis6","pecl-apcu","pgsql"];function pS(n){let i=`php${n.replace(".","")}`;return gS.map((s)=>`${i}-php-${s}`)}function Ul(n,i){let s=`php${n.replace(".","")}`,o=pS(n).join(" \\\n "),c=`/opt/remi/${s}/root`,u=`/etc/opt/remi/${s}`;return`${i?`FROM almalinux:9 AS ${i}`:"FROM almalinux:9"}
7242
7242
 
7243
7243
  # Build PHP on AlmaLinux 9 (where Remi's version-isolated SCL packages install
7244
7244
  # cleanly — Remi's release RPM rejects Amazon Linux 2023). AlmaLinux 9 shares
@@ -7278,7 +7278,7 @@ RUN printf 'extension_dir=/opt/php/lib/php/modules\\n' > /opt/php/etc/php.ini &&
7278
7278
  # Runtime assets (bootstrap, runtime loops, fpm config) are added by the build
7279
7279
  # orchestrator after the image is produced. Export /opt as the layer payload.
7280
7280
  CMD ["true"]
7281
- `}function kf(n={}){let i=n.phpVersion??"8.3";return`# ts-cloud PHP ${i} runtime layer (generated) — AWS Lambda provided.al2023.
7281
+ `}function Nf(n={}){let i=n.phpVersion??"8.3";return`# ts-cloud PHP ${i} runtime layer (generated) — AWS Lambda provided.al2023.
7282
7282
  ${Ul(i)}`}function Ql(n){if(n.kind==="php"){let s=n.phpVersion??"8.3";return`# ts-cloud serverless PHP app image (generated, multi-stage).
7283
7283
  ${Ul(s,"phpbuild")}
7284
7284
 
@@ -7299,7 +7299,7 @@ COPY app/ \${LAMBDA_TASK_ROOT}/
7299
7299
 
7300
7300
  # Per-function CMD (e.g. index.http) is supplied via ImageConfig.Command.
7301
7301
  CMD [ "index.http" ]
7302
- `}import{execFileSync as pt}from"node:child_process";import{mkdtempSync as jn,readFileSync as gt,rmSync as Kn}from"node:fs";import{tmpdir as qn}from"node:os";import{dirname as aa,join as we}from"node:path";import{fileURLToPath as sa}from"node:url";function zn(){return aa(sa(import.meta.url))}function Nf(){return gt(we(zn(),"runtime.mjs"),"utf-8")}function Qn(n){return gt(we(zn(),`${n}-bootstrap`),"utf-8")}function RE(n){let i=n.architecture??"x86_64",s=i==="arm64"?"arm64":"x64",o=n.version.replace(/^v/,""),c=n.onStep??(()=>{}),u=jn(we(qn(),"tscloud-node-layer-"));try{let d=o.includes(".")?o:oa(o),p=`node-v${d}-linux-${s}`,y=`https://nodejs.org/dist/v${d}/${p}.tar.xz`;c(`downloading Node ${d} (${i})`);let h=we(u,"node.tar.xz");Jn(y,h),c("extracting node binary"),pt("tar",["-xf",h,"-C",u,`${p}/bin/node`],{stdio:"inherit"});let b=gt(we(u,p,"bin","node"));c("packaging layer");let v=[{name:"bootstrap",data:Qn("node"),mode:493},{name:"runtime.mjs",data:Nf(),mode:420},{name:"bin/node",data:b,mode:493}];return{zip:rt(v),architecture:i,version:d,fileCount:v.length}}finally{Kn(u,{recursive:!0,force:!0})}}function DE(n){let i=n.architecture??"x86_64",s=i==="arm64"?"bun-linux-aarch64":"bun-linux-x64",o=n.version==="latest"?"":n.version.replace(/^v/,""),c=n.onStep??(()=>{}),u=jn(we(qn(),"tscloud-bun-layer-"));try{let d=o?`https://github.com/oven-sh/bun/releases/download/bun-v${o}/${s}.zip`:`https://github.com/oven-sh/bun/releases/latest/download/${s}.zip`;c(`downloading Bun ${o||"latest"} (${i})`);let p=we(u,"bun.zip");Jn(d,p),c("extracting bun binary"),pt("unzip",["-o","-q",p,"-d",u],{stdio:"inherit"});let y=gt(we(u,s,"bun"));c("packaging layer");let h=[{name:"bootstrap",data:Qn("bun"),mode:493},{name:"runtime.mjs",data:Nf(),mode:420},{name:"bin/bun",data:y,mode:493}];return{zip:rt(h),architecture:i,version:o||"latest",fileCount:h.length}}finally{Kn(u,{recursive:!0,force:!0})}}function Jn(n,i){pt("curl",["-fsSL","-o",i,n],{stdio:["ignore","ignore","inherit"]})}function oa(n){let i=pt("curl",["-fsSL","https://nodejs.org/dist/index.json"],{encoding:"utf-8"}),o=JSON.parse(i).find((c)=>c.version.startsWith(`v${n}.`));if(!o)throw Error(`No Node release found for major version ${n}`);return o.version.replace(/^v/,"")}import{AsyncLocalStorage as la}from"node:async_hooks";import{createHash as ca}from"node:crypto";var Wo="x-ts-cloud-invoke-depth",Jo="x-ts-cloud-invoke-chain",Xo="x-ts-cloud-trace-id";function Hl(n){return ca("sha256").update(n).digest("hex").slice(0,8)}var mn={maxDepth:10,maxRepeats:3,maxInvocationsPerTrace:100,traceWindowMs:60000,breakerThreshold:5,breakerCooldownMs:60000};function Yt(n,i){if(typeof n.get==="function")return n.get(i)??void 0;let s=n;return s[i]??s[i.toLowerCase()]??s[i.toUpperCase()]}function Gl(n,i=64){if(!n)return[];return n.split(".").map((s)=>s.trim()).filter((s)=>/^[0-9a-f]{8}$/.test(s)).slice(-i)}function Vl(n,i=mn){let s=Hl(n.functionId),o=Gl(Yt(n.headers,Jo)),c=n.traceId??Yt(n.headers,Xo)??crypto.randomUUID(),u=[...o,s],d=o.filter((v)=>v===s).length,p=o[o.length-1]===s,y=Number.parseInt(Yt(n.headers,Wo)??"",10),h=Math.max(u.length,Number.isFinite(y)?y+1:0),b="ok";if(h>i.maxDepth)b="depth_exceeded";else if(d>=i.maxRepeats)b="cycle_detected";else if(p&&i.maxRepeats<=1)b="self_invocation";return{reason:b,depth:h,chain:u,traceId:c,selfInvocation:p,repeats:d,propagate:{[Wo]:String(h),[Jo]:u.join("."),[Xo]:c}}}var Yn={ok:"",depth_exceeded:"Invocation chain is deeper than the configured limit; the call was refused to stop a runaway loop.",cycle_detected:"This function already appears in the invocation chain; the call was refused as a recursion loop.",self_invocation:"This function invoked itself directly; the call was refused.",trace_budget_exceeded:"This request has already made more invocations than its budget allows.",breaker_open:"Recursion protection is open for this function after repeated loop detections."};class is{limits;clock;traces=new Map;breakers=new Map;constructor(n=mn,i=()=>Date.now()){this.limits=n;this.clock=i}check(n){let i=this.clock();this.expireTraces(i);let s=Vl(n,this.limits),o=this.breakers.get(n.functionId);if(o?.openUntil!=null&&o.openUntil>i)return this.deny(n.functionId,s,"breaker_open",i,!1);if(s.reason!=="ok")return this.deny(n.functionId,s,s.reason,i,!0);let c=this.traces.get(s.traceId)??{count:0,firstAt:i};if(c.count>=this.limits.maxInvocationsPerTrace)return this.traces.set(s.traceId,c),this.deny(n.functionId,s,"trace_budget_exceeded",i,!0);if(this.traces.set(s.traceId,{count:c.count+1,firstAt:c.firstAt}),o)this.breakers.set(n.functionId,{consecutiveBlocks:0});return{...s,allowed:!0,reason:"ok",propagate:s.propagate}}deny(n,i,s,o,c){if(c){let u=this.breakers.get(n)??{consecutiveBlocks:0},d=u.consecutiveBlocks+1;this.breakers.set(n,{consecutiveBlocks:d,openUntil:d>=this.limits.breakerThreshold?o+this.limits.breakerCooldownMs:u.openUntil})}return{...i,allowed:!1,reason:s,message:Yn[s]}}breakerOpen(n){let i=this.breakers.get(n);return i?.openUntil!=null&&i.openUntil>this.clock()}reset(n){if(n){this.breakers.delete(n);return}this.breakers.clear(),this.traces.clear()}expireTraces(n){if(this.traces.size===0)return;for(let[i,s]of this.traces)if(n-s.firstAt>this.limits.traceWindowMs)this.traces.delete(i)}get trackedTraces(){return this.traces.size}}function Yo(n){return{...n.propagate}}function Zo(n){return{status:508,headers:{"content-type":"application/json","x-ts-cloud-recursion-blocked":n.reason},body:{error:"recursion_blocked",reason:n.reason,message:n.message??Yn[n.reason],depth:n.depth,traceId:n.traceId}}}var Bf=new la;function Zn(n){let i=globalThis.process?.env?.[n];if(i==null||i==="")return;return i!=="0"&&i.toLowerCase()!=="false"}function ua(){let n=globalThis.process?.env??{};return n.TS_CLOUD_FUNCTION_ID||n.AWS_LAMBDA_FUNCTION_NAME||n.FUNCTION_NAME||"function"}function pS(n){let i=n===!1?{enabled:!1}:n??{},s=Zn("TS_CLOUD_RECURSION_PROTECTION"),o=Zn("TS_CLOUD_RECURSION_DETECTION_ONLY");return{enabled:s??i.enabled??!0,detectionOnly:o??i.detectionOnly??!1,limits:{...mn,...i.limits},functionId:i.functionId??ua()}}var Me,ve;function mS(){let n=globalThis.fetch;if(!n||Me===n)return()=>{};ve=n;let i=async(s,o)=>{let c=Bf.getStore();if(!c)return ve(s,o);let u=new Headers(o?.headers??(s instanceof Request?s.headers:void 0));for(let[d,p]of Object.entries(Yo(c)))u.set(d,p);if(s instanceof Request)return ve(new Request(s,{headers:u}),o);return ve(s,{...o,headers:u})};return Object.assign(i,n),globalThis.fetch=i,Me=i,()=>{if(globalThis.fetch===Me&&ve)globalThis.fetch=ve;Me=void 0}}var yt,Zt;function fS(n){if(!yt||JSON.stringify(Zt)!==JSON.stringify(n))yt=new is(n),Zt=n;return yt}function PE(){if(yt=void 0,Zt=void 0,Me&&ve&&globalThis.fetch===Me)globalThis.fetch=ve;Me=void 0,ve=void 0}function xf(n,i){let s=pS(i);if(!s.enabled)return;let o=fS(s.limits),c={functionId:s.functionId,headers:n},u=o.check(c);return{verdict:u,blocked:!u.allowed&&!s.detectionOnly,observed:!u.allowed&&s.detectionOnly}}function Of(n,i){return mS(),Bf.run(n,i)}function kE(n){let i=n,s=i?.default??i;if(typeof s==="function")return{fetch:s};return{fetch:s?.fetch??i?.fetch,queue:s?.queue??i?.queue,cli:s?.cli??i?.cli}}var da=/^(?:text\/|application\/(?:json|xml|javascript|graphql|x-www-form-urlencoded|.*\+json|.*\+xml)|image\/svg)/i;function ma(n){if(!n)return!0;return da.test(n)}function pa(n){if(n?.maintenance)return n.maintenance;let i=globalThis.process?.env??{};return{enabled:i.MAINTENANCE_MODE==="1"||i.MAINTENANCE_MODE==="true",bypassSecret:i.MAINTENANCE_BYPASS_SECRET}}function hS(n){let i=n.requestContext?.domainName??"localhost",s=n.rawQueryString?`?${n.rawQueryString}`:"",o=`https://${i}${n.rawPath||"/"}${s}`,c=new Headers;for(let[p,y]of Object.entries(n.headers??{}))if(y!==void 0)c.set(p,y);if(n.cookies?.length)c.set("cookie",n.cookies.join("; "));let u=n.requestContext.http.method,d;if(n.body!==void 0&&u!=="GET"&&u!=="HEAD")d=n.isBase64Encoded?new Uint8Array(Buffer.from(n.body,"base64")):new TextEncoder().encode(n.body);return new Request(o,{method:u,headers:c,body:d})}async function _f(n){let i={},s=[],o=typeof n.headers.getSetCookie==="function"?n.headers.getSetCookie():[];for(let d of o)s.push(d);n.headers.forEach((d,p)=>{if(p.toLowerCase()==="set-cookie")return;i[p]=d});let c=Buffer.from(await n.arrayBuffer()),u=ma(n.headers.get("content-type"));return{statusCode:n.status,headers:i,...s.length?{cookies:s}:{},body:u?c.toString("utf-8"):c.toString("base64"),isBase64Encoded:!u}}function AS(n,i){return async(s)=>{if(s.warmer)return{statusCode:200,headers:{"content-type":"text/plain"},body:"warm",isBase64Encoded:!1};if(!n)return{statusCode:501,headers:{"content-type":"text/plain"},body:"No HTTP handler configured",isBase64Encoded:!1};let o=pa(i);if(o.enabled){let d=s.headers?.["x-maintenance-bypass"]??s.cookies?.find((p)=>p.startsWith("tscloud_bypass="))?.split("=")[1];if(!o.bypassSecret||d!==o.bypassSecret)return{statusCode:503,headers:{"content-type":"text/plain","retry-after":"120"},body:"Service temporarily unavailable (maintenance mode)",isBase64Encoded:!1}}let c=xf(s.headers??{},i?.recursionProtection);if(c?.blocked){let d=Zo(c.verdict);return{statusCode:d.status,headers:{...d.headers,"retry-after":"60"},body:JSON.stringify(d.body),isBase64Encoded:!1}}let u=hS(s);if(!c){let d=await n(u);return _f(d)}if(c.observed)console.warn(`[ts-cloud] recursion detected (${c.verdict.reason}) at depth ${c.verdict.depth}; detection-only mode let it run`);return Of(c.verdict,async()=>_f(await n(u)))}}function ga(n){try{return JSON.parse(n)}catch{return n}}function yS(n){return async(i)=>{let s=[];if(i.warmer)return{batchItemFailures:s};if(!n)return{batchItemFailures:s};for(let o of i.Records??[])try{await n(ga(o.body),o)}catch{s.push({itemIdentifier:o.messageId})}return{batchItemFailures:s}}}function SS(n){return async(i)=>{if(i.warmer)return{statusCode:0,output:"warm"};if(!n)return{statusCode:501,output:"No CLI handler configured"};return n(i)}}function NE(n,i){return{http:AS(n.fetch,i),queue:yS(n.queue),cli:SS(n.cli)}}function Lf(n={}){let i=n.socketPath??"/tmp/.tscloud-fpm.sock",s=n.maxChildren??1;return`; ts-cloud php-fpm configuration (generated) — AWS Lambda custom runtime.
7302
+ `}import{execFileSync as pt}from"node:child_process";import{mkdtempSync as jn,readFileSync as gt,rmSync as Kn}from"node:fs";import{tmpdir as qn}from"node:os";import{dirname as aa,join as we}from"node:path";import{fileURLToPath as sa}from"node:url";function zn(){return aa(sa(import.meta.url))}function Bf(){return gt(we(zn(),"runtime.mjs"),"utf-8")}function Qn(n){return gt(we(zn(),`${n}-bootstrap`),"utf-8")}function DE(n){let i=n.architecture??"x86_64",s=i==="arm64"?"arm64":"x64",o=n.version.replace(/^v/,""),c=n.onStep??(()=>{}),u=jn(we(qn(),"tscloud-node-layer-"));try{let d=o.includes(".")?o:oa(o),p=`node-v${d}-linux-${s}`,y=`https://nodejs.org/dist/v${d}/${p}.tar.xz`;c(`downloading Node ${d} (${i})`);let h=we(u,"node.tar.xz");Jn(y,h),c("extracting node binary"),pt("tar",["-xf",h,"-C",u,`${p}/bin/node`],{stdio:"inherit"});let b=gt(we(u,p,"bin","node"));c("packaging layer");let v=[{name:"bootstrap",data:Qn("node"),mode:493},{name:"runtime.mjs",data:Bf(),mode:420},{name:"bin/node",data:b,mode:493}];return{zip:rt(v),architecture:i,version:d,fileCount:v.length}}finally{Kn(u,{recursive:!0,force:!0})}}function PE(n){let i=n.architecture??"x86_64",s=i==="arm64"?"bun-linux-aarch64":"bun-linux-x64",o=n.version==="latest"?"":n.version.replace(/^v/,""),c=n.onStep??(()=>{}),u=jn(we(qn(),"tscloud-bun-layer-"));try{let d=o?`https://github.com/oven-sh/bun/releases/download/bun-v${o}/${s}.zip`:`https://github.com/oven-sh/bun/releases/latest/download/${s}.zip`;c(`downloading Bun ${o||"latest"} (${i})`);let p=we(u,"bun.zip");Jn(d,p),c("extracting bun binary"),pt("unzip",["-o","-q",p,"-d",u],{stdio:"inherit"});let y=gt(we(u,s,"bun"));c("packaging layer");let h=[{name:"bootstrap",data:Qn("bun"),mode:493},{name:"runtime.mjs",data:Bf(),mode:420},{name:"bin/bun",data:y,mode:493}];return{zip:rt(h),architecture:i,version:o||"latest",fileCount:h.length}}finally{Kn(u,{recursive:!0,force:!0})}}function Jn(n,i){pt("curl",["-fsSL","-o",i,n],{stdio:["ignore","ignore","inherit"]})}function oa(n){let i=pt("curl",["-fsSL","https://nodejs.org/dist/index.json"],{encoding:"utf-8"}),o=JSON.parse(i).find((c)=>c.version.startsWith(`v${n}.`));if(!o)throw Error(`No Node release found for major version ${n}`);return o.version.replace(/^v/,"")}import{AsyncLocalStorage as la}from"node:async_hooks";import{createHash as ca}from"node:crypto";var Wo="x-ts-cloud-invoke-depth",Jo="x-ts-cloud-invoke-chain",Xo="x-ts-cloud-trace-id";function Hl(n){return ca("sha256").update(n).digest("hex").slice(0,8)}var mn={maxDepth:10,maxRepeats:3,maxInvocationsPerTrace:100,traceWindowMs:60000,breakerThreshold:5,breakerCooldownMs:60000};function Yt(n,i){if(typeof n.get==="function")return n.get(i)??void 0;let s=n;return s[i]??s[i.toLowerCase()]??s[i.toUpperCase()]}function Gl(n,i=64){if(!n)return[];return n.split(".").map((s)=>s.trim()).filter((s)=>/^[0-9a-f]{8}$/.test(s)).slice(-i)}function Vl(n,i=mn){let s=Hl(n.functionId),o=Gl(Yt(n.headers,Jo)),c=n.traceId??Yt(n.headers,Xo)??crypto.randomUUID(),u=[...o,s],d=o.filter((v)=>v===s).length,p=o[o.length-1]===s,y=Number.parseInt(Yt(n.headers,Wo)??"",10),h=Math.max(u.length,Number.isFinite(y)?y+1:0),b="ok";if(h>i.maxDepth)b="depth_exceeded";else if(d>=i.maxRepeats)b="cycle_detected";else if(p&&i.maxRepeats<=1)b="self_invocation";return{reason:b,depth:h,chain:u,traceId:c,selfInvocation:p,repeats:d,propagate:{[Wo]:String(h),[Jo]:u.join("."),[Xo]:c}}}var Yn={ok:"",depth_exceeded:"Invocation chain is deeper than the configured limit; the call was refused to stop a runaway loop.",cycle_detected:"This function already appears in the invocation chain; the call was refused as a recursion loop.",self_invocation:"This function invoked itself directly; the call was refused.",trace_budget_exceeded:"This request has already made more invocations than its budget allows.",breaker_open:"Recursion protection is open for this function after repeated loop detections."};class is{limits;clock;traces=new Map;breakers=new Map;constructor(n=mn,i=()=>Date.now()){this.limits=n;this.clock=i}check(n){let i=this.clock();this.expireTraces(i);let s=Vl(n,this.limits),o=this.breakers.get(n.functionId);if(o?.openUntil!=null&&o.openUntil>i)return this.deny(n.functionId,s,"breaker_open",i,!1);if(s.reason!=="ok")return this.deny(n.functionId,s,s.reason,i,!0);let c=this.traces.get(s.traceId)??{count:0,firstAt:i};if(c.count>=this.limits.maxInvocationsPerTrace)return this.traces.set(s.traceId,c),this.deny(n.functionId,s,"trace_budget_exceeded",i,!0);if(this.traces.set(s.traceId,{count:c.count+1,firstAt:c.firstAt}),o)this.breakers.set(n.functionId,{consecutiveBlocks:0});return{...s,allowed:!0,reason:"ok",propagate:s.propagate}}deny(n,i,s,o,c){if(c){let u=this.breakers.get(n)??{consecutiveBlocks:0},d=u.consecutiveBlocks+1;this.breakers.set(n,{consecutiveBlocks:d,openUntil:d>=this.limits.breakerThreshold?o+this.limits.breakerCooldownMs:u.openUntil})}return{...i,allowed:!1,reason:s,message:Yn[s]}}breakerOpen(n){let i=this.breakers.get(n);return i?.openUntil!=null&&i.openUntil>this.clock()}reset(n){if(n){this.breakers.delete(n);return}this.breakers.clear(),this.traces.clear()}expireTraces(n){if(this.traces.size===0)return;for(let[i,s]of this.traces)if(n-s.firstAt>this.limits.traceWindowMs)this.traces.delete(i)}get trackedTraces(){return this.traces.size}}function Yo(n){return{...n.propagate}}function Zo(n){return{status:508,headers:{"content-type":"application/json","x-ts-cloud-recursion-blocked":n.reason},body:{error:"recursion_blocked",reason:n.reason,message:n.message??Yn[n.reason],depth:n.depth,traceId:n.traceId}}}var xf=new la;function Zn(n){let i=globalThis.process?.env?.[n];if(i==null||i==="")return;return i!=="0"&&i.toLowerCase()!=="false"}function ua(){let n=globalThis.process?.env??{};return n.TS_CLOUD_FUNCTION_ID||n.AWS_LAMBDA_FUNCTION_NAME||n.FUNCTION_NAME||"function"}function mS(n){let i=n===!1?{enabled:!1}:n??{},s=Zn("TS_CLOUD_RECURSION_PROTECTION"),o=Zn("TS_CLOUD_RECURSION_DETECTION_ONLY");return{enabled:s??i.enabled??!0,detectionOnly:o??i.detectionOnly??!1,limits:{...mn,...i.limits},functionId:i.functionId??ua()}}var Me,ve;function fS(){let n=globalThis.fetch;if(!n||Me===n)return()=>{};ve=n;let i=async(s,o)=>{let c=xf.getStore();if(!c)return ve(s,o);let u=new Headers(o?.headers??(s instanceof Request?s.headers:void 0));for(let[d,p]of Object.entries(Yo(c)))u.set(d,p);if(s instanceof Request)return ve(new Request(s,{headers:u}),o);return ve(s,{...o,headers:u})};return Object.assign(i,n),globalThis.fetch=i,Me=i,()=>{if(globalThis.fetch===Me&&ve)globalThis.fetch=ve;Me=void 0}}var yt,Zt;function hS(n){if(!yt||JSON.stringify(Zt)!==JSON.stringify(n))yt=new is(n),Zt=n;return yt}function kE(){if(yt=void 0,Zt=void 0,Me&&ve&&globalThis.fetch===Me)globalThis.fetch=ve;Me=void 0,ve=void 0}function Of(n,i){let s=mS(i);if(!s.enabled)return;let o=hS(s.limits),c={functionId:s.functionId,headers:n},u=o.check(c);return{verdict:u,blocked:!u.allowed&&!s.detectionOnly,observed:!u.allowed&&s.detectionOnly}}function _f(n,i){return fS(),xf.run(n,i)}function NE(n){let i=n,s=i?.default??i;if(typeof s==="function")return{fetch:s};return{fetch:s?.fetch??i?.fetch,queue:s?.queue??i?.queue,cli:s?.cli??i?.cli}}var da=/^(?:text\/|application\/(?:json|xml|javascript|graphql|x-www-form-urlencoded|.*\+json|.*\+xml)|image\/svg)/i;function ma(n){if(!n)return!0;return da.test(n)}function pa(n){if(n?.maintenance)return n.maintenance;let i=globalThis.process?.env??{};return{enabled:i.MAINTENANCE_MODE==="1"||i.MAINTENANCE_MODE==="true",bypassSecret:i.MAINTENANCE_BYPASS_SECRET}}function AS(n){let i=n.requestContext?.domainName??"localhost",s=n.rawQueryString?`?${n.rawQueryString}`:"",o=`https://${i}${n.rawPath||"/"}${s}`,c=new Headers;for(let[p,y]of Object.entries(n.headers??{}))if(y!==void 0)c.set(p,y);if(n.cookies?.length)c.set("cookie",n.cookies.join("; "));let u=n.requestContext.http.method,d;if(n.body!==void 0&&u!=="GET"&&u!=="HEAD")d=n.isBase64Encoded?new Uint8Array(Buffer.from(n.body,"base64")):new TextEncoder().encode(n.body);return new Request(o,{method:u,headers:c,body:d})}async function Lf(n){let i={},s=[],o=typeof n.headers.getSetCookie==="function"?n.headers.getSetCookie():[];for(let d of o)s.push(d);n.headers.forEach((d,p)=>{if(p.toLowerCase()==="set-cookie")return;i[p]=d});let c=Buffer.from(await n.arrayBuffer()),u=ma(n.headers.get("content-type"));return{statusCode:n.status,headers:i,...s.length?{cookies:s}:{},body:u?c.toString("utf-8"):c.toString("base64"),isBase64Encoded:!u}}function yS(n,i){return async(s)=>{if(s.warmer)return{statusCode:200,headers:{"content-type":"text/plain"},body:"warm",isBase64Encoded:!1};if(!n)return{statusCode:501,headers:{"content-type":"text/plain"},body:"No HTTP handler configured",isBase64Encoded:!1};let o=pa(i);if(o.enabled){let d=s.headers?.["x-maintenance-bypass"]??s.cookies?.find((p)=>p.startsWith("tscloud_bypass="))?.split("=")[1];if(!o.bypassSecret||d!==o.bypassSecret)return{statusCode:503,headers:{"content-type":"text/plain","retry-after":"120"},body:"Service temporarily unavailable (maintenance mode)",isBase64Encoded:!1}}let c=Of(s.headers??{},i?.recursionProtection);if(c?.blocked){let d=Zo(c.verdict);return{statusCode:d.status,headers:{...d.headers,"retry-after":"60"},body:JSON.stringify(d.body),isBase64Encoded:!1}}let u=AS(s);if(!c){let d=await n(u);return Lf(d)}if(c.observed)console.warn(`[ts-cloud] recursion detected (${c.verdict.reason}) at depth ${c.verdict.depth}; detection-only mode let it run`);return _f(c.verdict,async()=>Lf(await n(u)))}}function ga(n){try{return JSON.parse(n)}catch{return n}}function SS(n){return async(i)=>{let s=[];if(i.warmer)return{batchItemFailures:s};if(!n)return{batchItemFailures:s};for(let o of i.Records??[])try{await n(ga(o.body),o)}catch{s.push({itemIdentifier:o.messageId})}return{batchItemFailures:s}}}function IS(n){return async(i)=>{if(i.warmer)return{statusCode:0,output:"warm"};if(!n)return{statusCode:501,output:"No CLI handler configured"};return n(i)}}function BE(n,i){return{http:yS(n.fetch,i),queue:SS(n.queue),cli:IS(n.cli)}}function $f(n={}){let i=n.socketPath??"/tmp/.tscloud-fpm.sock",s=n.maxChildren??1;return`; ts-cloud php-fpm configuration (generated) — AWS Lambda custom runtime.
7303
7303
  [global]
7304
7304
  daemonize = no
7305
7305
  error_log = ${n.errorLog??"/tmp/storage/logs/php-fpm.log"}
@@ -7316,4 +7316,4 @@ decorate_workers_output = no
7316
7316
  php_admin_value[error_log] = /dev/stderr
7317
7317
  php_admin_flag[log_errors] = on
7318
7318
  clear_env = no
7319
- `}import{readFileSync as ya}from"node:fs";import{dirname as fa,join as Xn}from"node:path";import{fileURLToPath as ha}from"node:url";function ba(){return Xn(fa(ha(import.meta.url)),"runtime-assets")}function fn(){let n=ba(),i=(s)=>ya(Xn(n,s),"utf-8");return[{path:"bootstrap",contents:i("bootstrap"),mode:493},{path:"tscloud/runtime.php",contents:i("runtime.php"),mode:420},{path:"tscloud/octane-runtime.php",contents:i("octane-runtime.php"),mode:420},{path:"tscloud/cli-runtime.php",contents:i("cli-runtime.php"),mode:420},{path:"tscloud/fastcgi-client.php",contents:i("fastcgi-client.php"),mode:420},{path:"tscloud/php-fpm.conf",contents:Lf(),mode:420}]}function ql(n={}){let i=n.cacheDriver??"dynamodb";return{APP_ENV:"production",LOG_CHANNEL:"stderr",CACHE_STORE:i,CACHE_DRIVER:i,SESSION_DRIVER:i,QUEUE_CONNECTION:"sqs",FILESYSTEM_DISK:"s3",VIEW_COMPILED_PATH:"/tmp/storage/framework/views",APP_SERVICES_CACHE:"/tmp/bootstrap/cache/services.php",APP_PACKAGES_CACHE:"/tmp/bootstrap/cache/packages.php",APP_CONFIG_CACHE:"/tmp/bootstrap/cache/config.php",APP_ROUTES_CACHE:"/tmp/bootstrap/cache/routes.php",APP_EVENTS_CACHE:"/tmp/bootstrap/cache/events.php"}}var $f=["composer install --no-dev --optimize-autoloader --no-interaction","php artisan config:cache","php artisan route:cache","php artisan event:cache","php artisan view:cache"];import{execFileSync as ft}from"node:child_process";import{existsSync as Sa,mkdirSync as Aa,mkdtempSync as Ca,readdirSync as va,readFileSync as Ta,rmSync as Ra,statSync as er,writeFileSync as Pa}from"node:fs";import{tmpdir as Ea}from"node:os";import{join as Ge,relative as wa}from"node:path";function*tr(n){for(let i of va(n)){let s=Ge(n,i);if(er(s).isDirectory())yield*tr(s);else yield s}}function BE(n={}){let i=n.architecture??"x86_64",s=n.platform??(i==="arm64"?"linux/arm64":"linux/amd64"),o=n.onStep??(()=>{}),c=Ca(Ge(Ea(),"tscloud-php-layer-")),u="tscloud-php-layer:build";try{Pa(Ge(c,"Dockerfile"),kf(n)),o("Building PHP runtime image (docker)"),ft("docker",["build","--platform",s,"-t","tscloud-php-layer:build",c],{stdio:"inherit"}),o("Extracting /opt/php from image");let d=ft("docker",["create","--platform",s,"tscloud-php-layer:build"],{encoding:"utf-8"}).trim(),p=Ge(c,"opt");Aa(p,{recursive:!0});try{ft("docker",["cp",`${d}:/opt/php`,Ge(p,"php")],{stdio:"inherit"})}finally{ft("docker",["rm",d],{stdio:"ignore"})}if(!Sa(Ge(p,"php","bin","php")))throw Error("layer build produced no /opt/php/bin/php");let y=[];for(let A of tr(p)){let T=wa(p,A).replace(/\\/g,"/"),R=er(A).mode&73?493:420;y.push({name:T,data:Ta(A),mode:R})}o("Injecting runtime assets");let h=new Set(fn().map((A)=>A.path)),b=y.filter((A)=>!h.has(A.name));for(let A of fn())b.push({name:A.path,data:A.contents,mode:A.mode});return o("Packaging layer ZIP"),{zip:rt(b),architecture:i,fileCount:b.length}}finally{Ra(c,{recursive:!0,force:!0})}}import{execSync as Ia}from"node:child_process";import{createHash as Da}from"node:crypto";import{readdirSync as Na,readFileSync as xa,statSync as nr}from"node:fs";import{join as ka,relative as rr,resolve as Xt}from"node:path";var IS=[".git",".github","node_modules","tests","storage/logs","storage/framework/cache","storage/framework/sessions","storage/framework/views",".env",".env.local",".vapor",".ts-cloud","dist-lambda"];function Ma(n,i){return i.some((s)=>n===s||n.startsWith(`${s}/`))}function*ir(n,i,s){for(let o of Na(n)){let c=ka(n,o),u=rr(i,c).replace(/\\/g,"/");if(Ma(u,s))continue;if(nr(c).isDirectory())yield*ir(c,i,s);else yield c}}function ea(n){if(n.skipBuild)return;let i=Xt(n.projectRoot??process.cwd()),s=n.app.build??$f;for(let o of s)n.onStep?.(`build: ${o}`),Ia(o,{stdio:"inherit",cwd:i})}function ta(n,i=[]){let s=Xt(n),o=[...IS,cn(),...i],c=[];for(let u of ir(s,s,o)){let d=rr(s,u).replace(/\\/g,"/"),p=(nr(u).mode&73)!==0;c.push({name:d,data:xa(u),mode:p?493:420})}return c}function jl(n){let i=Xt(n.projectRoot??process.cwd());ea(n),n.onStep?.("packaging application tree");let s=ta(i,n.exclude);if(!s.length)throw Error(`No files to package under ${i}`);let o=rt(s),c=n.app.handlers?.http??"public/index.php";return{zip:o,sha256:Da("sha256").update(o).digest("hex"),handlers:{http:c,queue:n.app.handlers?.queue??c,cli:n.app.handlers?.cli??c},fileCount:s.length}}class Mf{optimizations=new Map;imageConfigs=new Map;ssgConfigs=new Map;prerenderConfigs=new Map;counter=0;createAssetOptimization(n){let i=`asset-opt-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.optimizations.set(i,s),s}createImageOptimization(n){let i=`image-opt-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.imageConfigs.set(i,s),s}createSSGConfig(n){let i=`ssg-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.ssgConfigs.set(i,s),s}createPrerenderConfig(n){let i=`prerender-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.prerenderConfigs.set(i,s),s}listOptimizations(){return Array.from(this.optimizations.values())}listImageConfigs(){return Array.from(this.imageConfigs.values())}clear(){this.optimizations.clear(),this.imageConfigs.clear(),this.ssgConfigs.clear(),this.prerenderConfigs.clear()}}var xE=new Mf;class zl{policies=new Map;versioningConfigs=new Map;replicationRules=new Map;tieringConfigs=new Map;objectLocks=new Map;transferAcceleration=new Map;accessPoints=new Map;glacierConfigs=new Map;inventories=new Map;batchOps=new Map;eventNotifications=new Map;counter=0;createLifecyclePolicy(n,i){let s=`lifecycle-${Date.now()}-${this.counter++}`,o={id:s,transitions:n,expiration:i};return this.policies.set(s,o),o}enableVersioning(n=!1){let i=`versioning-${Date.now()}-${this.counter++}`,s={id:i,enabled:!0,mfaDelete:n};return this.versioningConfigs.set(i,s),s}createReplicationRule(n,i,s){let o=`replication-${Date.now()}-${this.counter++}`,c={id:o,sourceRegion:n,destRegion:i,destBucket:s};return this.replicationRules.set(o,c),c}createIntelligentTiering(n,i){let s=`tiering-${Date.now()}-${this.counter++}`,o={id:s,archiveDays:n,deepArchiveDays:i};return this.tieringConfigs.set(s,o),o}enableObjectLock(n){let i=`object-lock-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,mode:n.mode||"COMPLIANCE",retentionDays:n.retentionDays,retentionYears:n.retentionYears,legalHoldEnabled:n.legalHoldEnabled||!1};return this.objectLocks.set(i,s),s}enableTransferAcceleration(n){let i=`transfer-accel-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n,enabled:!0,endpoint:`${n}.s3-accelerate.amazonaws.com`};return this.transferAcceleration.set(i,s),s}createAccessPoint(n){let i=`access-point-${Date.now()}-${this.counter++}`,s={id:i,name:n.name,bucketName:n.bucketName,vpcId:n.vpcId,publicAccessBlock:n.publicAccessBlock!==!1,policy:n.policy};return this.accessPoints.set(i,s),s}createGlacierArchive(n){let i=`glacier-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,archiveType:n.archiveType,transitionDays:n.transitionDays,restoreConfig:n.restoreTier?{tier:n.restoreTier,days:n.restoreDays||7}:void 0};return this.glacierConfigs.set(i,s),s}createInventory(n){let i=`inventory-${Date.now()}-${this.counter++}`,s={id:i,sourceBucket:n.sourceBucket,destinationBucket:n.destinationBucket,schedule:n.schedule||"Daily",format:n.format||"CSV",includedFields:n.includedFields||["Size","LastModifiedDate","StorageClass","ETag"],prefix:n.prefix};return this.inventories.set(i,s),s}createBatchOperation(n){let i=`batch-op-${Date.now()}-${this.counter++}`,s={id:i,operation:n.operation,manifestBucket:n.manifestBucket,manifestKey:n.manifestKey,priority:n.priority||10,status:"pending"};return this.batchOps.set(i,s),s}executeBatchOperation(n){let i=this.batchOps.get(n);if(!i)throw Error(`Batch operation not found: ${n}`);return i.status="in_progress",i.totalObjects=1000,i.processedObjects=0,i}getBatchOperationStatus(n){return this.batchOps.get(n)}createLambdaNotification(n){let i=`event-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,events:n.events,destination:{type:"Lambda",arn:n.lambdaArn},filter:n.prefix||n.suffix?{prefix:n.prefix,suffix:n.suffix}:void 0};return this.eventNotifications.set(i,s),s}createSQSNotification(n){let i=`event-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,events:n.events,destination:{type:"SQS",arn:n.queueArn},filter:n.prefix||n.suffix?{prefix:n.prefix,suffix:n.suffix}:void 0};return this.eventNotifications.set(i,s),s}createSNSNotification(n){let i=`event-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,events:n.events,destination:{type:"SNS",arn:n.topicArn},filter:n.prefix||n.suffix?{prefix:n.prefix,suffix:n.suffix}:void 0};return this.eventNotifications.set(i,s),s}generateObjectLockCF(n){let i={ObjectLockEnabled:"Enabled",ObjectLockConfiguration:{ObjectLockEnabled:"Enabled",Rule:{DefaultRetention:{Mode:n.mode}}}};if(n.retentionDays)i.ObjectLockConfiguration.Rule.DefaultRetention.Days=n.retentionDays;if(n.retentionYears)i.ObjectLockConfiguration.Rule.DefaultRetention.Years=n.retentionYears;return i}generateTransferAccelerationCF(n){return{AccelerateConfiguration:{AccelerationStatus:n.enabled?"Enabled":"Suspended"}}}generateAccessPointCF(n){return{Type:"AWS::S3::AccessPoint",Properties:{Name:n.name,Bucket:n.bucketName,...n.vpcId&&{VpcConfiguration:{VpcId:n.vpcId}},PublicAccessBlockConfiguration:n.publicAccessBlock?{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0}:void 0,...n.policy&&{Policy:n.policy}}}}generateInventoryCF(n){return{Type:"AWS::S3::Bucket",Properties:{InventoryConfigurations:[{Id:n.id,Destination:{BucketArn:`arn:aws:s3:::${n.destinationBucket}`,Format:n.format},Enabled:!0,IncludedObjectVersions:"Current",OptionalFields:n.includedFields,ScheduleFrequency:n.schedule,...n.prefix&&{Prefix:n.prefix}}]}}}generateEventNotificationCF(n){let i=n.destination.type==="Lambda"?"LambdaConfigurations":n.destination.type==="SQS"?"QueueConfigurations":"TopicConfigurations",s=n.destination.type==="Lambda"?"Function":n.destination.type==="SQS"?"Queue":"Topic",o={Event:n.events[0],[s]:n.destination.arn};if(n.filter)o.Filter={S3Key:{Rules:[...n.filter.prefix?[{Name:"prefix",Value:n.filter.prefix}]:[],...n.filter.suffix?[{Name:"suffix",Value:n.filter.suffix}]:[]]}};return{NotificationConfiguration:{[i]:[o]}}}clear(){this.policies.clear(),this.versioningConfigs.clear(),this.replicationRules.clear(),this.tieringConfigs.clear(),this.objectLocks.clear(),this.transferAcceleration.clear(),this.accessPoints.clear(),this.glacierConfigs.clear(),this.inventories.clear(),this.batchOps.clear(),this.eventNotifications.clear()}}var bS=new zl;class Ff{checks=new Map;synthetics=new Map;uptimeTrackers=new Map;counter=0;createHealthCheck(n,i=30,s=10){let o=`health-${Date.now()}-${this.counter++}`,c={id:o,url:n,interval:i,timeout:s,status:"healthy"};return this.checks.set(o,c),c}createSyntheticMonitor(n,i,s,o){let c=`synthetic-${Date.now()}-${this.counter++}`,u={id:c,name:n,script:i,frequency:s,locations:o};return this.synthetics.set(c,u),u}trackUptime(n,i,s){let o=`uptime-${Date.now()}-${this.counter++}`,c=i/(i+s)*100,u={id:o,resource:n,uptime:i,downtime:s,availability:c};return this.uptimeTrackers.set(o,u),u}clear(){this.checks.clear(),this.synthetics.clear(),this.uptimeTrackers.clear()}}var OE=new Ff;class Uf{wafRules=new Map;shieldProtections=new Map;securityGroups=new Map;nacls=new Map;counter=0;createWAFRule(n,i,s,o){let c=`waf-${Date.now()}-${this.counter++}`,u={id:c,name:n,priority:i,action:s,conditions:o};return this.wafRules.set(c,u),u}enableShield(n,i="standard"){let s=`shield-${Date.now()}-${this.counter++}`,o={id:s,resourceArn:n,protectionType:i};return this.shieldProtections.set(s,o),o}createSecurityGroup(n,i,s){let o=`sg-${Date.now()}-${this.counter++}`,c={id:o,name:n,vpcId:i,rules:s};return this.securityGroups.set(o,c),c}createNACL(n,i){let s=`nacl-${Date.now()}-${this.counter++}`,o={id:s,vpcId:n,rules:i};return this.nacls.set(s,o),o}clear(){this.wafRules.clear(),this.shieldProtections.clear(),this.securityGroups.clear(),this.nacls.clear()}}var _E=new Uf;class Qf{strategies=new Map;allocations=new Map;groups=new Map;counter=0;createTaggingStrategy(n,i){let s=`tagging-${Date.now()}-${this.counter++}`,o={id:s,tags:n,resources:i};return this.strategies.set(s,o),o}createCostAllocation(n,i){let s=`cost-${Date.now()}-${this.counter++}`,o={id:s,tagKey:n,allocations:i};return this.allocations.set(s,o),o}createResourceGroup(n,i,s){let o=`group-${Date.now()}-${this.counter++}`,c={id:o,name:n,query:{resourceTypeFilters:i,tagFilters:s}};return this.groups.set(o,c),c}clear(){this.strategies.clear(),this.allocations.clear(),this.groups.clear()}}var LE=new Qf;export{_I,LI,rl,Am,nl,il,cn,Q,l,sl,ym,K,ol,g,ey,C,Xe,Ji,dn,w,be,al,ty,r,t,$I,MI,m,FI,UI,QI,HI,GI,dr,cl,Xi,ry,VI,qI,xe,Ye,dl,Sm,Im,jI,bm,Cm,Em,Qo,ll,ce,ln,Dt,Ho,Pt,Ce,ny,ul,Go,vm,Tm,wm,Rm,gl,zI,W,E,iy,sy,Dm,a,S,Ze,f,Pm,et,J,kt,KI,km,X,pl,Oe,lr,Vo,de,ml,le,oy,qo,Y,Z,_,Yi,D,ur,Nt,ee,e,un,WI,Nm,fl,JI,XI,YI,ZI,hl,eb,tb,rb,nb,ib,sb,ob,ab,cb,db,lb,ub,ay,cy,dy,ly,uy,gy,py,gr,Bm,xm,pr,Zi,gb,Om,pb,mb,gn,fb,hb,Ab,yb,Sb,Ib,my,fy,hy,Ay,yy,es,bb,jo,Sy,_m,V,Iy,tt,zo,Bt,by,Lm,Cy,Ey,vy,$m,q,Cb,Eb,vb,Tb,Ty,wb,te,Rb,Db,Pb,Al,yl,wy,Mm,Fm,kb,Nb,Bb,xb,Ob,Ry,Sl,_b,Lb,$b,Mb,Fb,Dy,Py,Ub,Qb,Hb,Gb,Vb,qb,jb,ky,zb,Um,Il,Kb,Wb,Jb,Xb,Qm,Hm,Gm,Yb,bl,Ny,By,xy,Oy,Cl,_y,Zb,eC,tC,rC,nC,iC,sC,Ly,$y,My,Fy,Vm,oC,aC,cC,dC,lC,uC,gC,pC,mC,Uy,Qy,Hy,Gy,fC,hC,qm,AC,jm,zm,Km,Wm,yC,SC,IC,bC,_e,ts,CC,EC,vC,TC,wC,RC,DC,PC,Vy,kC,NC,Jm,Xm,BC,xC,qy,OC,_C,LC,$C,MC,FC,UC,QC,HC,GC,VC,qC,jC,zC,KC,WC,JC,XC,YC,ZC,eE,El,jy,vl,zy,Tl,Ky,wl,Wy,Rl,Jy,mr,Xy,Dl,Yy,rs,Zy,Pl,eS,kl,tS,Ym,tE,Zm,rE,Nl,rS,fr,nS,ef,nE,Bl,iS,tf,iE,rf,sE,nf,oE,xl,sS,sf,aE,of,cE,af,dE,cf,lE,Ol,oS,_l,aS,df,uE,lf,gE,uf,pE,gf,mE,pf,fE,mf,hE,Ll,cS,ff,AE,hf,yE,Af,SE,yf,IE,Sf,bE,If,CE,bf,Cf,Ef,vf,Tf,EE,wf,vE,Rf,TE,Df,wE,rt,Pf,dS,Ko,$l,pn,lS,ns,hr,Ml,Fl,uS,gS,Ul,kf,Ql,Nf,RE,DE,Wo,Jo,Xo,Hl,mn,Gl,Vl,is,Yo,Zo,Bf,pS,mS,fS,PE,xf,Of,kE,hS,_f,AS,yS,SS,NE,Lf,fn,ql,$f,BE,IS,ea,ta,jl,Mf,xE,zl,bS,Ff,OE,Uf,_E,Qf,LE};
7319
+ `}import{readFileSync as ya}from"node:fs";import{dirname as fa,join as Xn}from"node:path";import{fileURLToPath as ha}from"node:url";function ba(){return Xn(fa(ha(import.meta.url)),"runtime-assets")}function fn(){let n=ba(),i=(s)=>ya(Xn(n,s),"utf-8");return[{path:"bootstrap",contents:i("bootstrap"),mode:493},{path:"tscloud/runtime.php",contents:i("runtime.php"),mode:420},{path:"tscloud/octane-runtime.php",contents:i("octane-runtime.php"),mode:420},{path:"tscloud/cli-runtime.php",contents:i("cli-runtime.php"),mode:420},{path:"tscloud/fastcgi-client.php",contents:i("fastcgi-client.php"),mode:420},{path:"tscloud/php-fpm.conf",contents:$f(),mode:420}]}function ql(n={}){let i=n.cacheDriver??"dynamodb";return{APP_ENV:"production",LOG_CHANNEL:"stderr",CACHE_STORE:i,CACHE_DRIVER:i,SESSION_DRIVER:i,QUEUE_CONNECTION:"sqs",FILESYSTEM_DISK:"s3",VIEW_COMPILED_PATH:"/tmp/storage/framework/views",APP_SERVICES_CACHE:"/tmp/bootstrap/cache/services.php",APP_PACKAGES_CACHE:"/tmp/bootstrap/cache/packages.php",APP_CONFIG_CACHE:"/tmp/bootstrap/cache/config.php",APP_ROUTES_CACHE:"/tmp/bootstrap/cache/routes.php",APP_EVENTS_CACHE:"/tmp/bootstrap/cache/events.php"}}var Mf=["composer install --no-dev --optimize-autoloader --no-interaction","php artisan config:cache","php artisan route:cache","php artisan event:cache","php artisan view:cache"];import{execFileSync as ft}from"node:child_process";import{existsSync as Sa,mkdirSync as Aa,mkdtempSync as Ca,readdirSync as va,readFileSync as Ta,rmSync as Ra,statSync as er,writeFileSync as Pa}from"node:fs";import{tmpdir as Ea}from"node:os";import{join as Ge,relative as wa}from"node:path";function*tr(n){for(let i of va(n)){let s=Ge(n,i);if(er(s).isDirectory())yield*tr(s);else yield s}}function xE(n={}){let i=n.architecture??"x86_64",s=n.platform??(i==="arm64"?"linux/arm64":"linux/amd64"),o=n.onStep??(()=>{}),c=Ca(Ge(Ea(),"tscloud-php-layer-")),u="tscloud-php-layer:build";try{Pa(Ge(c,"Dockerfile"),Nf(n)),o("Building PHP runtime image (docker)"),ft("docker",["build","--platform",s,"-t","tscloud-php-layer:build",c],{stdio:"inherit"}),o("Extracting /opt/php from image");let d=ft("docker",["create","--platform",s,"tscloud-php-layer:build"],{encoding:"utf-8"}).trim(),p=Ge(c,"opt");Aa(p,{recursive:!0});try{ft("docker",["cp",`${d}:/opt/php`,Ge(p,"php")],{stdio:"inherit"})}finally{ft("docker",["rm",d],{stdio:"ignore"})}if(!Sa(Ge(p,"php","bin","php")))throw Error("layer build produced no /opt/php/bin/php");let y=[];for(let A of tr(p)){let T=wa(p,A).replace(/\\/g,"/"),R=er(A).mode&73?493:420;y.push({name:T,data:Ta(A),mode:R})}o("Injecting runtime assets");let h=new Set(fn().map((A)=>A.path)),b=y.filter((A)=>!h.has(A.name));for(let A of fn())b.push({name:A.path,data:A.contents,mode:A.mode});return o("Packaging layer ZIP"),{zip:rt(b),architecture:i,fileCount:b.length}}finally{Ra(c,{recursive:!0,force:!0})}}import{execSync as Ia}from"node:child_process";import{createHash as Da}from"node:crypto";import{readdirSync as Na,readFileSync as xa,statSync as nr}from"node:fs";import{join as ka,relative as rr,resolve as Xt}from"node:path";var bS=[".git",".github","node_modules","tests","storage/logs","storage/framework/cache","storage/framework/sessions","storage/framework/views",".env",".env.local",".vapor",".ts-cloud","dist-lambda"];function Ma(n,i){return i.some((s)=>n===s||n.startsWith(`${s}/`))}function*ir(n,i,s){for(let o of Na(n)){let c=ka(n,o),u=rr(i,c).replace(/\\/g,"/");if(Ma(u,s))continue;if(nr(c).isDirectory())yield*ir(c,i,s);else yield c}}function ea(n){if(n.skipBuild)return;let i=Xt(n.projectRoot??process.cwd()),s=n.app.build??Mf;for(let o of s)n.onStep?.(`build: ${o}`),Ia(o,{stdio:"inherit",cwd:i})}function ta(n,i=[]){let s=Xt(n),o=[...bS,cn(),...i],c=[];for(let u of ir(s,s,o)){let d=rr(s,u).replace(/\\/g,"/"),p=(nr(u).mode&73)!==0;c.push({name:d,data:xa(u),mode:p?493:420})}return c}function jl(n){let i=Xt(n.projectRoot??process.cwd());ea(n),n.onStep?.("packaging application tree");let s=ta(i,n.exclude);if(!s.length)throw Error(`No files to package under ${i}`);let o=rt(s),c=n.app.handlers?.http??"public/index.php";return{zip:o,sha256:Da("sha256").update(o).digest("hex"),handlers:{http:c,queue:n.app.handlers?.queue??c,cli:n.app.handlers?.cli??c},fileCount:s.length}}class Ff{optimizations=new Map;imageConfigs=new Map;ssgConfigs=new Map;prerenderConfigs=new Map;counter=0;createAssetOptimization(n){let i=`asset-opt-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.optimizations.set(i,s),s}createImageOptimization(n){let i=`image-opt-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.imageConfigs.set(i,s),s}createSSGConfig(n){let i=`ssg-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.ssgConfigs.set(i,s),s}createPrerenderConfig(n){let i=`prerender-${Date.now()}-${this.counter++}`,s={id:i,...n};return this.prerenderConfigs.set(i,s),s}listOptimizations(){return Array.from(this.optimizations.values())}listImageConfigs(){return Array.from(this.imageConfigs.values())}clear(){this.optimizations.clear(),this.imageConfigs.clear(),this.ssgConfigs.clear(),this.prerenderConfigs.clear()}}var OE=new Ff;class zl{policies=new Map;versioningConfigs=new Map;replicationRules=new Map;tieringConfigs=new Map;objectLocks=new Map;transferAcceleration=new Map;accessPoints=new Map;glacierConfigs=new Map;inventories=new Map;batchOps=new Map;eventNotifications=new Map;counter=0;createLifecyclePolicy(n,i){let s=`lifecycle-${Date.now()}-${this.counter++}`,o={id:s,transitions:n,expiration:i};return this.policies.set(s,o),o}enableVersioning(n=!1){let i=`versioning-${Date.now()}-${this.counter++}`,s={id:i,enabled:!0,mfaDelete:n};return this.versioningConfigs.set(i,s),s}createReplicationRule(n,i,s){let o=`replication-${Date.now()}-${this.counter++}`,c={id:o,sourceRegion:n,destRegion:i,destBucket:s};return this.replicationRules.set(o,c),c}createIntelligentTiering(n,i){let s=`tiering-${Date.now()}-${this.counter++}`,o={id:s,archiveDays:n,deepArchiveDays:i};return this.tieringConfigs.set(s,o),o}enableObjectLock(n){let i=`object-lock-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,mode:n.mode||"COMPLIANCE",retentionDays:n.retentionDays,retentionYears:n.retentionYears,legalHoldEnabled:n.legalHoldEnabled||!1};return this.objectLocks.set(i,s),s}enableTransferAcceleration(n){let i=`transfer-accel-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n,enabled:!0,endpoint:`${n}.s3-accelerate.amazonaws.com`};return this.transferAcceleration.set(i,s),s}createAccessPoint(n){let i=`access-point-${Date.now()}-${this.counter++}`,s={id:i,name:n.name,bucketName:n.bucketName,vpcId:n.vpcId,publicAccessBlock:n.publicAccessBlock!==!1,policy:n.policy};return this.accessPoints.set(i,s),s}createGlacierArchive(n){let i=`glacier-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,archiveType:n.archiveType,transitionDays:n.transitionDays,restoreConfig:n.restoreTier?{tier:n.restoreTier,days:n.restoreDays||7}:void 0};return this.glacierConfigs.set(i,s),s}createInventory(n){let i=`inventory-${Date.now()}-${this.counter++}`,s={id:i,sourceBucket:n.sourceBucket,destinationBucket:n.destinationBucket,schedule:n.schedule||"Daily",format:n.format||"CSV",includedFields:n.includedFields||["Size","LastModifiedDate","StorageClass","ETag"],prefix:n.prefix};return this.inventories.set(i,s),s}createBatchOperation(n){let i=`batch-op-${Date.now()}-${this.counter++}`,s={id:i,operation:n.operation,manifestBucket:n.manifestBucket,manifestKey:n.manifestKey,priority:n.priority||10,status:"pending"};return this.batchOps.set(i,s),s}executeBatchOperation(n){let i=this.batchOps.get(n);if(!i)throw Error(`Batch operation not found: ${n}`);return i.status="in_progress",i.totalObjects=1000,i.processedObjects=0,i}getBatchOperationStatus(n){return this.batchOps.get(n)}createLambdaNotification(n){let i=`event-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,events:n.events,destination:{type:"Lambda",arn:n.lambdaArn},filter:n.prefix||n.suffix?{prefix:n.prefix,suffix:n.suffix}:void 0};return this.eventNotifications.set(i,s),s}createSQSNotification(n){let i=`event-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,events:n.events,destination:{type:"SQS",arn:n.queueArn},filter:n.prefix||n.suffix?{prefix:n.prefix,suffix:n.suffix}:void 0};return this.eventNotifications.set(i,s),s}createSNSNotification(n){let i=`event-${Date.now()}-${this.counter++}`,s={id:i,bucketName:n.bucketName,events:n.events,destination:{type:"SNS",arn:n.topicArn},filter:n.prefix||n.suffix?{prefix:n.prefix,suffix:n.suffix}:void 0};return this.eventNotifications.set(i,s),s}generateObjectLockCF(n){let i={ObjectLockEnabled:"Enabled",ObjectLockConfiguration:{ObjectLockEnabled:"Enabled",Rule:{DefaultRetention:{Mode:n.mode}}}};if(n.retentionDays)i.ObjectLockConfiguration.Rule.DefaultRetention.Days=n.retentionDays;if(n.retentionYears)i.ObjectLockConfiguration.Rule.DefaultRetention.Years=n.retentionYears;return i}generateTransferAccelerationCF(n){return{AccelerateConfiguration:{AccelerationStatus:n.enabled?"Enabled":"Suspended"}}}generateAccessPointCF(n){return{Type:"AWS::S3::AccessPoint",Properties:{Name:n.name,Bucket:n.bucketName,...n.vpcId&&{VpcConfiguration:{VpcId:n.vpcId}},PublicAccessBlockConfiguration:n.publicAccessBlock?{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0}:void 0,...n.policy&&{Policy:n.policy}}}}generateInventoryCF(n){return{Type:"AWS::S3::Bucket",Properties:{InventoryConfigurations:[{Id:n.id,Destination:{BucketArn:`arn:aws:s3:::${n.destinationBucket}`,Format:n.format},Enabled:!0,IncludedObjectVersions:"Current",OptionalFields:n.includedFields,ScheduleFrequency:n.schedule,...n.prefix&&{Prefix:n.prefix}}]}}}generateEventNotificationCF(n){let i=n.destination.type==="Lambda"?"LambdaConfigurations":n.destination.type==="SQS"?"QueueConfigurations":"TopicConfigurations",s=n.destination.type==="Lambda"?"Function":n.destination.type==="SQS"?"Queue":"Topic",o={Event:n.events[0],[s]:n.destination.arn};if(n.filter)o.Filter={S3Key:{Rules:[...n.filter.prefix?[{Name:"prefix",Value:n.filter.prefix}]:[],...n.filter.suffix?[{Name:"suffix",Value:n.filter.suffix}]:[]]}};return{NotificationConfiguration:{[i]:[o]}}}clear(){this.policies.clear(),this.versioningConfigs.clear(),this.replicationRules.clear(),this.tieringConfigs.clear(),this.objectLocks.clear(),this.transferAcceleration.clear(),this.accessPoints.clear(),this.glacierConfigs.clear(),this.inventories.clear(),this.batchOps.clear(),this.eventNotifications.clear()}}var CS=new zl;class Uf{checks=new Map;synthetics=new Map;uptimeTrackers=new Map;counter=0;createHealthCheck(n,i=30,s=10){let o=`health-${Date.now()}-${this.counter++}`,c={id:o,url:n,interval:i,timeout:s,status:"healthy"};return this.checks.set(o,c),c}createSyntheticMonitor(n,i,s,o){let c=`synthetic-${Date.now()}-${this.counter++}`,u={id:c,name:n,script:i,frequency:s,locations:o};return this.synthetics.set(c,u),u}trackUptime(n,i,s){let o=`uptime-${Date.now()}-${this.counter++}`,c=i/(i+s)*100,u={id:o,resource:n,uptime:i,downtime:s,availability:c};return this.uptimeTrackers.set(o,u),u}clear(){this.checks.clear(),this.synthetics.clear(),this.uptimeTrackers.clear()}}var _E=new Uf;class Qf{wafRules=new Map;shieldProtections=new Map;securityGroups=new Map;nacls=new Map;counter=0;createWAFRule(n,i,s,o){let c=`waf-${Date.now()}-${this.counter++}`,u={id:c,name:n,priority:i,action:s,conditions:o};return this.wafRules.set(c,u),u}enableShield(n,i="standard"){let s=`shield-${Date.now()}-${this.counter++}`,o={id:s,resourceArn:n,protectionType:i};return this.shieldProtections.set(s,o),o}createSecurityGroup(n,i,s){let o=`sg-${Date.now()}-${this.counter++}`,c={id:o,name:n,vpcId:i,rules:s};return this.securityGroups.set(o,c),c}createNACL(n,i){let s=`nacl-${Date.now()}-${this.counter++}`,o={id:s,vpcId:n,rules:i};return this.nacls.set(s,o),o}clear(){this.wafRules.clear(),this.shieldProtections.clear(),this.securityGroups.clear(),this.nacls.clear()}}var LE=new Qf;class Hf{strategies=new Map;allocations=new Map;groups=new Map;counter=0;createTaggingStrategy(n,i){let s=`tagging-${Date.now()}-${this.counter++}`,o={id:s,tags:n,resources:i};return this.strategies.set(s,o),o}createCostAllocation(n,i){let s=`cost-${Date.now()}-${this.counter++}`,o={id:s,tagKey:n,allocations:i};return this.allocations.set(s,o),o}createResourceGroup(n,i,s){let o=`group-${Date.now()}-${this.counter++}`,c={id:o,name:n,query:{resourceTypeFilters:i,tagFilters:s}};return this.groups.set(o,c),c}clear(){this.strategies.clear(),this.allocations.clear(),this.groups.clear()}}var $E=new Hf;export{LI,$I,rl,ym,nl,il,cn,Q,l,sl,Sm,K,ol,g,ty,C,Xe,Ji,dn,w,be,al,ry,r,t,MI,FI,m,UI,QI,HI,GI,VI,dr,cl,Xi,ny,qI,jI,xe,Ye,dl,Im,bm,zI,Cm,Em,vm,Qo,ll,ce,ln,Dt,Ho,Pt,Ce,iy,ul,Go,Tm,wm,Rm,Dm,gl,KI,W,E,sy,oy,Pm,a,S,Ze,f,km,et,J,kt,WI,Nm,X,pl,Oe,lr,Vo,de,ml,le,ay,qo,Y,Z,_,Yi,D,ur,Nt,ee,e,un,JI,Bm,fl,XI,YI,ZI,eb,hl,tb,rb,nb,ib,sb,ob,ab,cb,db,lb,ub,gb,cy,dy,ly,uy,gy,py,my,gr,xm,Om,pr,Zi,pb,_m,mb,fb,gn,hb,Ab,yb,Sb,Ib,bb,fy,hy,Ay,yy,Sy,es,Cb,jo,Iy,Lm,V,by,tt,zo,Bt,Cy,$m,Ey,vy,Ty,Mm,q,Eb,vb,Tb,wb,wy,Rb,te,Db,Pb,kb,Al,yl,Ry,Fm,Um,Nb,Bb,xb,Ob,_b,Dy,Sl,Lb,$b,Mb,Fb,Ub,Py,ky,Qb,Hb,Gb,Vb,qb,jb,zb,Ny,Kb,Qm,Il,Wb,Jb,Xb,Yb,Hm,Gm,Vm,Zb,bl,By,xy,Oy,_y,Cl,Ly,eC,tC,rC,nC,iC,sC,oC,$y,My,Fy,Uy,qm,aC,cC,dC,lC,uC,gC,pC,mC,fC,Qy,Hy,Gy,Vy,hC,AC,jm,yC,zm,Km,Wm,Jm,SC,IC,bC,CC,_e,ts,EC,vC,TC,wC,RC,DC,PC,kC,qy,NC,BC,Xm,Ym,xC,OC,jy,_C,LC,$C,MC,FC,UC,QC,HC,GC,VC,qC,jC,zC,KC,WC,JC,XC,YC,ZC,eE,tE,El,zy,vl,Ky,Tl,Wy,wl,Jy,Rl,Xy,mr,Yy,Dl,Zy,rs,eS,Pl,tS,kl,rS,Zm,rE,ef,nE,Nl,nS,fr,iS,tf,iE,Bl,sS,rf,sE,nf,oE,sf,aE,xl,oS,of,cE,af,dE,cf,lE,df,uE,Ol,aS,_l,cS,lf,gE,uf,pE,gf,mE,pf,fE,mf,hE,ff,AE,Ll,dS,hf,yE,Af,SE,yf,IE,Sf,bE,If,CE,bf,EE,Cf,Ef,vf,Tf,wf,vE,Rf,TE,Df,wE,Pf,RE,rt,kf,lS,Ko,$l,pn,uS,ns,hr,Ml,Fl,gS,pS,Ul,Nf,Ql,Bf,DE,PE,Wo,Jo,Xo,Hl,mn,Gl,Vl,is,Yo,Zo,xf,mS,fS,hS,kE,Of,_f,NE,AS,Lf,yS,SS,IS,BE,$f,fn,ql,Mf,xE,bS,ea,ta,jl,Ff,OE,zl,CS,Uf,_E,Qf,LE,Hf,$E};