@stacksjs/ts-cloud 0.12.15 → 0.12.16

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 (166) hide show
  1. package/dist/aws/index.js +1 -1
  2. package/dist/bin/chunk-005sxfmc.js +1 -0
  3. package/dist/bin/{chunk-pt2bz3kr.js → chunk-2shtky1g.js} +1 -1
  4. package/dist/bin/chunk-3zq0wkz2.js +1 -0
  5. package/dist/bin/chunk-4qzpqmhe.js +1 -0
  6. package/dist/bin/chunk-4vgbynq6.js +1 -0
  7. package/dist/bin/chunk-52wgrpe8.js +1 -0
  8. package/dist/bin/{chunk-sdwr2tnp.js → chunk-5qann9n2.js} +1 -1
  9. package/dist/bin/{chunk-gd4w6bht.js → chunk-6tty6sjf.js} +1 -1
  10. package/dist/bin/{chunk-ynr22ma8.js → chunk-7jwxgxxf.js} +1 -1
  11. package/dist/bin/{chunk-77qpn2m8.js → chunk-7xszcdqn.js} +1 -1
  12. package/dist/bin/{chunk-raj6j2j5.js → chunk-8sxb2rr0.js} +1 -1
  13. package/dist/bin/{chunk-7a7n6p2m.js → chunk-9jmnmhpy.js} +1 -1
  14. package/dist/bin/{chunk-x42gb7pq.js → chunk-9vrnrxay.js} +1 -1
  15. package/dist/bin/{chunk-9e22a51n.js → chunk-9wjgxjqp.js} +57 -57
  16. package/dist/bin/chunk-9yra64dd.js +1 -0
  17. package/dist/bin/{chunk-r1w08y38.js → chunk-a76krpa1.js} +1 -1
  18. package/dist/bin/{chunk-swete552.js → chunk-a8rn2wym.js} +5 -5
  19. package/dist/bin/{chunk-ng0949x3.js → chunk-b48j6k55.js} +1 -1
  20. package/dist/bin/{chunk-r1vtnn8w.js → chunk-be7rhw60.js} +3 -3
  21. package/dist/bin/chunk-bwvnfc74.js +1 -0
  22. package/dist/bin/chunk-cy4wwpnf.js +1 -0
  23. package/dist/bin/{chunk-s1j941z1.js → chunk-dvm4n8m8.js} +1 -1
  24. package/dist/bin/{chunk-5tsxt28g.js → chunk-dxfsq94k.js} +1 -1
  25. package/dist/bin/chunk-dy10cmt9.js +1 -0
  26. package/dist/bin/{chunk-zzsdhhmb.js → chunk-e3d9m062.js} +1 -1
  27. package/dist/bin/{chunk-kc2e193t.js → chunk-ebdybz7x.js} +61 -61
  28. package/dist/bin/chunk-fbe5kk6w.js +1 -0
  29. package/dist/bin/{chunk-yx1qgp1q.js → chunk-hzj5r6b7.js} +2 -2
  30. package/dist/bin/chunk-j3w462ep.js +1 -0
  31. package/dist/bin/{chunk-80zkjpfz.js → chunk-k3er0h4j.js} +1 -1
  32. package/dist/bin/chunk-k7w2ztw9.js +1 -0
  33. package/dist/bin/{chunk-dhxwmkhz.js → chunk-mcqkjhgp.js} +1 -1
  34. package/dist/bin/{chunk-w5hzt11d.js → chunk-mekcw1zn.js} +1 -1
  35. package/dist/bin/{chunk-7xvm2ygt.js → chunk-ndbtr4mb.js} +2 -2
  36. package/dist/bin/chunk-ntahmgqg.js +1 -0
  37. package/dist/bin/{chunk-57w9nsjk.js → chunk-p197a99s.js} +1 -1
  38. package/dist/bin/{chunk-vymg9ywg.js → chunk-pd8v6bpd.js} +1 -1
  39. package/dist/bin/{chunk-yhxpmk29.js → chunk-pthfzst7.js} +1 -1
  40. package/dist/bin/{chunk-n7eq4t9a.js → chunk-srw2jmh3.js} +1 -1
  41. package/dist/bin/chunk-t1eft7s7.js +1 -0
  42. package/dist/bin/{chunk-49sthm4q.js → chunk-t7seq21w.js} +1 -1
  43. package/dist/bin/chunk-t8n2961n.js +1 -0
  44. package/dist/bin/{chunk-pcyywgx7.js → chunk-tpjepvwa.js} +1 -1
  45. package/dist/bin/chunk-xvn07b0e.js +1 -0
  46. package/dist/bin/{chunk-8tbj9h2a.js → chunk-xyk8qe2c.js} +29 -29
  47. package/dist/bin/{chunk-4zbnwt9b.js → chunk-y1r1evt0.js} +1 -1
  48. package/dist/bin/{chunk-n8cwx54p.js → chunk-y24gfke7.js} +1 -1
  49. package/dist/bin/{chunk-vesvsvdy.js → chunk-zav02r6k.js} +1 -1
  50. package/dist/bin/{chunk-ejqhbj1h.js → chunk-zhpzxnpg.js} +1 -1
  51. package/dist/bin/{chunk-c51xp8f7.js → chunk-zs8bfer0.js} +1 -1
  52. package/dist/bin/cli.js +72 -72
  53. package/dist/bin/dashboard-server.js +1 -1
  54. package/dist/{chunk-x07tpsv0.js → chunk-1zz5n6q8.js} +2 -2
  55. package/dist/{chunk-cy6qh4ea.js → chunk-4ywy6dp5.js} +2 -2
  56. package/dist/{chunk-a6k322xc.js → chunk-7hjsnwcv.js} +19 -19
  57. package/dist/chunk-8fcrgq31.js +1 -0
  58. package/dist/{chunk-6t9tjvpy.js → chunk-8msfne57.js} +1 -1
  59. package/dist/{chunk-6nvn041c.js → chunk-93mgdgd5.js} +1 -1
  60. package/dist/{chunk-83p688yv.js → chunk-a6zymyfs.js} +1 -1
  61. package/dist/{chunk-6g81m01r.js → chunk-a7v15116.js} +1 -1
  62. package/dist/{chunk-2knc1zyy.js → chunk-ajq92t46.js} +41 -41
  63. package/dist/{chunk-zftpjxkr.js → chunk-bga3mw5f.js} +1 -1
  64. package/dist/{chunk-r5emv4x8.js → chunk-bgrre2px.js} +1 -1
  65. package/dist/{chunk-hnkw6pde.js → chunk-d1tv3wx0.js} +2 -2
  66. package/dist/chunk-eadp23eh.js +1 -0
  67. package/dist/{chunk-gd9g0v9w.js → chunk-j9rv5m58.js} +1 -1
  68. package/dist/{chunk-678rwkz8.js → chunk-jk7ecnmc.js} +71 -71
  69. package/dist/{chunk-9w32efae.js → chunk-jpbgr1wg.js} +1 -1
  70. package/dist/{chunk-rbem58rx.js → chunk-kazw813q.js} +1 -1
  71. package/dist/{chunk-w495x89g.js → chunk-mherymtx.js} +1 -1
  72. package/dist/{chunk-wjgnfg6q.js → chunk-nr1bdzwy.js} +1 -1
  73. package/dist/{chunk-jb8em9ba.js → chunk-qszktnnz.js} +1 -1
  74. package/dist/{chunk-yq3pdbz7.js → chunk-rtg6nw3n.js} +1 -1
  75. package/dist/{chunk-jvqcw0b4.js → chunk-thghrpf9.js} +11 -11
  76. package/dist/chunk-w7710vzg.js +1 -0
  77. package/dist/{chunk-g9mnmddy.js → chunk-wxv3ypt5.js} +1 -1
  78. package/dist/{chunk-88nxsyry.js → chunk-wz57brcf.js} +5 -5
  79. package/dist/chunk-xfdpxsbc.js +1 -0
  80. package/dist/deploy/index.js +1 -1
  81. package/dist/dns/index.js +1 -1
  82. package/dist/drivers/index.js +1 -1
  83. package/dist/drivers/shared/rpx-gateway.d.ts +17 -0
  84. package/dist/index.js +13 -13
  85. package/dist/operations/index.js +1 -1
  86. package/dist/protection/index.js +1 -1
  87. package/dist/spend/index.js +1 -1
  88. package/dist/ui/404.html +1 -1
  89. package/dist/ui/accept-invitation.html +1 -1
  90. package/dist/ui/access-denied.html +1 -1
  91. package/dist/ui/account/automation.html +5 -5
  92. package/dist/ui/account/security.html +1 -1
  93. package/dist/ui/applications/compose.html +6 -6
  94. package/dist/ui/applications/new.html +2 -2
  95. package/dist/ui/data/backups.html +6 -6
  96. package/dist/ui/data/services.html +6 -6
  97. package/dist/ui/data/volumes.html +6 -6
  98. package/dist/ui/index.html +6 -6
  99. package/dist/ui/infrastructure/topology.html +6 -6
  100. package/dist/ui/integrations.html +2 -2
  101. package/dist/ui/operations/alerts.html +6 -6
  102. package/dist/ui/operations/configuration.html +6 -6
  103. package/dist/ui/operations/jobs.html +5 -5
  104. package/dist/ui/operations/maintenance.html +6 -6
  105. package/dist/ui/operations/observability.html +6 -6
  106. package/dist/ui/operations/previews.html +6 -6
  107. package/dist/ui/operations/queue.html +6 -6
  108. package/dist/ui/operations/regions.html +6 -6
  109. package/dist/ui/operations/releases.html +6 -6
  110. package/dist/ui/operations/spend.html +6 -6
  111. package/dist/ui/operations/workloads.html +6 -6
  112. package/dist/ui/security.html +2 -2
  113. package/dist/ui/server/actions.html +5 -5
  114. package/dist/ui/server/activity.html +1 -1
  115. package/dist/ui/server/capacity.html +6 -6
  116. package/dist/ui/server/database.html +5 -5
  117. package/dist/ui/server/deployments.html +5 -5
  118. package/dist/ui/server/diagnostics.html +2 -2
  119. package/dist/ui/server/firewall.html +6 -6
  120. package/dist/ui/server/fleet.html +6 -6
  121. package/dist/ui/server/logs.html +6 -6
  122. package/dist/ui/server/metrics.html +5 -5
  123. package/dist/ui/server/security.html +2 -2
  124. package/dist/ui/server/services.html +2 -2
  125. package/dist/ui/server/sites.html +6 -6
  126. package/dist/ui/server/ssh-keys.html +6 -6
  127. package/dist/ui/server/team.html +6 -6
  128. package/dist/ui/server/terminal.html +2 -2
  129. package/dist/ui/serverless/alarms.html +6 -6
  130. package/dist/ui/serverless/assets.html +2 -2
  131. package/dist/ui/serverless/cost.html +2 -2
  132. package/dist/ui/serverless/data.html +6 -6
  133. package/dist/ui/serverless/deployments.html +2 -2
  134. package/dist/ui/serverless/firewall.html +2 -2
  135. package/dist/ui/serverless/functions.html +6 -6
  136. package/dist/ui/serverless/logs.html +6 -6
  137. package/dist/ui/serverless/metrics.html +2 -2
  138. package/dist/ui/serverless/queues.html +6 -6
  139. package/dist/ui/serverless/secrets.html +6 -6
  140. package/dist/ui/serverless/traces.html +6 -6
  141. package/dist/ui/serverless.html +6 -6
  142. package/dist/ui-src/src/charts.ts +1 -1
  143. package/dist/ui-src/src/topology.ts +1 -1
  144. package/package.json +3 -3
  145. package/dist/bin/chunk-1s4dny8d.js +0 -1
  146. package/dist/bin/chunk-4w80w3sm.js +0 -1
  147. package/dist/bin/chunk-4yntpqbe.js +0 -1
  148. package/dist/bin/chunk-7x0hrna6.js +0 -1
  149. package/dist/bin/chunk-971tfc6m.js +0 -1
  150. package/dist/bin/chunk-dpw8x3sr.js +0 -1
  151. package/dist/bin/chunk-h785hw6a.js +0 -1
  152. package/dist/bin/chunk-jyggrdh2.js +0 -1
  153. package/dist/bin/chunk-q524s7cx.js +0 -1
  154. package/dist/bin/chunk-q9gpw6wv.js +0 -1
  155. package/dist/bin/chunk-r6cvc2pr.js +0 -1
  156. package/dist/bin/chunk-rh2sqtew.js +0 -1
  157. package/dist/bin/chunk-tkzpbb7n.js +0 -1
  158. package/dist/bin/chunk-v78r5tx0.js +0 -1
  159. package/dist/bin/chunk-v7f4c62s.js +0 -1
  160. package/dist/bin/chunk-vx649y7t.js +0 -1
  161. package/dist/chunk-atny1wp9.js +0 -1
  162. package/dist/chunk-fdexq9e1.js +0 -1
  163. package/dist/chunk-hn2v0b0d.js +0 -1
  164. package/dist/chunk-v46b25w9.js +0 -1
  165. /package/dist/bin/{chunk-bckm6fre.js → chunk-pdw0qjq1.js} +0 -0
  166. /package/dist/{chunk-30h9rgfn.js → chunk-crpjqnjb.js} +0 -0
@@ -10,7 +10,7 @@ import{createRequire as qa}from"node:module";import{isAbsolute as $t,join as gt,
10
10
  `),j=[C,f,b,await ut(B)].join(`
11
11
  `),J=await Sa(l,S,y,h,j,v??ke);return w.searchParams.set("X-Amz-Signature",J),{url:w.toString(),method:i,headers:{},body:s||void 0}}function rf(a){let{url:n,method:i="GET",expiresIn:s=3600,...c}=a,l=Math.min(s,604800);return x({...c,url:n,method:i,signQuery:!0,expiresIn:l}).url}async function uy(a){let{url:n,method:i="GET",expiresIn:s=3600,...c}=a,l=Math.min(s,604800);return(await Cp({...c,url:n,method:i,signQuery:!0,expiresIn:l})).url}function ga(a){return Object.keys(a).sort().map((n)=>`${n.toLowerCase()}:${a[n].trim().replace(/\s+/g," ")}`).join(`
12
12
  `)+`
13
- `}function ha(a){return Object.keys(a).sort().map((n)=>n.toLowerCase()).join(";")}function ft(a){let n=[];return a.forEach((i,s)=>{n.push([kt(s),kt(i)])}),n.sort((i,s)=>{if(i[0]<s[0])return-1;if(i[0]>s[0])return 1;if(i[1]<s[1])return-1;if(i[1]>s[1])return 1;return 0}),n.map(([i,s])=>`${i}=${s}`).join("&")}function St(a){return a.split("/").map((n)=>kt(n)).join("/")}function kt(a){return encodeURIComponent(a).replace(/[!'()*]/g,(n)=>`%${n.charCodeAt(0).toString(16).toUpperCase()}`)}function Je(a){if(!Oe)throw Error("Synchronous hash not available in browser. Use signRequestAsync() instead.");return Oe.createHash("sha256").update(a,"utf8").digest("hex")}function Ge(a,n){if(!Oe)throw Error("Synchronous hmac not available in browser. Use signRequestAsync() instead.");return Oe.createHmac("sha256",a).update(n,"utf8").digest()}async function ut(a){let n=new TextEncoder().encode(a),i=await crypto.subtle.digest("SHA-256",n);return ya(new Uint8Array(i))}async function Ve(a,n){let i=new TextEncoder,s=typeof a==="string"?i.encode(a):a,c=i.encode(n),l=await crypto.subtle.importKey("raw",s.buffer,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),u=await crypto.subtle.sign("HMAC",l,c.buffer);return new Uint8Array(u)}function ya(a){return Array.from(a).map((n)=>n.toString(16).padStart(2,"0")).join("")}function fa(a,n,i,s,c,l){let u=`${a}:${n}:${i}:${s}`,h=l.get(u);if(!h){let y=Ge(`AWS4${a}`,n),f=Ge(y,i),S=Ge(f,s);if(h=Ge(S,"aws4_request"),l.size>=Aa){let b=l.keys().next().value;if(b)l.delete(b)}l.set(u,h)}return Ge(h,c).toString("hex")}async function Sa(a,n,i,s,c,l){let u=`${a}:${n}:${i}:${s}`,h=l.get(u);if(!h){let f=await Ve(`AWS4${a}`,n),S=await Ve(f,i),b=await Ve(S,s);if(h=await Ve(b,"aws4_request"),l.size>=Aa){let C=l.keys().next().value;if(C)l.delete(C)}l.set(u,h)}let y=await Ve(h,c);return ya(y)}function ba(a,n){return n.includes(a)}function mt(a,n,i){let s=n*Math.pow(2,a),c=Math.random()*0.3*s;return Math.min(s+c,i)}function pt(a){return new Promise((n)=>setTimeout(n,a))}async function nf(a,n){let{maxRetries:i=3,initialDelayMs:s=100,maxDelayMs:c=5000,retryableStatusCodes:l=[429,500,502,503,504],timeoutMs:u=30000}=n??{},h,y;for(let f=0;f<=i;f++){let S=x(a),b={method:S.method,headers:S.headers};if(S.body)b.body=S.body;let C=new AbortController,T=setTimeout(()=>C.abort(),u);b.signal=C.signal;try{let v=await fetch(S.url,b);if(clearTimeout(T),y=v,v.ok)return v;if(f<i&&ba(v.status,l)){let R=mt(f,s,c);await pt(R);continue}let w=await v.text();throw Error(`AWS API request failed (${v.status}): ${w}`)}catch(v){if(clearTimeout(T),h=v,v instanceof Error&&v.name==="AbortError")h=Error(`Request timed out after ${u}ms`);if(f<i&&!(v instanceof Error&&v.message.includes("AWS API request failed"))){let w=mt(f,s,c);await pt(w);continue}throw h}}throw h??Error("Request failed after retries")}async function py(a){return nf(a,{maxRetries:0})}async function gy(a,n){let{maxRetries:i=3,initialDelayMs:s=100,maxDelayMs:c=5000,retryableStatusCodes:l=[429,500,502,503,504],timeoutMs:u=30000}=n??{},h;for(let y=0;y<=i;y++){let f=await Cp(a),S={method:f.method,headers:f.headers};if(f.body)S.body=f.body;let b=new AbortController,C=setTimeout(()=>b.abort(),u);S.signal=b.signal;try{let T=await fetch(f.url,S);if(clearTimeout(C),T.ok)return T;if(y<i&&ba(T.status,l)){let w=mt(y,s,c);await pt(w);continue}let v=await T.text();throw Error(`AWS API request failed (${T.status}): ${v}`)}catch(T){if(clearTimeout(C),h=T,T instanceof Error&&T.name==="AbortError")h=Error(`Request timed out after ${u}ms`);if(y<i&&!(T instanceof Error&&T.message.includes("AWS API request failed"))){let v=mt(y,s,c);await pt(v);continue}throw h}}throw h??Error("Request failed after retries")}async function my(a){let n=await a.text(),i={},s=/<(\w+)>([^<]+)<\/\1>/g,c;while((c=s.exec(n))!==null){let[,l,u]=c;i[l]=u}return i}async function hy(a){return await a.json()}function fy(){ke.clear()}function Ay(){return ke.size}function yy(){return Oe!==void 0}function Iy(){return typeof crypto<"u"&&typeof crypto.subtle<"u"}var Oe,ke,Aa=100,Ca,et=Ya(async()=>{try{Oe=await import("node:crypto")}catch{}ke=new Map,Ca={appstream2:"appstream",cloudhsmv2:"cloudhsm",email:"ses",marketplace:"aws-marketplace",mobile:"AWSMobileHubService",pinpoint:"mobiletargeting",queue:"sqs","git-codecommit":"codecommit","mturk-requester-sandbox":"mturk-requester","personalize-runtime":"personalize"}}),Sy={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}},Cy={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}}}},bp=".ts-cloud",Ep="TS_CLOUD_STATE_DIR",Ot=null;function Wc(a){Ot=a?.trim()||null}function Jc(){return Boolean(process.env[Ep]?.trim()||Ot)}function Qs(){return process.env[Ep]?.trim()||Ot||bp}function _(...a){return gt(Qs(),...a)}function d(a,...n){let i=Qs();return $t(i)?gt(i,...n):gt(a,i,...n)}function Xc(a,n=process.cwd()){let i=(c,l)=>{let u=tr(c,l);return u===""||!u.startsWith("..")&&!$t(u)},s=$t(a)?a:gt(n,a);return i(d(n),s)}function vp(a){let n=a.infrastructure?.compute!=null,i=Object.values(a.environments??{}).some((s)=>s?.app!=null);return{server:n,serverless:i}}function O(a){if(a.mode==="server"||a.mode==="serverless")return a.mode;let{serverless:n}=vp(a);return n?"serverless":"server"}function Yc(a){let{server:n,serverless:i}=vp(a);if(n&&i)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(a.mode==="server"&&i&&!n)return"Config sets `mode: 'server'` but declares a serverless app (`environments.<env>.app`). Remove the app or change the mode.";if(a.mode==="serverless"&&n&&!i)return"Config sets `mode: 'serverless'` but declares a server (`infrastructure.compute`). Remove the compute block or change the mode.";return null}function p(a){return a.infrastructure?.appDatabase??a.infrastructure?.compute?.database}function ar(a){return typeof a==="object"&&a!==null?a:{}}function sf(a){return a===!0||typeof a==="object"&&a!==null}function rr(a,n){let i=n?a.environments?.[n]:void 0;if(i?.domain)return i.domain;let s=Object.values(a.sites??{}),c=a.sites?.main?.domain??s.find((l)=>l.domain)?.domain;if(c)return c;return`${a.project?.slug??"app"}.local`}function nr(a){let n=a.indexOf(".");return n>0?a.slice(n+1):void 0}function ui(a,n={}){let i=a.infrastructure?.compute?.managedServices?.mail,s=ar(i),c=n.environmentType??(n.environment?a.environments?.[n.environment]?.type:void 0),l=s.mode??(c==="production"?"server":"catcher"),u=l==="server",h=rr(a,n.environment),y=s.hostname??(u?`mail.${h}`:"localhost"),f=s.ports??{},S=u?{smtp:f.smtp??25,submission:f.submission??587,submissions:f.submissions??465,imap:f.imap??143,imaps:f.imaps??993,webmail:f.webmail??8080,managesieve:f.managesieve}:{smtp:f.smtp??1025,submission:f.submission,submissions:f.submissions,imap:f.imap,imaps:f.imaps,webmail:f.webmail??8025,managesieve:f.managesieve},b=s.tls??{},C=b.enabled??u,T=!!(b.certPath&&b.keyPath),v=(s.accounts??[]).map((K)=>({address:K.address,password:K.password})),w=typeof s.dkim==="object"&&s.dkim!==null?s.dkim:{},R=s.dkim===!1?!1:s.dkim===!0||u,k=typeof s.webmail==="object"&&s.webmail!==null?s.webmail:{},W=s.webmail===!1?!1:k.enabled??!0,P=s.spam??{},V=s.delivery??(u?"direct":"none"),B=s.expose??u,j=nr(y),J=[...new Set([y,...j?[j]:[],...s.domains??[]])];return{enabled:sf(i),mode:l,version:s.version,hostname:y,domains:J,ports:S,tls:{enabled:C,acme:C&&!T&&(b.acme??!0),certPath:b.certPath,keyPath:b.keyPath,requireForAuth:b.requireForAuth??(C&&u),acmeEmail:b.acmeEmail??v[0]?.address},dkim:{enabled:R,selector:w.selector??"default",rotate:w.rotate??!1,rotateIntervalDays:w.rotateIntervalDays??90},webmail:{enabled:W,port:k.port??S.webmail,domain:k.domain},delivery:V,sesRegion:s.sesRegion??"us-east-1",accounts:v,storagePath:s.storagePath??"/var/lib/mail",maxMessageSize:s.maxMessageSize??26214400,spam:{enabled:P.enabled??u,enforce:P.enforce??!1,junkScore:P.junkScore??5,rejectScore:P.rejectScore??12,dnsbl:P.dnsbl??u,greylist:P.greylist??!1},webhookUrl:s.webhookUrl,expose:B,bindAddress:B?"0.0.0.0":"127.0.0.1"}}function Zc(a){if(!a.enabled||!a.expose)return[];let n=[a.ports.smtp,a.ports.submission,a.ports.submissions,a.ports.imap,a.ports.imaps,a.ports.managesieve].filter((i)=>typeof i==="number");if(a.webmail.enabled&&!a.webmail.domain)n.push(a.webmail.port);return[...new Set(n)].sort((i,s)=>i-s)}function ed(a){if(!a.enabled)return{};let n=a.ports.submission??a.ports.smtp,i={MAIL_MAILER:"smtp",MAIL_HOST:"127.0.0.1",MAIL_PORT:String(n)};if(a.mode==="server"){i.MAIL_ENCRYPTION=a.tls.enabled?"tls":"null";let s=a.accounts[0];if(s)i.MAIL_USERNAME=s.address,i.MAIL_PASSWORD=s.password}else i.MAIL_ENCRYPTION="null",i.MAIL_USERNAME="null",i.MAIL_PASSWORD="null";return i}function ce(a){if(a.cloud?.provider)return a.cloud.provider;if(a.ssh?.hosts?.length)return"ssh";if(a.hetzner?.apiToken)return"hetzner";return"aws"}class td{template;constructor(a){this.template={AWSTemplateFormatVersion:"2010-09-09",Description:a,Resources:{}}}addResource(a,n){return this.template.Resources[a]=n,this}addResources(a){return Object.assign(this.template.Resources,a),this}addParameter(a,n){if(!this.template.Parameters)this.template.Parameters={};return this.template.Parameters[a]=n,this}addOutput(a,n){if(!this.template.Outputs)this.template.Outputs={};return this.template.Outputs[a]=n,this}hasResource(a){return a in this.template.Resources}getResources(){return this.template.Resources}build(){return this.template}toJSON(a=!0){return JSON.stringify(this.template,null,a?2:0)}toYAML(){return this.convertToYAML(this.template)}convertToYAML(a,n=0){let i=" ".repeat(n),s="";for(let[c,l]of Object.entries(a)){if(l===null||l===void 0)continue;if(typeof l==="object"&&!Array.isArray(l))s+=`${i}${c}:
13
+ `}function ha(a){return Object.keys(a).sort().map((n)=>n.toLowerCase()).join(";")}function ft(a){let n=[];return a.forEach((i,s)=>{n.push([kt(s),kt(i)])}),n.sort((i,s)=>{if(i[0]<s[0])return-1;if(i[0]>s[0])return 1;if(i[1]<s[1])return-1;if(i[1]>s[1])return 1;return 0}),n.map(([i,s])=>`${i}=${s}`).join("&")}function St(a){return a.split("/").map((n)=>kt(n)).join("/")}function kt(a){return encodeURIComponent(a).replace(/[!'()*]/g,(n)=>`%${n.charCodeAt(0).toString(16).toUpperCase()}`)}function Je(a){if(!Oe)throw Error("Synchronous hash not available in browser. Use signRequestAsync() instead.");return Oe.createHash("sha256").update(a,"utf8").digest("hex")}function Fe(a,n){if(!Oe)throw Error("Synchronous hmac not available in browser. Use signRequestAsync() instead.");return Oe.createHmac("sha256",a).update(n,"utf8").digest()}async function ut(a){let n=new TextEncoder().encode(a),i=await crypto.subtle.digest("SHA-256",n);return ya(new Uint8Array(i))}async function Ve(a,n){let i=new TextEncoder,s=typeof a==="string"?i.encode(a):a,c=i.encode(n),l=await crypto.subtle.importKey("raw",s.buffer,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),u=await crypto.subtle.sign("HMAC",l,c.buffer);return new Uint8Array(u)}function ya(a){return Array.from(a).map((n)=>n.toString(16).padStart(2,"0")).join("")}function fa(a,n,i,s,c,l){let u=`${a}:${n}:${i}:${s}`,h=l.get(u);if(!h){let y=Fe(`AWS4${a}`,n),f=Fe(y,i),S=Fe(f,s);if(h=Fe(S,"aws4_request"),l.size>=Aa){let b=l.keys().next().value;if(b)l.delete(b)}l.set(u,h)}return Fe(h,c).toString("hex")}async function Sa(a,n,i,s,c,l){let u=`${a}:${n}:${i}:${s}`,h=l.get(u);if(!h){let f=await Ve(`AWS4${a}`,n),S=await Ve(f,i),b=await Ve(S,s);if(h=await Ve(b,"aws4_request"),l.size>=Aa){let C=l.keys().next().value;if(C)l.delete(C)}l.set(u,h)}let y=await Ve(h,c);return ya(y)}function ba(a,n){return n.includes(a)}function mt(a,n,i){let s=n*Math.pow(2,a),c=Math.random()*0.3*s;return Math.min(s+c,i)}function pt(a){return new Promise((n)=>setTimeout(n,a))}async function nf(a,n){let{maxRetries:i=3,initialDelayMs:s=100,maxDelayMs:c=5000,retryableStatusCodes:l=[429,500,502,503,504],timeoutMs:u=30000}=n??{},h,y;for(let f=0;f<=i;f++){let S=x(a),b={method:S.method,headers:S.headers};if(S.body)b.body=S.body;let C=new AbortController,T=setTimeout(()=>C.abort(),u);b.signal=C.signal;try{let v=await fetch(S.url,b);if(clearTimeout(T),y=v,v.ok)return v;if(f<i&&ba(v.status,l)){let R=mt(f,s,c);await pt(R);continue}let w=await v.text();throw Error(`AWS API request failed (${v.status}): ${w}`)}catch(v){if(clearTimeout(T),h=v,v instanceof Error&&v.name==="AbortError")h=Error(`Request timed out after ${u}ms`);if(f<i&&!(v instanceof Error&&v.message.includes("AWS API request failed"))){let w=mt(f,s,c);await pt(w);continue}throw h}}throw h??Error("Request failed after retries")}async function py(a){return nf(a,{maxRetries:0})}async function gy(a,n){let{maxRetries:i=3,initialDelayMs:s=100,maxDelayMs:c=5000,retryableStatusCodes:l=[429,500,502,503,504],timeoutMs:u=30000}=n??{},h;for(let y=0;y<=i;y++){let f=await Cp(a),S={method:f.method,headers:f.headers};if(f.body)S.body=f.body;let b=new AbortController,C=setTimeout(()=>b.abort(),u);S.signal=b.signal;try{let T=await fetch(f.url,S);if(clearTimeout(C),T.ok)return T;if(y<i&&ba(T.status,l)){let w=mt(y,s,c);await pt(w);continue}let v=await T.text();throw Error(`AWS API request failed (${T.status}): ${v}`)}catch(T){if(clearTimeout(C),h=T,T instanceof Error&&T.name==="AbortError")h=Error(`Request timed out after ${u}ms`);if(y<i&&!(T instanceof Error&&T.message.includes("AWS API request failed"))){let v=mt(y,s,c);await pt(v);continue}throw h}}throw h??Error("Request failed after retries")}async function my(a){let n=await a.text(),i={},s=/<(\w+)>([^<]+)<\/\1>/g,c;while((c=s.exec(n))!==null){let[,l,u]=c;i[l]=u}return i}async function hy(a){return await a.json()}function fy(){ke.clear()}function Ay(){return ke.size}function yy(){return Oe!==void 0}function Iy(){return typeof crypto<"u"&&typeof crypto.subtle<"u"}var Oe,ke,Aa=100,Ca,et=Ya(async()=>{try{Oe=await import("node:crypto")}catch{}ke=new Map,Ca={appstream2:"appstream",cloudhsmv2:"cloudhsm",email:"ses",marketplace:"aws-marketplace",mobile:"AWSMobileHubService",pinpoint:"mobiletargeting",queue:"sqs","git-codecommit":"codecommit","mturk-requester-sandbox":"mturk-requester","personalize-runtime":"personalize"}}),Sy={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}},Cy={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}}}},bp=".ts-cloud",Ep="TS_CLOUD_STATE_DIR",Ot=null;function Wc(a){Ot=a?.trim()||null}function Jc(){return Boolean(process.env[Ep]?.trim()||Ot)}function Qs(){return process.env[Ep]?.trim()||Ot||bp}function _(...a){return gt(Qs(),...a)}function d(a,...n){let i=Qs();return $t(i)?gt(i,...n):gt(a,i,...n)}function Xc(a,n=process.cwd()){let i=(c,l)=>{let u=tr(c,l);return u===""||!u.startsWith("..")&&!$t(u)},s=$t(a)?a:gt(n,a);return i(d(n),s)}function vp(a){let n=a.infrastructure?.compute!=null,i=Object.values(a.environments??{}).some((s)=>s?.app!=null);return{server:n,serverless:i}}function O(a){if(a.mode==="server"||a.mode==="serverless")return a.mode;let{serverless:n}=vp(a);return n?"serverless":"server"}function Yc(a){let{server:n,serverless:i}=vp(a);if(n&&i)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(a.mode==="server"&&i&&!n)return"Config sets `mode: 'server'` but declares a serverless app (`environments.<env>.app`). Remove the app or change the mode.";if(a.mode==="serverless"&&n&&!i)return"Config sets `mode: 'serverless'` but declares a server (`infrastructure.compute`). Remove the compute block or change the mode.";return null}function p(a){return a.infrastructure?.appDatabase??a.infrastructure?.compute?.database}function ar(a){return typeof a==="object"&&a!==null?a:{}}function sf(a){return a===!0||typeof a==="object"&&a!==null}function rr(a,n){let i=n?a.environments?.[n]:void 0;if(i?.domain)return i.domain;let s=Object.values(a.sites??{}),c=a.sites?.main?.domain??s.find((l)=>l.domain)?.domain;if(c)return c;return`${a.project?.slug??"app"}.local`}function nr(a){let n=a.indexOf(".");return n>0?a.slice(n+1):void 0}function ui(a,n={}){let i=a.infrastructure?.compute?.managedServices?.mail,s=ar(i),c=n.environmentType??(n.environment?a.environments?.[n.environment]?.type:void 0),l=s.mode??(c==="production"?"server":"catcher"),u=l==="server",h=rr(a,n.environment),y=s.hostname??(u?`mail.${h}`:"localhost"),f=s.ports??{},S=u?{smtp:f.smtp??25,submission:f.submission??587,submissions:f.submissions??465,imap:f.imap??143,imaps:f.imaps??993,webmail:f.webmail??8080,managesieve:f.managesieve}:{smtp:f.smtp??1025,submission:f.submission,submissions:f.submissions,imap:f.imap,imaps:f.imaps,webmail:f.webmail??8025,managesieve:f.managesieve},b=s.tls??{},C=b.enabled??u,T=!!(b.certPath&&b.keyPath),v=(s.accounts??[]).map((K)=>({address:K.address,password:K.password})),w=typeof s.dkim==="object"&&s.dkim!==null?s.dkim:{},R=s.dkim===!1?!1:s.dkim===!0||u,k=typeof s.webmail==="object"&&s.webmail!==null?s.webmail:{},W=s.webmail===!1?!1:k.enabled??!0,P=s.spam??{},V=s.delivery??(u?"direct":"none"),B=s.expose??u,j=nr(y),J=[...new Set([y,...j?[j]:[],...s.domains??[]])];return{enabled:sf(i),mode:l,version:s.version,hostname:y,domains:J,ports:S,tls:{enabled:C,acme:C&&!T&&(b.acme??!0),certPath:b.certPath,keyPath:b.keyPath,requireForAuth:b.requireForAuth??(C&&u),acmeEmail:b.acmeEmail??v[0]?.address},dkim:{enabled:R,selector:w.selector??"default",rotate:w.rotate??!1,rotateIntervalDays:w.rotateIntervalDays??90},webmail:{enabled:W,port:k.port??S.webmail,domain:k.domain},delivery:V,sesRegion:s.sesRegion??"us-east-1",accounts:v,storagePath:s.storagePath??"/var/lib/mail",maxMessageSize:s.maxMessageSize??26214400,spam:{enabled:P.enabled??u,enforce:P.enforce??!1,junkScore:P.junkScore??5,rejectScore:P.rejectScore??12,dnsbl:P.dnsbl??u,greylist:P.greylist??!1},webhookUrl:s.webhookUrl,expose:B,bindAddress:B?"0.0.0.0":"127.0.0.1"}}function Zc(a){if(!a.enabled||!a.expose)return[];let n=[a.ports.smtp,a.ports.submission,a.ports.submissions,a.ports.imap,a.ports.imaps,a.ports.managesieve].filter((i)=>typeof i==="number");if(a.webmail.enabled&&!a.webmail.domain)n.push(a.webmail.port);return[...new Set(n)].sort((i,s)=>i-s)}function ed(a){if(!a.enabled)return{};let n=a.ports.submission??a.ports.smtp,i={MAIL_MAILER:"smtp",MAIL_HOST:"127.0.0.1",MAIL_PORT:String(n)};if(a.mode==="server"){i.MAIL_ENCRYPTION=a.tls.enabled?"tls":"null";let s=a.accounts[0];if(s)i.MAIL_USERNAME=s.address,i.MAIL_PASSWORD=s.password}else i.MAIL_ENCRYPTION="null",i.MAIL_USERNAME="null",i.MAIL_PASSWORD="null";return i}function ce(a){if(a.cloud?.provider)return a.cloud.provider;if(a.ssh?.hosts?.length)return"ssh";if(a.hetzner?.apiToken)return"hetzner";return"aws"}class td{template;constructor(a){this.template={AWSTemplateFormatVersion:"2010-09-09",Description:a,Resources:{}}}addResource(a,n){return this.template.Resources[a]=n,this}addResources(a){return Object.assign(this.template.Resources,a),this}addParameter(a,n){if(!this.template.Parameters)this.template.Parameters={};return this.template.Parameters[a]=n,this}addOutput(a,n){if(!this.template.Outputs)this.template.Outputs={};return this.template.Outputs[a]=n,this}hasResource(a){return a in this.template.Resources}getResources(){return this.template.Resources}build(){return this.template}toJSON(a=!0){return JSON.stringify(this.template,null,a?2:0)}toYAML(){return this.convertToYAML(this.template)}convertToYAML(a,n=0){let i=" ".repeat(n),s="";for(let[c,l]of Object.entries(a)){if(l===null||l===void 0)continue;if(typeof l==="object"&&!Array.isArray(l))s+=`${i}${c}:
14
14
  ${this.convertToYAML(l,n+1)}`;else if(Array.isArray(l)){s+=`${i}${c}:
15
15
  `;for(let u of l)if(typeof u==="object")s+=`${i} -
16
16
  ${this.convertToYAML(u,n+2)}`;else s+=`${i} - ${u}
@@ -20,7 +20,7 @@ ${this.convertToYAML(u,n+2)}`;else s+=`${i} - ${u}
20
20
  `),n.join(`
21
21
  `);if(n.push(`Total changes: ${a.summary.totalChanges}`),n.push(`Requires replacement: ${a.summary.requiresReplacement?"Yes":"No"}
22
22
  `),a.summary.dangerousChanges.length>0){n.push("⚠️ DANGEROUS CHANGES DETECTED:");for(let i of a.summary.dangerousChanges)n.push(` • ${i}`);n.push("")}if(a.added.length>0){n.push(`✅ Resources to Add (${a.added.length}):`);for(let i of a.added)n.push(` + ${i.logicalId} (${i.resourceType})`);n.push("")}if(a.removed.length>0){n.push(`❌ Resources to Remove (${a.removed.length}):`);for(let i of a.removed)n.push(` - ${i.logicalId} (${i.resourceType})`);n.push("")}if(a.replaced.length>0){n.push(`\uD83D\uDD04 Resources to Replace (${a.replaced.length}):`);for(let i of a.replaced){if(n.push(` ~ ${i.logicalId} (${i.resourceType})`),i.reason)n.push(` Reason: ${i.reason}`);if(i.changes){for(let s of i.changes.slice(0,3))n.push(` • ${s.path}: ${JSON.stringify(s.oldValue)} → ${JSON.stringify(s.newValue)}`);if(i.changes.length>3)n.push(` ... and ${i.changes.length-3} more changes`)}}n.push("")}if(a.updated.length>0){n.push(`\uD83D\uDCDD Resources to Update (${a.updated.length}):`);for(let i of a.updated)if(n.push(` ~ ${i.logicalId} (${i.resourceType})`),i.changes){for(let s of i.changes.slice(0,3))n.push(` • ${s.path}: ${JSON.stringify(s.oldValue)} → ${JSON.stringify(s.newValue)}`);if(i.changes.length>3)n.push(` ... and ${i.changes.length-3} more changes`)}n.push("")}if(a.unchanged.length>0)n.push(`⚪ Unchanged Resources (${a.unchanged.length})`);return n.join(`
23
- `)}class Se{static createBucket(a){let{name:n,bucketName:i,slug:s,environment:c,public:l=!1,versioning:u=!1,website:h=!1,encryption:y=!0,intelligentTiering:f=!1,cors:S,lifecycleRules:b}=a,C=i??r({slug:s,environment:c,resourceType:"s3",suffix:n}),T=t(C),v={Type:"AWS::S3::Bucket",Properties:{BucketName:C}};if(y)v.Properties.BucketEncryption={ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]};if(u)v.Properties.VersioningConfiguration={Status:"Enabled"};if(h)v.Properties.WebsiteConfiguration={IndexDocument:"index.html",ErrorDocument:"error.html"};if(!l)v.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0};if(S&&S.length>0)v.Properties.CorsConfiguration={CorsRules:S.map((R)=>({AllowedOrigins:R.allowedOrigins,AllowedMethods:R.allowedMethods,AllowedHeaders:R.allowedHeaders,MaxAge:R.maxAge}))};if(b&&b.length>0)v.Properties.LifecycleConfiguration={Rules:b.map((R)=>({Id:R.id,Status:R.enabled?"Enabled":"Disabled",ExpirationInDays:R.expirationDays,Transitions:R.transitions?.map((k)=>({TransitionInDays:k.days,StorageClass:k.storageClass}))}))};if(f&&b){let R={id:"IntelligentTieringRule",enabled:!0,transitions:[{days:0,storageClass:"INTELLIGENT_TIERING"}]};if(!v.Properties.LifecycleConfiguration)v.Properties.LifecycleConfiguration={Rules:[]};v.Properties.LifecycleConfiguration.Rules.push({Id:R.id,Status:"Enabled",Transitions:R.transitions?.map((k)=>({TransitionInDays:k.days,StorageClass:k.storageClass}))})}let w;if(l)w={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:N.Ref(T),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadGetObject",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[N.Join("",[N.GetAtt(T,"Arn"),"/*"])]}]}}};return{bucket:v,bucketPolicy:w,logicalId:T}}static enableVersioning(a){if(!a.Properties)a.Properties={};return a.Properties.VersioningConfiguration={Status:"Enabled"},a}static enableWebsiteHosting(a,n="index.html",i="error.html"){if(!a.Properties)a.Properties={};return a.Properties.WebsiteConfiguration={IndexDocument:n,ErrorDocument:i},a}static setLifecycleRules(a,n){if(!a.Properties)a.Properties={};return a.Properties.LifecycleConfiguration={Rules:n.map((i)=>({Id:i.id,Status:i.enabled?"Enabled":"Disabled",ExpirationInDays:i.expirationDays,Transitions:i.transitions?.map((s)=>({TransitionInDays:s.days,StorageClass:s.storageClass}))}))},a}static enableIntelligentTiering(a){if(!a.Properties)a.Properties={};if(!a.Properties.LifecycleConfiguration)a.Properties.LifecycleConfiguration={Rules:[]};return a.Properties.LifecycleConfiguration.Rules.push({Id:"IntelligentTieringRule",Status:"Enabled",Transitions:[{TransitionInDays:0,StorageClass:"INTELLIGENT_TIERING"}]}),a}static addLambdaNotification(a,n){if(!a.Properties)a.Properties={};if(!a.Properties.NotificationConfiguration)a.Properties.NotificationConfiguration={};if(!a.Properties.NotificationConfiguration.LambdaConfigurations)a.Properties.NotificationConfiguration.LambdaConfigurations=[];let i={Event:n.events[0],Function:n.functionArn};if(n.filter)i.Filter={S3Key:{Rules:[...n.filter.prefix?[{Name:"prefix",Value:n.filter.prefix}]:[],...n.filter.suffix?[{Name:"suffix",Value:n.filter.suffix}]:[]]}};for(let s of n.events){let c={...i,Event:s};a.Properties.NotificationConfiguration.LambdaConfigurations.push(c)}return a}static Notifications={onObjectCreated:(a)=>({functionArn:a,events:["s3:ObjectCreated:*"]}),onObjectRemoved:(a)=>({functionArn:a,events:["s3:ObjectRemoved:*"]}),onImageUpload:(a,n)=>({functionArn:a,events:["s3:ObjectCreated:*"],filter:{prefix:n,suffix:".jpg"}}),onFileType:(a,n,i)=>({functionArn:a,events:["s3:ObjectCreated:*"],filter:{prefix:i,suffix:n}}),onFolderUpload:(a,n)=>({functionArn:a,events:["s3:ObjectCreated:*"],filter:{prefix:n.endsWith("/")?n:`${n}/`}})};static createBackupPlan(a){let{name:n,slug:i,environment:s,bucketLogicalIds:c,retentionDays:l,schedule:u="cron(0 5 * * ? *)",vaultName:h,enableContinuousBackup:y=!1,moveToColdStorageAfterDays:f}=a,S=h||r({slug:i,environment:s,resourceType:"backup-vault",suffix:n}),b=t(S),C={Type:"AWS::Backup::BackupVault",Properties:{BackupVaultName:S}},T=r({slug:i,environment:s,resourceType:"backup-role",suffix:n}),v=t(T),w={Type:"AWS::IAM::Role",Properties:{RoleName:T,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"backup.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup","arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"]}},R=r({slug:i,environment:s,resourceType:"backup-plan",suffix:n}),k=t(R),W={DeleteAfterDays:l};if(f&&f<l)W.MoveToColdStorageAfterDays=f;let P={Type:"AWS::Backup::BackupPlan",Properties:{BackupPlan:{BackupPlanName:R,BackupPlanRule:[{RuleName:`${n}-daily-backup`,TargetBackupVault:N.Ref(b),ScheduleExpression:u,StartWindowMinutes:60,CompletionWindowMinutes:120,Lifecycle:W,EnableContinuousBackup:y}]}}},V=r({slug:i,environment:s,resourceType:"backup-selection",suffix:n}),B=t(V),j=c.map((K)=>N.GetAtt(K,"Arn")),J={Type:"AWS::Backup::BackupSelection",Properties:{BackupPlanId:N.Ref(k),BackupSelection:{SelectionName:V,IamRoleArn:N.GetAtt(v,"Arn"),Resources:j}}};return{vault:C,plan:P,selection:J,role:w,vaultLogicalId:b,planLogicalId:k,selectionLogicalId:B,roleLogicalId:v}}static BackupSchedules={HOURLY:"cron(0 * * * ? *)",DAILY_5AM:"cron(0 5 * * ? *)",DAILY_MIDNIGHT:"cron(0 0 * * ? *)",WEEKLY_SUNDAY:"cron(0 5 ? * SUN *)",WEEKLY_SATURDAY:"cron(0 5 ? * SAT *)",MONTHLY_FIRST:"cron(0 5 1 * ? *)",EVERY_12_HOURS:"cron(0 */12 * * ? *)",EVERY_6_HOURS:"cron(0 */6 * * ? *)"};static BackupRetention={ONE_DAY:1,ONE_WEEK:7,TWO_WEEKS:14,ONE_MONTH:30,THREE_MONTHS:90,SIX_MONTHS:180,ONE_YEAR:365,TWO_YEARS:730,FIVE_YEARS:1825,SEVEN_YEARS:2555};static createWwwRedirectBucket(a){let{slug:n,environment:i,sourceDomain:s,targetDomain:c,protocol:l="https"}=a,u=r({slug:n,environment:i,resourceType:"s3",suffix:"www-redirect"}),h=t(u),y={Type:"AWS::S3::Bucket",Properties:{BucketName:s,WebsiteConfiguration:{RedirectAllRequestsTo:{HostName:c,Protocol:l}},PublicAccessBlockConfiguration:{BlockPublicAcls:!1,BlockPublicPolicy:!1,IgnorePublicAcls:!1,RestrictPublicBuckets:!1}}},f={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:N.Ref(h),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadForRedirect",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[N.Join("",[N.GetAtt(h,"Arn"),"/*"])]}]}}};return{bucket:y,bucketPolicy:f,logicalId:h}}static createDocsBucket(a){let{slug:n,environment:i,domain:s}=a,c=s||r({slug:n,environment:i,resourceType:"s3",suffix:"docs"}),l=t(c);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:c,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},Tags:[{Key:"backup",Value:"weekly"}]}},logicalId:l}}static createEmailBucket(a){let{slug:n,environment:i}=a,s=r({slug:n,environment:i,resourceType:"s3",suffix:"email"}),c=t(s),l={Type:"AWS::S3::Bucket",Properties:{BucketName:s,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"EmailRetention",Status:"Enabled",ExpirationInDays:90,Transitions:[{TransitionInDays:30,StorageClass:"STANDARD_IA"}]}]}}},u={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:N.Ref(c),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowSESPuts",Effect:"Allow",Principal:{Service:"ses.amazonaws.com"},Action:"s3:PutObject",Resource:N.Join("",[N.GetAtt(c,"Arn"),"/*"]),Condition:{StringEquals:{"AWS:SourceAccount":N.Ref("AWS::AccountId")}}}]}}};return{bucket:l,bucketPolicy:u,logicalId:c}}static docsExist(a={}){let{projectRoot:n=process.cwd(),docsPaths:i=["docs","documentation","doc"]}=a;for(let s of i){let c=ve(n,s);if(je(c)){let l=["dist","build",".bunpress/dist","_site","out","public"];for(let u of l){let h=ve(c,u);if(je(h))try{if(or(h).length>0)return{exists:!0,path:c,hasDistFolder:!0,distPath:h}}catch{}}return{exists:!0,path:c,hasDistFolder:!1,distPath:null}}}return{exists:!1,path:null,hasDistFolder:!1,distPath:null}}static createDocsBucketIfExists(a){let n=Se.docsExist({projectRoot:a.projectRoot,docsPaths:a.docsPaths});if(!n.exists)return{bucket:null,logicalId:null,docsInfo:n};let i=Se.createDocsBucket({slug:a.slug,environment:a.environment,domain:a.domain});return{bucket:i.bucket,bucketPolicy:i.bucketPolicy,logicalId:i.logicalId,docsInfo:n}}static createPrivateBucket(a){let{slug:n,environment:i,enableVersioning:s=!0,retentionDays:c,encryptionKeyArn:l}=a,u=r({slug:n,environment:i,resourceType:"s3",suffix:"private"}),h=t(u);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:u,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:l?{SSEAlgorithm:"aws:kms",KMSMasterKeyID:l}:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},VersioningConfiguration:s?{Status:"Enabled"}:void 0,LifecycleConfiguration:c?{Rules:[{Id:"RetentionPolicy",Status:"Enabled",ExpirationInDays:c}]}:void 0,Tags:[{Key:"backup",Value:"daily"}]}},logicalId:h}}static checkSourcePaths(a={}){let{projectRoot:n=process.cwd(),paths:i={}}=a,s=i.web||"views/web/dist",c=i.docs||"docs/dist",l=i.private||"private";return{web:{exists:je(ve(n,s)),path:ve(n,s)},docs:{exists:je(ve(n,c)),path:ve(n,c)},private:{exists:je(ve(n,l)),path:ve(n,l)}}}static createDeploymentBuckets(a){let{slug:n,environment:i,domain:s,projectRoot:c,paths:l}=a,u=Se.checkSourcePaths({projectRoot:c,paths:l}),h={},y={web:!1,docs:!1,private:!1},f=Se.createBucket({name:"web",slug:n,environment:i,public:!1,versioning:!1,encryption:!0});if(h[f.logicalId]=f.bucket,y.web=!0,u.docs.exists){let S=Se.createDocsBucket({slug:n,environment:i,domain:s?`docs.${s}`:void 0});if(h[S.logicalId]=S.bucket,S.bucketPolicy)h[`${S.logicalId}Policy`]=S.bucketPolicy;y.docs=!0}if(u.private.exists){let S=Se.createPrivateBucket({slug:n,environment:i,enableVersioning:!0});h[S.logicalId]=S.bucket,y.private=!0}return{resources:h,created:y,sourcePaths:u}}}class Fe{static createRepository(a){let{name:n,slug:i,environment:s,scanOnPush:c=!0,imageMutability:l="MUTABLE",encryption:u="AES256",kmsKey:h,lifecyclePolicy:y,tags:f}=a,S=r({slug:i,environment:s,resourceType:"ecr",suffix:n}),b=t(S),C={Type:"AWS::ECR::Repository",Properties:{RepositoryName:S,ImageTagMutability:l,ImageScanningConfiguration:{ScanOnPush:c},EncryptionConfiguration:{EncryptionType:u,...h&&u==="KMS"?{KmsKey:h}:{}}}};if(y)C.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(Fe.generateLifecyclePolicy(y))};if(f)C.Properties.Tags=Object.entries(f).map(([T,v])=>({Key:T,Value:v}));return{repository:C,logicalId:b}}static generateLifecyclePolicy(a){let n=[];if(a.untaggedImageExpireDays!==void 0)n.push({rulePriority:1,description:"Delete untagged images",selection:{tagStatus:"untagged",countType:"sinceImagePushed",countNumber:a.untaggedImageExpireDays,countUnit:"days"},action:{type:"expire"}});if(a.maxImageCount!==void 0)n.push({rulePriority:n.length+1,description:"Keep only most recent images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:a.maxImageCount},action:{type:"expire"}});if(a.maxImageAgeDays!==void 0)n.push({rulePriority:n.length+1,description:"Delete images older than specified days",selection:{tagStatus:"any",countType:"sinceImagePushed",countNumber:a.maxImageAgeDays,countUnit:"days"},action:{type:"expire"}});return{rules:n}}static LifecyclePolicies={production:{maxImageCount:10,untaggedImageExpireDays:7},development:{maxImageCount:5,untaggedImageExpireDays:3},minimal:{maxImageCount:3,untaggedImageExpireDays:1},archive:{maxImageCount:50,untaggedImageExpireDays:30}};static enableImmutableTags(a){if(!a.Properties)a.Properties={};return a.Properties.ImageTagMutability="IMMUTABLE",a}static enableScanOnPush(a){if(!a.Properties)a.Properties={};return a.Properties.ImageScanningConfiguration={ScanOnPush:!0},a}static setLifecyclePolicy(a,n){if(!a.Properties)a.Properties={};return a.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(Fe.generateLifecyclePolicy(n))},a}static addCrossAccountAccess(a,n){if(!a.Properties)a.Properties={};return a.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"CrossAccountPull",Effect:"Allow",Principal:{AWS:n.map((i)=>`arn:aws:iam::${i}:root`)},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:BatchCheckLayerAvailability"]}]},a}static addLambdaAccess(a){if(!a.Properties)a.Properties={};return a.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"LambdaECRImageRetrievalPolicy",Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage"]}]},a}static generateBunDockerfile(a){let{baseImage:n="oven/bun:1-debian",serverPath:i,port:s=3000,additionalDirs:c=[],healthCheckEndpoint:l="/health",nodeCompatible:u=!1,envVars:h={},buildCommands:y=[],runCommand:f}=a,S=["app","config",...c],b=f||`bun run ${i}`,C=`# Multi-stage build for Bun application
23
+ `)}class Se{static createBucket(a){let{name:n,bucketName:i,slug:s,environment:c,public:l=!1,versioning:u=!1,website:h=!1,encryption:y=!0,intelligentTiering:f=!1,cors:S,lifecycleRules:b}=a,C=i??r({slug:s,environment:c,resourceType:"s3",suffix:n}),T=t(C),v={Type:"AWS::S3::Bucket",Properties:{BucketName:C}};if(y)v.Properties.BucketEncryption={ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]};if(u)v.Properties.VersioningConfiguration={Status:"Enabled"};if(h)v.Properties.WebsiteConfiguration={IndexDocument:"index.html",ErrorDocument:"error.html"};if(!l)v.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0};if(S&&S.length>0)v.Properties.CorsConfiguration={CorsRules:S.map((R)=>({AllowedOrigins:R.allowedOrigins,AllowedMethods:R.allowedMethods,AllowedHeaders:R.allowedHeaders,MaxAge:R.maxAge}))};if(b&&b.length>0)v.Properties.LifecycleConfiguration={Rules:b.map((R)=>({Id:R.id,Status:R.enabled?"Enabled":"Disabled",ExpirationInDays:R.expirationDays,Transitions:R.transitions?.map((k)=>({TransitionInDays:k.days,StorageClass:k.storageClass}))}))};if(f&&b){let R={id:"IntelligentTieringRule",enabled:!0,transitions:[{days:0,storageClass:"INTELLIGENT_TIERING"}]};if(!v.Properties.LifecycleConfiguration)v.Properties.LifecycleConfiguration={Rules:[]};v.Properties.LifecycleConfiguration.Rules.push({Id:R.id,Status:"Enabled",Transitions:R.transitions?.map((k)=>({TransitionInDays:k.days,StorageClass:k.storageClass}))})}let w;if(l)w={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:N.Ref(T),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadGetObject",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[N.Join("",[N.GetAtt(T,"Arn"),"/*"])]}]}}};return{bucket:v,bucketPolicy:w,logicalId:T}}static enableVersioning(a){if(!a.Properties)a.Properties={};return a.Properties.VersioningConfiguration={Status:"Enabled"},a}static enableWebsiteHosting(a,n="index.html",i="error.html"){if(!a.Properties)a.Properties={};return a.Properties.WebsiteConfiguration={IndexDocument:n,ErrorDocument:i},a}static setLifecycleRules(a,n){if(!a.Properties)a.Properties={};return a.Properties.LifecycleConfiguration={Rules:n.map((i)=>({Id:i.id,Status:i.enabled?"Enabled":"Disabled",ExpirationInDays:i.expirationDays,Transitions:i.transitions?.map((s)=>({TransitionInDays:s.days,StorageClass:s.storageClass}))}))},a}static enableIntelligentTiering(a){if(!a.Properties)a.Properties={};if(!a.Properties.LifecycleConfiguration)a.Properties.LifecycleConfiguration={Rules:[]};return a.Properties.LifecycleConfiguration.Rules.push({Id:"IntelligentTieringRule",Status:"Enabled",Transitions:[{TransitionInDays:0,StorageClass:"INTELLIGENT_TIERING"}]}),a}static addLambdaNotification(a,n){if(!a.Properties)a.Properties={};if(!a.Properties.NotificationConfiguration)a.Properties.NotificationConfiguration={};if(!a.Properties.NotificationConfiguration.LambdaConfigurations)a.Properties.NotificationConfiguration.LambdaConfigurations=[];let i={Event:n.events[0],Function:n.functionArn};if(n.filter)i.Filter={S3Key:{Rules:[...n.filter.prefix?[{Name:"prefix",Value:n.filter.prefix}]:[],...n.filter.suffix?[{Name:"suffix",Value:n.filter.suffix}]:[]]}};for(let s of n.events){let c={...i,Event:s};a.Properties.NotificationConfiguration.LambdaConfigurations.push(c)}return a}static Notifications={onObjectCreated:(a)=>({functionArn:a,events:["s3:ObjectCreated:*"]}),onObjectRemoved:(a)=>({functionArn:a,events:["s3:ObjectRemoved:*"]}),onImageUpload:(a,n)=>({functionArn:a,events:["s3:ObjectCreated:*"],filter:{prefix:n,suffix:".jpg"}}),onFileType:(a,n,i)=>({functionArn:a,events:["s3:ObjectCreated:*"],filter:{prefix:i,suffix:n}}),onFolderUpload:(a,n)=>({functionArn:a,events:["s3:ObjectCreated:*"],filter:{prefix:n.endsWith("/")?n:`${n}/`}})};static createBackupPlan(a){let{name:n,slug:i,environment:s,bucketLogicalIds:c,retentionDays:l,schedule:u="cron(0 5 * * ? *)",vaultName:h,enableContinuousBackup:y=!1,moveToColdStorageAfterDays:f}=a,S=h||r({slug:i,environment:s,resourceType:"backup-vault",suffix:n}),b=t(S),C={Type:"AWS::Backup::BackupVault",Properties:{BackupVaultName:S}},T=r({slug:i,environment:s,resourceType:"backup-role",suffix:n}),v=t(T),w={Type:"AWS::IAM::Role",Properties:{RoleName:T,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"backup.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup","arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"]}},R=r({slug:i,environment:s,resourceType:"backup-plan",suffix:n}),k=t(R),W={DeleteAfterDays:l};if(f&&f<l)W.MoveToColdStorageAfterDays=f;let P={Type:"AWS::Backup::BackupPlan",Properties:{BackupPlan:{BackupPlanName:R,BackupPlanRule:[{RuleName:`${n}-daily-backup`,TargetBackupVault:N.Ref(b),ScheduleExpression:u,StartWindowMinutes:60,CompletionWindowMinutes:120,Lifecycle:W,EnableContinuousBackup:y}]}}},V=r({slug:i,environment:s,resourceType:"backup-selection",suffix:n}),B=t(V),j=c.map((K)=>N.GetAtt(K,"Arn")),J={Type:"AWS::Backup::BackupSelection",Properties:{BackupPlanId:N.Ref(k),BackupSelection:{SelectionName:V,IamRoleArn:N.GetAtt(v,"Arn"),Resources:j}}};return{vault:C,plan:P,selection:J,role:w,vaultLogicalId:b,planLogicalId:k,selectionLogicalId:B,roleLogicalId:v}}static BackupSchedules={HOURLY:"cron(0 * * * ? *)",DAILY_5AM:"cron(0 5 * * ? *)",DAILY_MIDNIGHT:"cron(0 0 * * ? *)",WEEKLY_SUNDAY:"cron(0 5 ? * SUN *)",WEEKLY_SATURDAY:"cron(0 5 ? * SAT *)",MONTHLY_FIRST:"cron(0 5 1 * ? *)",EVERY_12_HOURS:"cron(0 */12 * * ? *)",EVERY_6_HOURS:"cron(0 */6 * * ? *)"};static BackupRetention={ONE_DAY:1,ONE_WEEK:7,TWO_WEEKS:14,ONE_MONTH:30,THREE_MONTHS:90,SIX_MONTHS:180,ONE_YEAR:365,TWO_YEARS:730,FIVE_YEARS:1825,SEVEN_YEARS:2555};static createWwwRedirectBucket(a){let{slug:n,environment:i,sourceDomain:s,targetDomain:c,protocol:l="https"}=a,u=r({slug:n,environment:i,resourceType:"s3",suffix:"www-redirect"}),h=t(u),y={Type:"AWS::S3::Bucket",Properties:{BucketName:s,WebsiteConfiguration:{RedirectAllRequestsTo:{HostName:c,Protocol:l}},PublicAccessBlockConfiguration:{BlockPublicAcls:!1,BlockPublicPolicy:!1,IgnorePublicAcls:!1,RestrictPublicBuckets:!1}}},f={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:N.Ref(h),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadForRedirect",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[N.Join("",[N.GetAtt(h,"Arn"),"/*"])]}]}}};return{bucket:y,bucketPolicy:f,logicalId:h}}static createDocsBucket(a){let{slug:n,environment:i,domain:s}=a,c=s||r({slug:n,environment:i,resourceType:"s3",suffix:"docs"}),l=t(c);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:c,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},Tags:[{Key:"backup",Value:"weekly"}]}},logicalId:l}}static createEmailBucket(a){let{slug:n,environment:i}=a,s=r({slug:n,environment:i,resourceType:"s3",suffix:"email"}),c=t(s),l={Type:"AWS::S3::Bucket",Properties:{BucketName:s,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"EmailRetention",Status:"Enabled",ExpirationInDays:90,Transitions:[{TransitionInDays:30,StorageClass:"STANDARD_IA"}]}]}}},u={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:N.Ref(c),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowSESPuts",Effect:"Allow",Principal:{Service:"ses.amazonaws.com"},Action:"s3:PutObject",Resource:N.Join("",[N.GetAtt(c,"Arn"),"/*"]),Condition:{StringEquals:{"AWS:SourceAccount":N.Ref("AWS::AccountId")}}}]}}};return{bucket:l,bucketPolicy:u,logicalId:c}}static docsExist(a={}){let{projectRoot:n=process.cwd(),docsPaths:i=["docs","documentation","doc"]}=a;for(let s of i){let c=ve(n,s);if(je(c)){let l=["dist","build",".bunpress/dist","_site","out","public"];for(let u of l){let h=ve(c,u);if(je(h))try{if(or(h).length>0)return{exists:!0,path:c,hasDistFolder:!0,distPath:h}}catch{}}return{exists:!0,path:c,hasDistFolder:!1,distPath:null}}}return{exists:!1,path:null,hasDistFolder:!1,distPath:null}}static createDocsBucketIfExists(a){let n=Se.docsExist({projectRoot:a.projectRoot,docsPaths:a.docsPaths});if(!n.exists)return{bucket:null,logicalId:null,docsInfo:n};let i=Se.createDocsBucket({slug:a.slug,environment:a.environment,domain:a.domain});return{bucket:i.bucket,bucketPolicy:i.bucketPolicy,logicalId:i.logicalId,docsInfo:n}}static createPrivateBucket(a){let{slug:n,environment:i,enableVersioning:s=!0,retentionDays:c,encryptionKeyArn:l}=a,u=r({slug:n,environment:i,resourceType:"s3",suffix:"private"}),h=t(u);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:u,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:l?{SSEAlgorithm:"aws:kms",KMSMasterKeyID:l}:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},VersioningConfiguration:s?{Status:"Enabled"}:void 0,LifecycleConfiguration:c?{Rules:[{Id:"RetentionPolicy",Status:"Enabled",ExpirationInDays:c}]}:void 0,Tags:[{Key:"backup",Value:"daily"}]}},logicalId:h}}static checkSourcePaths(a={}){let{projectRoot:n=process.cwd(),paths:i={}}=a,s=i.web||"views/web/dist",c=i.docs||"docs/dist",l=i.private||"private";return{web:{exists:je(ve(n,s)),path:ve(n,s)},docs:{exists:je(ve(n,c)),path:ve(n,c)},private:{exists:je(ve(n,l)),path:ve(n,l)}}}static createDeploymentBuckets(a){let{slug:n,environment:i,domain:s,projectRoot:c,paths:l}=a,u=Se.checkSourcePaths({projectRoot:c,paths:l}),h={},y={web:!1,docs:!1,private:!1},f=Se.createBucket({name:"web",slug:n,environment:i,public:!1,versioning:!1,encryption:!0});if(h[f.logicalId]=f.bucket,y.web=!0,u.docs.exists){let S=Se.createDocsBucket({slug:n,environment:i,domain:s?`docs.${s}`:void 0});if(h[S.logicalId]=S.bucket,S.bucketPolicy)h[`${S.logicalId}Policy`]=S.bucketPolicy;y.docs=!0}if(u.private.exists){let S=Se.createPrivateBucket({slug:n,environment:i,enableVersioning:!0});h[S.logicalId]=S.bucket,y.private=!0}return{resources:h,created:y,sourcePaths:u}}}class Ue{static createRepository(a){let{name:n,slug:i,environment:s,scanOnPush:c=!0,imageMutability:l="MUTABLE",encryption:u="AES256",kmsKey:h,lifecyclePolicy:y,tags:f}=a,S=r({slug:i,environment:s,resourceType:"ecr",suffix:n}),b=t(S),C={Type:"AWS::ECR::Repository",Properties:{RepositoryName:S,ImageTagMutability:l,ImageScanningConfiguration:{ScanOnPush:c},EncryptionConfiguration:{EncryptionType:u,...h&&u==="KMS"?{KmsKey:h}:{}}}};if(y)C.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(Ue.generateLifecyclePolicy(y))};if(f)C.Properties.Tags=Object.entries(f).map(([T,v])=>({Key:T,Value:v}));return{repository:C,logicalId:b}}static generateLifecyclePolicy(a){let n=[];if(a.untaggedImageExpireDays!==void 0)n.push({rulePriority:1,description:"Delete untagged images",selection:{tagStatus:"untagged",countType:"sinceImagePushed",countNumber:a.untaggedImageExpireDays,countUnit:"days"},action:{type:"expire"}});if(a.maxImageCount!==void 0)n.push({rulePriority:n.length+1,description:"Keep only most recent images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:a.maxImageCount},action:{type:"expire"}});if(a.maxImageAgeDays!==void 0)n.push({rulePriority:n.length+1,description:"Delete images older than specified days",selection:{tagStatus:"any",countType:"sinceImagePushed",countNumber:a.maxImageAgeDays,countUnit:"days"},action:{type:"expire"}});return{rules:n}}static LifecyclePolicies={production:{maxImageCount:10,untaggedImageExpireDays:7},development:{maxImageCount:5,untaggedImageExpireDays:3},minimal:{maxImageCount:3,untaggedImageExpireDays:1},archive:{maxImageCount:50,untaggedImageExpireDays:30}};static enableImmutableTags(a){if(!a.Properties)a.Properties={};return a.Properties.ImageTagMutability="IMMUTABLE",a}static enableScanOnPush(a){if(!a.Properties)a.Properties={};return a.Properties.ImageScanningConfiguration={ScanOnPush:!0},a}static setLifecyclePolicy(a,n){if(!a.Properties)a.Properties={};return a.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(Ue.generateLifecyclePolicy(n))},a}static addCrossAccountAccess(a,n){if(!a.Properties)a.Properties={};return a.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"CrossAccountPull",Effect:"Allow",Principal:{AWS:n.map((i)=>`arn:aws:iam::${i}:root`)},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:BatchCheckLayerAvailability"]}]},a}static addLambdaAccess(a){if(!a.Properties)a.Properties={};return a.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"LambdaECRImageRetrievalPolicy",Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage"]}]},a}static generateBunDockerfile(a){let{baseImage:n="oven/bun:1-debian",serverPath:i,port:s=3000,additionalDirs:c=[],healthCheckEndpoint:l="/health",nodeCompatible:u=!1,envVars:h={},buildCommands:y=[],runCommand:f}=a,S=["app","config",...c],b=f||`bun run ${i}`,C=`# Multi-stage build for Bun application
24
24
  # Generated by ts-cloud
25
25
 
26
26
  # Builder stage
@@ -74,7 +74,7 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\
74
74
 
75
75
  # Start application
76
76
  CMD ["bun", "run", "${i}"]
77
- `,C}static generateDockerBuildCommands(a){let{repositoryUri:n,tag:i="latest",dockerfilePath:s="Dockerfile",context:c=".",additionalTags:l=[],buildArgs:u={},platform:h="linux/amd64",noCache:y=!1}=a,f=`${n}:${i}`,S=[i,...l],b=`docker build -f ${s} -t ${f}`;if(h)b+=` --platform ${h}`;if(y)b+=" --no-cache";for(let[v,w]of Object.entries(u))b+=` --build-arg ${v}=${w}`;b+=` ${c}`;let C=S.slice(1).map((v)=>`docker tag ${f} ${n}:${v}`),T=S.map((v)=>`docker push ${n}:${v}`);return{build:b,tag:C,push:T,all:[b,...C,...T]}}static generateEcrLoginCommand(a,n){return`aws ecr get-login-password --region ${a} | docker login --username AWS --password-stdin ${n}.dkr.ecr.${a}.amazonaws.com`}static buildRepositoryUri(a){return`${a.accountId}.dkr.ecr.${a.region}.amazonaws.com/${a.repositoryName}`}static generateImageTags(a){let n=["latest"];if(a.version){n.push(a.version);let i=a.version.split(".");if(i.length>=2)n.push(`${i[0]}.${i[1]}`);if(i.length>=1)n.push(i[0])}if(a.gitSha)n.push(a.gitSha.substring(0,7)),n.push(a.gitSha);if(a.gitBranch){let i=a.gitBranch.replace(/[^a-zA-Z0-9.-]/g,"-").replace(/^-+|-+$/g,"");n.push(i)}if(a.environment)n.push(a.environment);if(a.timestamp){let i=new Date().toISOString().replace(/[:.]/g,"-").substring(0,19);n.push(i)}return[...new Set(n)]}static DeploymentWorkflow={generateDeployScript:(a)=>{let n=Fe.buildRepositoryUri({accountId:a.accountId,region:a.region,repositoryName:a.repositoryName}),i=a.tags||["latest"],s=i[0];return`#!/bin/bash
77
+ `,C}static generateDockerBuildCommands(a){let{repositoryUri:n,tag:i="latest",dockerfilePath:s="Dockerfile",context:c=".",additionalTags:l=[],buildArgs:u={},platform:h="linux/amd64",noCache:y=!1}=a,f=`${n}:${i}`,S=[i,...l],b=`docker build -f ${s} -t ${f}`;if(h)b+=` --platform ${h}`;if(y)b+=" --no-cache";for(let[v,w]of Object.entries(u))b+=` --build-arg ${v}=${w}`;b+=` ${c}`;let C=S.slice(1).map((v)=>`docker tag ${f} ${n}:${v}`),T=S.map((v)=>`docker push ${n}:${v}`);return{build:b,tag:C,push:T,all:[b,...C,...T]}}static generateEcrLoginCommand(a,n){return`aws ecr get-login-password --region ${a} | docker login --username AWS --password-stdin ${n}.dkr.ecr.${a}.amazonaws.com`}static buildRepositoryUri(a){return`${a.accountId}.dkr.ecr.${a.region}.amazonaws.com/${a.repositoryName}`}static generateImageTags(a){let n=["latest"];if(a.version){n.push(a.version);let i=a.version.split(".");if(i.length>=2)n.push(`${i[0]}.${i[1]}`);if(i.length>=1)n.push(i[0])}if(a.gitSha)n.push(a.gitSha.substring(0,7)),n.push(a.gitSha);if(a.gitBranch){let i=a.gitBranch.replace(/[^a-zA-Z0-9.-]/g,"-").replace(/^-+|-+$/g,"");n.push(i)}if(a.environment)n.push(a.environment);if(a.timestamp){let i=new Date().toISOString().replace(/[:.]/g,"-").substring(0,19);n.push(i)}return[...new Set(n)]}static DeploymentWorkflow={generateDeployScript:(a)=>{let n=Ue.buildRepositoryUri({accountId:a.accountId,region:a.region,repositoryName:a.repositoryName}),i=a.tags||["latest"],s=i[0];return`#!/bin/bash
78
78
  set -e
79
79
 
80
80
  # Configuration
@@ -85,7 +85,7 @@ IMAGE_URI="${n}"
85
85
  DOCKERFILE="${a.dockerfilePath||"Dockerfile"}"
86
86
 
87
87
  echo "=== ECR Login ==="
88
- ${Fe.generateEcrLoginCommand(a.region,a.accountId)}
88
+ ${Ue.generateEcrLoginCommand(a.region,a.accountId)}
89
89
 
90
90
  echo "=== Building Image ==="
91
91
  docker build -f $DOCKERFILE -t $IMAGE_URI:${s} --platform linux/amd64 .
@@ -103,7 +103,7 @@ echo "Image: $IMAGE_URI:${s}"
103
103
  docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
104
104
  docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest`},...a.ecsCluster&&a.ecsService?[{name:"Deploy to ECS",run:`aws ecs update-service --cluster ${a.ecsCluster} --service ${a.ecsService} --force-new-deployment`}]:[]]}}};return`# Generated by ts-cloud
105
105
  ${JSON.stringify(n,null,2).replace(/"/g,"").replace(/,\n/g,`
106
- `)}`}};static DockerfileTemplates={bunServer:(a,n=3000)=>Fe.generateBunDockerfile({serverPath:a,port:n}),bunWithBuild:(a,n,i=3000)=>Fe.generateBunDockerfile({serverPath:a,port:i,buildCommands:[n]}),bunFullStack:(a,n=3000)=>Fe.generateBunDockerfile({serverPath:a,port:n,additionalDirs:["public","views","dist"],buildCommands:["bun run build"]}),bunApi:(a,n=3000)=>Fe.generateBunDockerfile({serverPath:a,port:n,healthCheckEndpoint:"/api/health"})}}class Ce{static createDistribution(a){let{slug:n,environment:i,origin:s,customDomain:c,certificateArn:l,errorPages:u,cachePolicy:h,edgeFunctions:y,http3:f=!1,comment:S}=a,b=r({slug:n,environment:i,resourceType:"cdn"}),C=t(b),T={Id:"DefaultOrigin",DomainName:s.domainName,OriginPath:s.originPath||""},v;if(s.type==="s3"){let R=`${C}OAC`;v={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${b}-oac`,Description:`Origin Access Control for ${b}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},T.OriginAccessControlId=N.Ref(R)}else if(s.type==="alb"||s.type==="custom")T.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};let w={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:S||`CDN for ${b}`,DefaultRootObject:"index.html",Origins:[T],DefaultCacheBehavior:{TargetOriginId:"DefaultOrigin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},PriceClass:"PriceClass_100",HttpVersion:f?"http2and3":"http2"}}};if(c&&l)w.Properties.DistributionConfig.Aliases=[c],w.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:l,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};if(u&&u.length>0)w.Properties.DistributionConfig.CustomErrorResponses=u.map((R)=>({ErrorCode:R.errorCode,ResponseCode:R.responseCode,ResponsePagePath:R.responsePagePath}));if(y&&y.length>0)w.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=y.map((R)=>({EventType:R.event,LambdaFunctionARN:R.functionArn}));return{distribution:w,originAccessControl:v,logicalId:C}}static setCustomDomain(a,n,i){return a.Properties.DistributionConfig.Aliases=[n],a.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:i,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"},a}static setErrorPages(a,n){return a.Properties.DistributionConfig.CustomErrorResponses=n.map((i)=>({ErrorCode:i.errorCode,ResponseCode:i.responseCode,ResponsePagePath:i.responsePagePath})),a}static enableHttp3(a){return a.Properties.DistributionConfig.HttpVersion="http2and3",a}static addEdgeFunction(a,n,i){if(!a.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations)a.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=[];return a.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations.push({EventType:n,LambdaFunctionARN:i}),a}static setCachePolicy(a,n){return a.Properties.DistributionConfig.Comment=`${a.Properties.DistributionConfig.Comment||""} (TTL: ${n.default||86400}s)`,a}static createSpaDistribution(a){return Ce.createDistribution({...a,errorPages:[{errorCode:404,responseCode:200,responsePagePath:"/index.html"},{errorCode:403,responseCode:200,responsePagePath:"/index.html"}]})}static createDocsOriginRequestFunction(a){let{slug:n,environment:i}=a,s=r({slug:n,environment:i,resourceType:"edge-docs"}),c=t(s),l=t(`${s}-role`),u=t(`${s}-version`),h={Type:"AWS::IAM::Role",Properties:{RoleName:`${s}-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=`
106
+ `)}`}};static DockerfileTemplates={bunServer:(a,n=3000)=>Ue.generateBunDockerfile({serverPath:a,port:n}),bunWithBuild:(a,n,i=3000)=>Ue.generateBunDockerfile({serverPath:a,port:i,buildCommands:[n]}),bunFullStack:(a,n=3000)=>Ue.generateBunDockerfile({serverPath:a,port:n,additionalDirs:["public","views","dist"],buildCommands:["bun run build"]}),bunApi:(a,n=3000)=>Ue.generateBunDockerfile({serverPath:a,port:n,healthCheckEndpoint:"/api/health"})}}class Ce{static createDistribution(a){let{slug:n,environment:i,origin:s,customDomain:c,certificateArn:l,errorPages:u,cachePolicy:h,edgeFunctions:y,http3:f=!1,comment:S}=a,b=r({slug:n,environment:i,resourceType:"cdn"}),C=t(b),T={Id:"DefaultOrigin",DomainName:s.domainName,OriginPath:s.originPath||""},v;if(s.type==="s3"){let R=`${C}OAC`;v={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${b}-oac`,Description:`Origin Access Control for ${b}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},T.OriginAccessControlId=N.Ref(R)}else if(s.type==="alb"||s.type==="custom")T.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};let w={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:S||`CDN for ${b}`,DefaultRootObject:"index.html",Origins:[T],DefaultCacheBehavior:{TargetOriginId:"DefaultOrigin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},PriceClass:"PriceClass_100",HttpVersion:f?"http2and3":"http2"}}};if(c&&l)w.Properties.DistributionConfig.Aliases=[c],w.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:l,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};if(u&&u.length>0)w.Properties.DistributionConfig.CustomErrorResponses=u.map((R)=>({ErrorCode:R.errorCode,ResponseCode:R.responseCode,ResponsePagePath:R.responsePagePath}));if(y&&y.length>0)w.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=y.map((R)=>({EventType:R.event,LambdaFunctionARN:R.functionArn}));return{distribution:w,originAccessControl:v,logicalId:C}}static setCustomDomain(a,n,i){return a.Properties.DistributionConfig.Aliases=[n],a.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:i,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"},a}static setErrorPages(a,n){return a.Properties.DistributionConfig.CustomErrorResponses=n.map((i)=>({ErrorCode:i.errorCode,ResponseCode:i.responseCode,ResponsePagePath:i.responsePagePath})),a}static enableHttp3(a){return a.Properties.DistributionConfig.HttpVersion="http2and3",a}static addEdgeFunction(a,n,i){if(!a.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations)a.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=[];return a.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations.push({EventType:n,LambdaFunctionARN:i}),a}static setCachePolicy(a,n){return a.Properties.DistributionConfig.Comment=`${a.Properties.DistributionConfig.Comment||""} (TTL: ${n.default||86400}s)`,a}static createSpaDistribution(a){return Ce.createDistribution({...a,errorPages:[{errorCode:404,responseCode:200,responsePagePath:"/index.html"},{errorCode:403,responseCode:200,responsePagePath:"/index.html"}]})}static createDocsOriginRequestFunction(a){let{slug:n,environment:i}=a,s=r({slug:n,environment:i,resourceType:"edge-docs"}),c=t(s),l=t(`${s}-role`),u=t(`${s}-version`),h={Type:"AWS::IAM::Role",Properties:{RoleName:`${s}-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=`
107
107
  'use strict';
108
108
 
109
109
  exports.handler = async (event) => {
@@ -620,7 +620,7 @@ echo "Redis server setup complete!"
620
620
  - Using a single NAT Gateway (singleNatGateway: true)
621
621
  - Using NAT Instances instead (cheaper but requires management)
622
622
  - Disabling NAT entirely for isolated private subnets
623
- `}class Ue{static createFileSystem(a){let{slug:n,environment:i,encrypted:s=!0,kmsKeyId:c,performanceMode:l="generalPurpose",throughputMode:u="bursting",provisionedThroughput:h,enableBackup:y=!0}=a,f=r({slug:n,environment:i,resourceType:"efs"}),S=t(f),b={Type:"AWS::EFS::FileSystem",Properties:{Encrypted:s,PerformanceMode:l,ThroughputMode:u,FileSystemTags:[{Key:"Name",Value:f},{Key:"Environment",Value:i}]}};if(c)b.Properties.KmsKeyId=c;if(u==="provisioned"&&h)b.Properties.ProvisionedThroughputInMibps=h;if(y)b.Properties.BackupPolicy={Status:"ENABLED"};return{fileSystem:b,logicalId:S}}static createMountTarget(a,n){let{slug:i,environment:s,subnetId:c,securityGroups:l,ipAddress:u}=n,h=r({slug:i,environment:s,resourceType:"efs-mt"}),y=t(`${h}-${c}`),f={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:N.Ref(a),SubnetId:c,SecurityGroups:l}};if(u)f.Properties.IpAddress=u;return{mountTarget:f,logicalId:y}}static createAccessPoint(a,n){let{slug:i,environment:s,path:c="/",uid:l="1000",gid:u="1000",permissions:h="755"}=n,y=r({slug:i,environment:s,resourceType:"efs-ap"}),f=t(`${y}-${c.replace(/\//g,"-")}`);return{accessPoint:{Type:"AWS::EFS::AccessPoint",Properties:{FileSystemId:N.Ref(a),PosixUser:{Uid:l,Gid:u},RootDirectory:{Path:c,CreationInfo:{OwnerUid:l,OwnerGid:u,Permissions:h}},AccessPointTags:[{Key:"Name",Value:`${y}-${c}`},{Key:"Environment",Value:s}]}},logicalId:f}}static setLifecyclePolicy(a,n){let{transitionToIA:i,transitionToPrimary:s=!1}=n;if(!a.Properties)a.Properties={};if(a.Properties.LifecyclePolicies=[],i){let c=`AFTER_${i}_DAYS`;a.Properties.LifecyclePolicies.push({TransitionToIA:c})}if(s)a.Properties.LifecyclePolicies.push({TransitionToPrimaryStorageClass:"AFTER_1_ACCESS"});return a}static enableBackup(a){if(!a.Properties)a.Properties={};return a.Properties.BackupPolicy={Status:"ENABLED"},a}static disableBackup(a){if(!a.Properties)a.Properties={};return a.Properties.BackupPolicy={Status:"DISABLED"},a}static setProvisionedThroughput(a,n){if(!a.Properties)a.Properties={};return a.Properties.ThroughputMode="provisioned",a.Properties.ProvisionedThroughputInMibps=n,a}static setElasticThroughput(a){if(!a.Properties)a.Properties={};return a.Properties.ThroughputMode="elastic",a}static enableMaxIO(a){if(!a.Properties)a.Properties={};return a.Properties.PerformanceMode="maxIO",a}static createEfsSecurityGroup(a){let{slug:n,environment:i,vpcId:s,sourceSecurityGroupIds:c=[],sourceCidrBlocks:l=[],description:u}=a,h=r({slug:n,environment:i,resourceType:"efs-sg"}),y=t(h),f=[];for(let S of c)f.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,SourceSecurityGroupId:S,Description:"NFS from security group"});for(let S of l)f.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,CidrIp:S,Description:"NFS from CIDR block"});return{securityGroup:{Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:h,GroupDescription:u||`Security group for EFS mount targets - ${n} ${i}`,VpcId:s,SecurityGroupIngress:f,Tags:[{Key:"Name",Value:h},{Key:"Environment",Value:i}]}},logicalId:y}}static createMultiAzMountTargets(a,n){let{slug:i,environment:s,subnetIds:c,securityGroupId:l}=n,u=[],h=[];for(let y=0;y<c.length;y++){let f=c[y],S=r({slug:i,environment:s,resourceType:"efs-mt"}),b=t(`${S}-az${y+1}`),C={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:N.Ref(a),SubnetId:f,SecurityGroups:[l]}};u.push(C),h.push(b)}return{mountTargets:u,logicalIds:h}}static createCompleteFileSystem(a){let{slug:n,environment:i,vpcId:s,subnetIds:c,sourceSecurityGroupIds:l=[],encrypted:u=!0,performanceMode:h="generalPurpose",throughputMode:y="elastic",enableBackup:f=!0,transitionToIA:S}=a,b={},{fileSystem:C,logicalId:T}=Ue.createFileSystem({slug:n,environment:i,encrypted:u,performanceMode:h,throughputMode:y,enableBackup:f});if(S)Ue.setLifecyclePolicy(C,{transitionToIA:S,transitionToPrimary:!0});b[T]=C;let{securityGroup:v,logicalId:w}=Ue.createEfsSecurityGroup({slug:n,environment:i,vpcId:s,sourceSecurityGroupIds:l});b[w]=v;let{mountTargets:R,logicalIds:k}=Ue.createMultiAzMountTargets(T,{slug:n,environment:i,subnetIds:c,securityGroupId:N.Ref(w)});for(let W=0;W<R.length;W++)b[k[W]]=R[W];return{resources:b,outputs:{fileSystemId:T,securityGroupId:w,mountTargetIds:k}}}}class m{static verifyDomain(a){let{domain:n,slug:i,environment:s,enableDkim:c=!0,dkimKeyLength:l="RSA_2048_BIT"}=a,u=r({slug:i,environment:s,resourceType:"ses-identity"}),h=t(`${u}-${n.replace(/\./g,"")}`),y={Type:"AWS::SES::EmailIdentity",Properties:{EmailIdentity:n,FeedbackAttributes:{EmailForwardingEnabled:!0}}};if(c)y.Properties.DkimSigningAttributes={NextSigningKeyLength:l};return{emailIdentity:y,logicalId:h}}static createDkimRecords(a,n,i){let s=[];for(let c=0;c<n.length;c++){let l=n[c],u=t(`dkim-${a.replace(/\./g,"")}-${c+1}`),h={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i,Name:`${l}._domainkey.${a}`,Type:"CNAME",TTL:1800,ResourceRecords:[`${l}.dkim.amazonses.com`]}};s.push({record:h,logicalId:u})}return s}static createConfigurationSet(a){let{slug:n,environment:i,name:s,reputationMetrics:c=!0,sendingEnabled:l=!0,suppressBounces:u=!0,suppressComplaints:h=!0}=a,y=s||r({slug:n,environment:i,resourceType:"ses-config"}),f=t(y),S=[];if(u)S.push("BOUNCE");if(h)S.push("COMPLAINT");return{configurationSet:{Type:"AWS::SES::ConfigurationSet",Properties:{Name:y,ReputationOptions:{ReputationMetricsEnabled:c},SendingOptions:{SendingEnabled:l},SuppressionOptions:{SuppressedReasons:S}}},logicalId:f}}static createReceiptRuleSet(a){let{slug:n,environment:i,name:s}=a,c=s||r({slug:n,environment:i,resourceType:"ses-ruleset"}),l=t(c);return{ruleSet:{Type:"AWS::SES::ReceiptRuleSet",Properties:{RuleSetName:c}},logicalId:l}}static createReceiptRule(a,n){let{slug:i,environment:s,ruleSetName:c,recipients:l,enabled:u=!0,scanEnabled:h=!0,tlsPolicy:y="Require",s3Action:f,lambdaAction:S,snsAction:b}=n,C=r({slug:i,environment:s,resourceType:"ses-rule"}),T=t(C),v=[];if(f)v.push({S3Action:{BucketName:f.bucketName,ObjectKeyPrefix:f.prefix,KmsKeyArn:f.kmsKeyArn}});if(S)v.push({LambdaAction:{FunctionArn:S.functionArn,InvocationType:S.invocationType||"Event"}});if(b)v.push({SNSAction:{TopicArn:b.topicArn,Encoding:b.encoding||"UTF-8"}});return{receiptRule:{Type:"AWS::SES::ReceiptRule",Properties:{RuleSetName:c,Rule:{Name:C,Enabled:u,ScanEnabled:h,TlsPolicy:y,Recipients:l,Actions:v.length>0?v:void 0}}},logicalId:T}}static createMxRecord(a,n,i){let s=t(`mx-${a.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n,Name:a,Type:"MX",TTL:300,ResourceRecords:[`10 inbound-smtp.${i}.amazonaws.com`]}},logicalId:s}}static createVerificationRecord(a,n,i){let s=t(`verification-${a.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i,Name:`_amazonses.${a}`,Type:"TXT",TTL:1800,ResourceRecords:[`"${n}"`]}},logicalId:s}}static getSmtpEndpoint(a){return`email-smtp.${a}.amazonaws.com`}static SmtpPorts={TLS:587,SSL:465,Unencrypted:25};static createSpfRecord(a,n,i){let{includeDomains:s=[],softFail:c=!1}=i||{},l=t(`spf-${a.replace(/\./g,"")}`),u="v=spf1 include:amazonses.com";for(let h of s)u+=` include:${h}`;return u+=c?" ~all":" -all",{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n,Name:a,Type:"TXT",TTL:300,ResourceRecords:[`"${u}"`]}},logicalId:l}}static createDmarcRecord(a,n,i){let{policy:s="none",subdomainPolicy:c,percentage:l=100,reportingEmail:u,forensicEmail:h}=i||{},y=t(`dmarc-${a.replace(/\./g,"")}`),f=`v=DMARC1; p=${s}; pct=${l}`;if(c)f+=`; sp=${c}`;if(u)f+=`; rua=mailto:${u}`;if(h)f+=`; ruf=mailto:${h}`;return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n,Name:`_dmarc.${a}`,Type:"TXT",TTL:300,ResourceRecords:[`"${f}"`]}},logicalId:y}}static createInboundEmailSetup(a){let{slug:n,environment:i,domain:s,s3BucketName:c,s3KeyPrefix:l="inbound/",region:u,hostedZoneId:h,lambdaFunctionArn:y,snsTopicArn:f}=a,S={},{ruleSet:b,logicalId:C}=m.createReceiptRuleSet({slug:n,environment:i});S[C]=b;let{receiptRule:T,logicalId:v}=m.createReceiptRule(C,{slug:n,environment:i,ruleSetName:b.Properties.RuleSetName||`${n}-${i}-receipt-rule-set`,recipients:[s],s3Action:{bucketName:c,prefix:l},lambdaAction:y?{functionArn:y,invocationType:"Event"}:void 0,snsAction:f?{topicArn:f}:void 0});S[v]=T;let{record:w,logicalId:R}=m.createMxRecord(s,h,u);return S[R]=w,{resources:S,outputs:{ruleSetLogicalId:C,ruleLogicalId:v,mxRecordLogicalId:R}}}static createCompleteDomainSetup(a){let{slug:n,environment:i,domain:s,hostedZoneId:c,region:l,enableInbound:u=!1,inboundS3Bucket:h,dmarcReportingEmail:y}=a,f={},{emailIdentity:S,logicalId:b}=m.verifyDomain({domain:s,slug:n,environment:i});f[b]=S;let{configurationSet:C,logicalId:T}=m.createConfigurationSet({slug:n,environment:i});f[T]=C;let{record:v,logicalId:w}=m.createSpfRecord(s,c);f[w]=v;let{record:R,logicalId:k}=m.createDmarcRecord(s,c,{policy:"none",reportingEmail:y||`dmarc-reports@${s}`});if(f[k]=R,u&&h){let W=m.createInboundEmailSetup({slug:n,environment:i,domain:s,s3BucketName:h,region:l,hostedZoneId:c});Object.assign(f,W.resources)}return{resources:f,outputs:{identityLogicalId:b,configSetLogicalId:T}}}static InboundSmtpEndpoints={"us-east-1":"inbound-smtp.us-east-1.amazonaws.com","us-west-2":"inbound-smtp.us-west-2.amazonaws.com","eu-west-1":"inbound-smtp.eu-west-1.amazonaws.com"};static supportsInboundEmail(a){return a in m.InboundSmtpEndpoints}static createEmailLambdaRole(a){let{slug:n,environment:i,s3BucketArn:s,sesIdentityArn:c}=a,l=r({slug:n,environment:i,resourceType:"email-lambda-role"}),u=t(l),h=t(`${l}-policy`),y={Type:"AWS::IAM::Role",Properties:{RoleName:l,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"],Tags:[{Key:"Name",Value:l},{Key:"Environment",Value:i}]}},f=[{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucket"],Resource:[s,`${s}/*`]}];if(c)f.push({Effect:"Allow",Action:["ses:SendEmail","ses:SendRawEmail"],Resource:c});let S={Type:"AWS::IAM::Policy",Properties:{PolicyName:`${l}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:f},Roles:[N.Ref(u)]}};return{role:y,policy:S,roleLogicalId:u,policyLogicalId:h}}static createOutboundEmailLambda(a){let{slug:n,environment:i,roleArn:s,domain:c,configurationSetName:l,timeout:u=30,memorySize:h=256}=a,y=r({slug:n,environment:i,resourceType:"outbound-email"}),f=t(y);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:y,Runtime:"nodejs20.x",Handler:"index.handler",Role:s,Timeout:u,MemorySize:h,Environment:{Variables:{DOMAIN:c,CONFIGURATION_SET:l||""}},Code:{ZipFile:m.LambdaCode.outboundEmail},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:i},{Key:"Purpose",Value:"OutboundEmail"}]}},logicalId:f}}static createInboundEmailLambda(a){let{slug:n,environment:i,roleArn:s,s3BucketName:c,organizedPrefix:l="organized/",timeout:u=60,memorySize:h=512}=a,y=r({slug:n,environment:i,resourceType:"inbound-email"}),f=t(y),S=t(`${y}-permission`),b={Type:"AWS::Lambda::Function",Properties:{FunctionName:y,Runtime:"nodejs20.x",Handler:"index.handler",Role:s,Timeout:u,MemorySize:h,Environment:{Variables:{S3_BUCKET:c,ORGANIZED_PREFIX:l}},Code:{ZipFile:m.LambdaCode.inboundEmail},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:i},{Key:"Purpose",Value:"InboundEmail"}]}},C={Type:"AWS::Lambda::Permission",Properties:{FunctionName:N.Ref(f),Action:"lambda:InvokeFunction",Principal:"ses.amazonaws.com",SourceAccount:N.Ref("AWS::AccountId")}};return{function:b,permission:C,logicalId:f,permissionLogicalId:S}}static createEmailConversionLambda(a){let{slug:n,environment:i,roleArn:s,s3BucketName:c,convertedPrefix:l="converted/",timeout:u=60,memorySize:h=512}=a,y=r({slug:n,environment:i,resourceType:"email-conversion"}),f=t(y);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:y,Runtime:"nodejs20.x",Handler:"index.handler",Role:s,Timeout:u,MemorySize:h,Environment:{Variables:{S3_BUCKET:c,CONVERTED_PREFIX:l}},Code:{ZipFile:m.LambdaCode.emailConversion},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:i},{Key:"Purpose",Value:"EmailConversion"}]}},logicalId:f}}static createEmailBucketNotification(a){let{lambdaArn:n,prefix:i="inbound/",suffix:s,events:c}=a,l=c??["s3:ObjectCreated:*"],u={};if(i||s){if(u.S3Key={Rules:[]},i)u.S3Key.Rules.push({Name:"prefix",Value:i});if(s)u.S3Key.Rules.push({Name:"suffix",Value:s})}return{notificationConfiguration:{LambdaConfigurations:[{Event:l[0],Function:n,Filter:Object.keys(u).length>0?u:void 0}]}}}static createS3LambdaPermission(a){let{slug:n,environment:i,lambdaLogicalId:s,s3BucketArn:c}=a,l=r({slug:n,environment:i,resourceType:"s3-lambda-permission"}),u=t(l);return{permission:{Type:"AWS::Lambda::Permission",Properties:{FunctionName:N.Ref(s),Action:"lambda:InvokeFunction",Principal:"s3.amazonaws.com",SourceArn:c}},logicalId:u}}static createEmailProcessingStack(a){let{slug:n,environment:i,domain:s,s3BucketName:c,s3BucketArn:l,configurationSetName:u,enableInbound:h=!0,enableConversion:y=!0}=a,f={},{role:S,policy:b,roleLogicalId:C,policyLogicalId:T}=m.createEmailLambdaRole({slug:n,environment:i,s3BucketArn:l,sesIdentityArn:`arn:aws:ses:*:*:identity/${s}`});f[C]=S,f[T]=b;let{function:v,logicalId:w}=m.createOutboundEmailLambda({slug:n,environment:i,roleArn:N.GetAtt(C,"Arn"),domain:s,configurationSetName:u});f[w]=v;let R={roleLogicalId:C,outboundLambdaLogicalId:w};if(h){let{function:k,permission:W,logicalId:P,permissionLogicalId:V}=m.createInboundEmailLambda({slug:n,environment:i,roleArn:N.GetAtt(C,"Arn"),s3BucketName:c});f[P]=k,f[V]=W;let{permission:B,logicalId:j}=m.createS3LambdaPermission({slug:n,environment:i,lambdaLogicalId:P,s3BucketArn:l});f[j]=B,R.inboundLambdaLogicalId=P}if(y){let{function:k,logicalId:W}=m.createEmailConversionLambda({slug:n,environment:i,roleArn:N.GetAtt(C,"Arn"),s3BucketName:c});f[W]=k,R.conversionLambdaLogicalId=W}return{resources:f,outputs:R}}static LambdaCode={outboundEmail:`
623
+ `}class Qe{static createFileSystem(a){let{slug:n,environment:i,encrypted:s=!0,kmsKeyId:c,performanceMode:l="generalPurpose",throughputMode:u="bursting",provisionedThroughput:h,enableBackup:y=!0}=a,f=r({slug:n,environment:i,resourceType:"efs"}),S=t(f),b={Type:"AWS::EFS::FileSystem",Properties:{Encrypted:s,PerformanceMode:l,ThroughputMode:u,FileSystemTags:[{Key:"Name",Value:f},{Key:"Environment",Value:i}]}};if(c)b.Properties.KmsKeyId=c;if(u==="provisioned"&&h)b.Properties.ProvisionedThroughputInMibps=h;if(y)b.Properties.BackupPolicy={Status:"ENABLED"};return{fileSystem:b,logicalId:S}}static createMountTarget(a,n){let{slug:i,environment:s,subnetId:c,securityGroups:l,ipAddress:u}=n,h=r({slug:i,environment:s,resourceType:"efs-mt"}),y=t(`${h}-${c}`),f={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:N.Ref(a),SubnetId:c,SecurityGroups:l}};if(u)f.Properties.IpAddress=u;return{mountTarget:f,logicalId:y}}static createAccessPoint(a,n){let{slug:i,environment:s,path:c="/",uid:l="1000",gid:u="1000",permissions:h="755"}=n,y=r({slug:i,environment:s,resourceType:"efs-ap"}),f=t(`${y}-${c.replace(/\//g,"-")}`);return{accessPoint:{Type:"AWS::EFS::AccessPoint",Properties:{FileSystemId:N.Ref(a),PosixUser:{Uid:l,Gid:u},RootDirectory:{Path:c,CreationInfo:{OwnerUid:l,OwnerGid:u,Permissions:h}},AccessPointTags:[{Key:"Name",Value:`${y}-${c}`},{Key:"Environment",Value:s}]}},logicalId:f}}static setLifecyclePolicy(a,n){let{transitionToIA:i,transitionToPrimary:s=!1}=n;if(!a.Properties)a.Properties={};if(a.Properties.LifecyclePolicies=[],i){let c=`AFTER_${i}_DAYS`;a.Properties.LifecyclePolicies.push({TransitionToIA:c})}if(s)a.Properties.LifecyclePolicies.push({TransitionToPrimaryStorageClass:"AFTER_1_ACCESS"});return a}static enableBackup(a){if(!a.Properties)a.Properties={};return a.Properties.BackupPolicy={Status:"ENABLED"},a}static disableBackup(a){if(!a.Properties)a.Properties={};return a.Properties.BackupPolicy={Status:"DISABLED"},a}static setProvisionedThroughput(a,n){if(!a.Properties)a.Properties={};return a.Properties.ThroughputMode="provisioned",a.Properties.ProvisionedThroughputInMibps=n,a}static setElasticThroughput(a){if(!a.Properties)a.Properties={};return a.Properties.ThroughputMode="elastic",a}static enableMaxIO(a){if(!a.Properties)a.Properties={};return a.Properties.PerformanceMode="maxIO",a}static createEfsSecurityGroup(a){let{slug:n,environment:i,vpcId:s,sourceSecurityGroupIds:c=[],sourceCidrBlocks:l=[],description:u}=a,h=r({slug:n,environment:i,resourceType:"efs-sg"}),y=t(h),f=[];for(let S of c)f.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,SourceSecurityGroupId:S,Description:"NFS from security group"});for(let S of l)f.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,CidrIp:S,Description:"NFS from CIDR block"});return{securityGroup:{Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:h,GroupDescription:u||`Security group for EFS mount targets - ${n} ${i}`,VpcId:s,SecurityGroupIngress:f,Tags:[{Key:"Name",Value:h},{Key:"Environment",Value:i}]}},logicalId:y}}static createMultiAzMountTargets(a,n){let{slug:i,environment:s,subnetIds:c,securityGroupId:l}=n,u=[],h=[];for(let y=0;y<c.length;y++){let f=c[y],S=r({slug:i,environment:s,resourceType:"efs-mt"}),b=t(`${S}-az${y+1}`),C={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:N.Ref(a),SubnetId:f,SecurityGroups:[l]}};u.push(C),h.push(b)}return{mountTargets:u,logicalIds:h}}static createCompleteFileSystem(a){let{slug:n,environment:i,vpcId:s,subnetIds:c,sourceSecurityGroupIds:l=[],encrypted:u=!0,performanceMode:h="generalPurpose",throughputMode:y="elastic",enableBackup:f=!0,transitionToIA:S}=a,b={},{fileSystem:C,logicalId:T}=Qe.createFileSystem({slug:n,environment:i,encrypted:u,performanceMode:h,throughputMode:y,enableBackup:f});if(S)Qe.setLifecyclePolicy(C,{transitionToIA:S,transitionToPrimary:!0});b[T]=C;let{securityGroup:v,logicalId:w}=Qe.createEfsSecurityGroup({slug:n,environment:i,vpcId:s,sourceSecurityGroupIds:l});b[w]=v;let{mountTargets:R,logicalIds:k}=Qe.createMultiAzMountTargets(T,{slug:n,environment:i,subnetIds:c,securityGroupId:N.Ref(w)});for(let W=0;W<R.length;W++)b[k[W]]=R[W];return{resources:b,outputs:{fileSystemId:T,securityGroupId:w,mountTargetIds:k}}}}class m{static verifyDomain(a){let{domain:n,slug:i,environment:s,enableDkim:c=!0,dkimKeyLength:l="RSA_2048_BIT"}=a,u=r({slug:i,environment:s,resourceType:"ses-identity"}),h=t(`${u}-${n.replace(/\./g,"")}`),y={Type:"AWS::SES::EmailIdentity",Properties:{EmailIdentity:n,FeedbackAttributes:{EmailForwardingEnabled:!0}}};if(c)y.Properties.DkimSigningAttributes={NextSigningKeyLength:l};return{emailIdentity:y,logicalId:h}}static createDkimRecords(a,n,i){let s=[];for(let c=0;c<n.length;c++){let l=n[c],u=t(`dkim-${a.replace(/\./g,"")}-${c+1}`),h={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i,Name:`${l}._domainkey.${a}`,Type:"CNAME",TTL:1800,ResourceRecords:[`${l}.dkim.amazonses.com`]}};s.push({record:h,logicalId:u})}return s}static createConfigurationSet(a){let{slug:n,environment:i,name:s,reputationMetrics:c=!0,sendingEnabled:l=!0,suppressBounces:u=!0,suppressComplaints:h=!0}=a,y=s||r({slug:n,environment:i,resourceType:"ses-config"}),f=t(y),S=[];if(u)S.push("BOUNCE");if(h)S.push("COMPLAINT");return{configurationSet:{Type:"AWS::SES::ConfigurationSet",Properties:{Name:y,ReputationOptions:{ReputationMetricsEnabled:c},SendingOptions:{SendingEnabled:l},SuppressionOptions:{SuppressedReasons:S}}},logicalId:f}}static createReceiptRuleSet(a){let{slug:n,environment:i,name:s}=a,c=s||r({slug:n,environment:i,resourceType:"ses-ruleset"}),l=t(c);return{ruleSet:{Type:"AWS::SES::ReceiptRuleSet",Properties:{RuleSetName:c}},logicalId:l}}static createReceiptRule(a,n){let{slug:i,environment:s,ruleSetName:c,recipients:l,enabled:u=!0,scanEnabled:h=!0,tlsPolicy:y="Require",s3Action:f,lambdaAction:S,snsAction:b}=n,C=r({slug:i,environment:s,resourceType:"ses-rule"}),T=t(C),v=[];if(f)v.push({S3Action:{BucketName:f.bucketName,ObjectKeyPrefix:f.prefix,KmsKeyArn:f.kmsKeyArn}});if(S)v.push({LambdaAction:{FunctionArn:S.functionArn,InvocationType:S.invocationType||"Event"}});if(b)v.push({SNSAction:{TopicArn:b.topicArn,Encoding:b.encoding||"UTF-8"}});return{receiptRule:{Type:"AWS::SES::ReceiptRule",Properties:{RuleSetName:c,Rule:{Name:C,Enabled:u,ScanEnabled:h,TlsPolicy:y,Recipients:l,Actions:v.length>0?v:void 0}}},logicalId:T}}static createMxRecord(a,n,i){let s=t(`mx-${a.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n,Name:a,Type:"MX",TTL:300,ResourceRecords:[`10 inbound-smtp.${i}.amazonaws.com`]}},logicalId:s}}static createVerificationRecord(a,n,i){let s=t(`verification-${a.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i,Name:`_amazonses.${a}`,Type:"TXT",TTL:1800,ResourceRecords:[`"${n}"`]}},logicalId:s}}static getSmtpEndpoint(a){return`email-smtp.${a}.amazonaws.com`}static SmtpPorts={TLS:587,SSL:465,Unencrypted:25};static createSpfRecord(a,n,i){let{includeDomains:s=[],softFail:c=!1}=i||{},l=t(`spf-${a.replace(/\./g,"")}`),u="v=spf1 include:amazonses.com";for(let h of s)u+=` include:${h}`;return u+=c?" ~all":" -all",{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n,Name:a,Type:"TXT",TTL:300,ResourceRecords:[`"${u}"`]}},logicalId:l}}static createDmarcRecord(a,n,i){let{policy:s="none",subdomainPolicy:c,percentage:l=100,reportingEmail:u,forensicEmail:h}=i||{},y=t(`dmarc-${a.replace(/\./g,"")}`),f=`v=DMARC1; p=${s}; pct=${l}`;if(c)f+=`; sp=${c}`;if(u)f+=`; rua=mailto:${u}`;if(h)f+=`; ruf=mailto:${h}`;return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:n,Name:`_dmarc.${a}`,Type:"TXT",TTL:300,ResourceRecords:[`"${f}"`]}},logicalId:y}}static createInboundEmailSetup(a){let{slug:n,environment:i,domain:s,s3BucketName:c,s3KeyPrefix:l="inbound/",region:u,hostedZoneId:h,lambdaFunctionArn:y,snsTopicArn:f}=a,S={},{ruleSet:b,logicalId:C}=m.createReceiptRuleSet({slug:n,environment:i});S[C]=b;let{receiptRule:T,logicalId:v}=m.createReceiptRule(C,{slug:n,environment:i,ruleSetName:b.Properties.RuleSetName||`${n}-${i}-receipt-rule-set`,recipients:[s],s3Action:{bucketName:c,prefix:l},lambdaAction:y?{functionArn:y,invocationType:"Event"}:void 0,snsAction:f?{topicArn:f}:void 0});S[v]=T;let{record:w,logicalId:R}=m.createMxRecord(s,h,u);return S[R]=w,{resources:S,outputs:{ruleSetLogicalId:C,ruleLogicalId:v,mxRecordLogicalId:R}}}static createCompleteDomainSetup(a){let{slug:n,environment:i,domain:s,hostedZoneId:c,region:l,enableInbound:u=!1,inboundS3Bucket:h,dmarcReportingEmail:y}=a,f={},{emailIdentity:S,logicalId:b}=m.verifyDomain({domain:s,slug:n,environment:i});f[b]=S;let{configurationSet:C,logicalId:T}=m.createConfigurationSet({slug:n,environment:i});f[T]=C;let{record:v,logicalId:w}=m.createSpfRecord(s,c);f[w]=v;let{record:R,logicalId:k}=m.createDmarcRecord(s,c,{policy:"none",reportingEmail:y||`dmarc-reports@${s}`});if(f[k]=R,u&&h){let W=m.createInboundEmailSetup({slug:n,environment:i,domain:s,s3BucketName:h,region:l,hostedZoneId:c});Object.assign(f,W.resources)}return{resources:f,outputs:{identityLogicalId:b,configSetLogicalId:T}}}static InboundSmtpEndpoints={"us-east-1":"inbound-smtp.us-east-1.amazonaws.com","us-west-2":"inbound-smtp.us-west-2.amazonaws.com","eu-west-1":"inbound-smtp.eu-west-1.amazonaws.com"};static supportsInboundEmail(a){return a in m.InboundSmtpEndpoints}static createEmailLambdaRole(a){let{slug:n,environment:i,s3BucketArn:s,sesIdentityArn:c}=a,l=r({slug:n,environment:i,resourceType:"email-lambda-role"}),u=t(l),h=t(`${l}-policy`),y={Type:"AWS::IAM::Role",Properties:{RoleName:l,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"],Tags:[{Key:"Name",Value:l},{Key:"Environment",Value:i}]}},f=[{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucket"],Resource:[s,`${s}/*`]}];if(c)f.push({Effect:"Allow",Action:["ses:SendEmail","ses:SendRawEmail"],Resource:c});let S={Type:"AWS::IAM::Policy",Properties:{PolicyName:`${l}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:f},Roles:[N.Ref(u)]}};return{role:y,policy:S,roleLogicalId:u,policyLogicalId:h}}static createOutboundEmailLambda(a){let{slug:n,environment:i,roleArn:s,domain:c,configurationSetName:l,timeout:u=30,memorySize:h=256}=a,y=r({slug:n,environment:i,resourceType:"outbound-email"}),f=t(y);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:y,Runtime:"nodejs20.x",Handler:"index.handler",Role:s,Timeout:u,MemorySize:h,Environment:{Variables:{DOMAIN:c,CONFIGURATION_SET:l||""}},Code:{ZipFile:m.LambdaCode.outboundEmail},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:i},{Key:"Purpose",Value:"OutboundEmail"}]}},logicalId:f}}static createInboundEmailLambda(a){let{slug:n,environment:i,roleArn:s,s3BucketName:c,organizedPrefix:l="organized/",timeout:u=60,memorySize:h=512}=a,y=r({slug:n,environment:i,resourceType:"inbound-email"}),f=t(y),S=t(`${y}-permission`),b={Type:"AWS::Lambda::Function",Properties:{FunctionName:y,Runtime:"nodejs20.x",Handler:"index.handler",Role:s,Timeout:u,MemorySize:h,Environment:{Variables:{S3_BUCKET:c,ORGANIZED_PREFIX:l}},Code:{ZipFile:m.LambdaCode.inboundEmail},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:i},{Key:"Purpose",Value:"InboundEmail"}]}},C={Type:"AWS::Lambda::Permission",Properties:{FunctionName:N.Ref(f),Action:"lambda:InvokeFunction",Principal:"ses.amazonaws.com",SourceAccount:N.Ref("AWS::AccountId")}};return{function:b,permission:C,logicalId:f,permissionLogicalId:S}}static createEmailConversionLambda(a){let{slug:n,environment:i,roleArn:s,s3BucketName:c,convertedPrefix:l="converted/",timeout:u=60,memorySize:h=512}=a,y=r({slug:n,environment:i,resourceType:"email-conversion"}),f=t(y);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:y,Runtime:"nodejs20.x",Handler:"index.handler",Role:s,Timeout:u,MemorySize:h,Environment:{Variables:{S3_BUCKET:c,CONVERTED_PREFIX:l}},Code:{ZipFile:m.LambdaCode.emailConversion},Tags:[{Key:"Name",Value:y},{Key:"Environment",Value:i},{Key:"Purpose",Value:"EmailConversion"}]}},logicalId:f}}static createEmailBucketNotification(a){let{lambdaArn:n,prefix:i="inbound/",suffix:s,events:c}=a,l=c??["s3:ObjectCreated:*"],u={};if(i||s){if(u.S3Key={Rules:[]},i)u.S3Key.Rules.push({Name:"prefix",Value:i});if(s)u.S3Key.Rules.push({Name:"suffix",Value:s})}return{notificationConfiguration:{LambdaConfigurations:[{Event:l[0],Function:n,Filter:Object.keys(u).length>0?u:void 0}]}}}static createS3LambdaPermission(a){let{slug:n,environment:i,lambdaLogicalId:s,s3BucketArn:c}=a,l=r({slug:n,environment:i,resourceType:"s3-lambda-permission"}),u=t(l);return{permission:{Type:"AWS::Lambda::Permission",Properties:{FunctionName:N.Ref(s),Action:"lambda:InvokeFunction",Principal:"s3.amazonaws.com",SourceArn:c}},logicalId:u}}static createEmailProcessingStack(a){let{slug:n,environment:i,domain:s,s3BucketName:c,s3BucketArn:l,configurationSetName:u,enableInbound:h=!0,enableConversion:y=!0}=a,f={},{role:S,policy:b,roleLogicalId:C,policyLogicalId:T}=m.createEmailLambdaRole({slug:n,environment:i,s3BucketArn:l,sesIdentityArn:`arn:aws:ses:*:*:identity/${s}`});f[C]=S,f[T]=b;let{function:v,logicalId:w}=m.createOutboundEmailLambda({slug:n,environment:i,roleArn:N.GetAtt(C,"Arn"),domain:s,configurationSetName:u});f[w]=v;let R={roleLogicalId:C,outboundLambdaLogicalId:w};if(h){let{function:k,permission:W,logicalId:P,permissionLogicalId:V}=m.createInboundEmailLambda({slug:n,environment:i,roleArn:N.GetAtt(C,"Arn"),s3BucketName:c});f[P]=k,f[V]=W;let{permission:B,logicalId:j}=m.createS3LambdaPermission({slug:n,environment:i,lambdaLogicalId:P,s3BucketArn:l});f[j]=B,R.inboundLambdaLogicalId=P}if(y){let{function:k,logicalId:W}=m.createEmailConversionLambda({slug:n,environment:i,roleArn:N.GetAtt(C,"Arn"),s3BucketName:c});f[W]=k,R.conversionLambdaLogicalId=W}return{resources:f,outputs:R}}static LambdaCode={outboundEmail:`
624
624
  const { SESClient, SendRawEmailCommand } = require('@aws-sdk/client-ses');
625
625
  const ses = new SESClient({});
626
626
 
@@ -1658,7 +1658,7 @@ catch (error) {
1658
1658
 
1659
1659
  return { statusCode: 200, body: 'OK' };
1660
1660
  };
1661
- `;class Qe{static LambdaCode={incomingCall:va,voicemail:ur,missedCall:lr};static createConnectInstance(a){let{slug:n,environment:i,instanceAlias:s,inboundCallsEnabled:c=!0,outboundCallsEnabled:l=!0}=a;return{[`${n}ConnectInstance`]:{Type:"AWS::Connect::Instance",Properties:{InstanceAlias:s,IdentityManagementType:"CONNECT_MANAGED",Attributes:{InboundCalls:c,OutboundCalls:l,ContactflowLogs:!0,ContactLens:!0,AutoResolveBestVoices:!0,UseCustomTTSVoices:!1,EarlyMedia:!0}}}}}static createHoursOfOperation(a){return{[`${a.slug}HoursOfOperation`]:{Type:"AWS::Connect::HoursOfOperation",Properties:{InstanceArn:a.instanceArn,Name:a.name,TimeZone:a.timezone,Config:a.schedule.map((n)=>({Day:n.day,StartTime:{Hours:n.startHour,Minutes:n.startMinute},EndTime:{Hours:n.endHour,Minutes:n.endMinute}}))}}}}static createQueue(a){return{[`${a.slug}Queue`]:{Type:"AWS::Connect::Queue",Properties:{InstanceArn:a.instanceArn,Name:a.name,HoursOfOperationArn:a.hoursOfOperationArn,MaxContacts:a.maxContacts||10}}}}static createContactFlow(a){return{[`${a.slug}ContactFlow`]:{Type:"AWS::Connect::ContactFlow",Properties:{InstanceArn:a.instanceArn,Name:a.name,Type:a.type,Content:a.content}}}}static createBasicIvrFlow(a){let n={Version:"2019-10-30",StartAction:"greeting",Actions:[{Identifier:"greeting",Type:"MessageParticipant",Parameters:{Text:a.greeting},Transitions:{NextAction:"transfer_to_queue",Errors:[{NextAction:"disconnect"}]}},{Identifier:"transfer_to_queue",Type:"TransferToQueue",Parameters:{QueueId:a.queueArn},Transitions:{NextAction:a.voicemailLambdaArn?"voicemail":"disconnect",Errors:[{NextAction:"disconnect"}]}},...a.voicemailLambdaArn?[{Identifier:"voicemail",Type:"InvokeLambdaFunction",Parameters:{LambdaFunctionARN:a.voicemailLambdaArn},Transitions:{NextAction:"disconnect",Errors:[{NextAction:"disconnect"}]}}]:[],{Identifier:"disconnect",Type:"DisconnectParticipant",Parameters:{},Transitions:{}}]};return JSON.stringify(n)}static createPhoneLambdaRole(a){return{[`${a.slug}PhoneLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${a.slug}-phone-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:"PhoneLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject"],Resource:"*"},{Effect:"Allow",Action:["transcribe:StartTranscriptionJob","transcribe:GetTranscriptionJob"],Resource:"*"},{Effect:"Allow",Action:["connect:*"],Resource:"*"}]}}]}}}}static createIncomingCallLambda(a){return{[`${a.slug}IncomingCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${a.slug}-incoming-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:a.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:Qe.LambdaCode.incomingCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:a.notificationTopicArn||"",CALL_LOG_TABLE:a.callLogTable||"",WEBHOOK_URL:a.webhookUrl||""}}}}}}static createVoicemailLambda(a){return{[`${a.slug}VoicemailLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${a.slug}-voicemail`,Runtime:"nodejs20.x",Handler:"index.handler",Role:a.roleArn,Timeout:300,MemorySize:512,Code:{ZipFile:Qe.LambdaCode.voicemail},Environment:{Variables:{VOICEMAIL_BUCKET:a.voicemailBucket,NOTIFICATION_TOPIC_ARN:a.notificationTopicArn||"",CALL_LOG_TABLE:a.callLogTable||"",TRANSCRIPTION_ENABLED:a.transcriptionEnabled?"true":"false"}}}}}}static createMissedCallLambda(a){return{[`${a.slug}MissedCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${a.slug}-missed-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:a.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:Qe.LambdaCode.missedCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:a.notificationTopicArn||"",CALL_LOG_TABLE:a.callLogTable||"",WEBHOOK_URL:a.webhookUrl||""}}}}}}static createCallLogTable(a){return{[`${a.slug}CallLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${a.slug}-call-log`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"contactId",AttributeType:"S"}],KeySchema:[{AttributeName:"contactId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createCompleteSetup(a){let n={},i={};Object.assign(n,Qe.createPhoneLambdaRole({slug:a.slug})),Object.assign(n,Qe.createCallLogTable({slug:a.slug})),n[`${a.slug}PhoneNotificationTopic`]={Type:"AWS::SNS::Topic",Properties:{TopicName:`${a.slug}-phone-notifications`}},n[`${a.slug}VoicemailBucket`]={Type:"AWS::S3::Bucket",Properties:{BucketName:`${a.slug}-voicemails`,LifecycleConfiguration:{Rules:[{Id:"DeleteOldVoicemails",Status:"Enabled",ExpirationInDays:90}]}}};let s={"Fn::GetAtt":[`${a.slug}PhoneLambdaRole`,"Arn"]},c={Ref:`${a.slug}PhoneNotificationTopic`},l={Ref:`${a.slug}CallLogTable`},u={Ref:`${a.slug}VoicemailBucket`};if(Object.assign(n,Qe.createIncomingCallLambda({slug:a.slug,roleArn:s,notificationTopicArn:c,callLogTable:l,webhookUrl:a.webhookUrl})),a.voicemailEnabled!==!1)Object.assign(n,Qe.createVoicemailLambda({slug:a.slug,roleArn:s,voicemailBucket:u,notificationTopicArn:c,callLogTable:l,transcriptionEnabled:a.transcriptionEnabled}));return Object.assign(n,Qe.createMissedCallLambda({slug:a.slug,roleArn:s,notificationTopicArn:c,callLogTable:l,webhookUrl:a.webhookUrl})),i[`${a.slug}PhoneNotificationTopicArn`]={Description:"Phone notification topic ARN",Value:{Ref:`${a.slug}PhoneNotificationTopic`}},i[`${a.slug}CallLogTableName`]={Description:"Call log table name",Value:{Ref:`${a.slug}CallLogTable`}},i[`${a.slug}VoicemailBucketName`]={Description:"Voicemail bucket name",Value:{Ref:`${a.slug}VoicemailBucket`}},{resources:n,outputs:i}}}class M{static createQueue(a){let{slug:n,environment:i,name:s,delaySeconds:c=0,visibilityTimeout:l=30,messageRetentionPeriod:u=345600,maxMessageSize:h=262144,receiveMessageWaitTime:y=0,fifo:f=!1,contentBasedDeduplication:S=!1,encrypted:b=!0,kmsKeyId:C}=a,T=s||r({slug:n,environment:i,resourceType:"queue"}),v=f?`${T}.fifo`:T,w=t(T),R={Type:"AWS::SQS::Queue",Properties:{QueueName:v,DelaySeconds:c,MaximumMessageSize:h,MessageRetentionPeriod:u,ReceiveMessageWaitTimeSeconds:y,VisibilityTimeout:l,Tags:[{Key:"Name",Value:v},{Key:"Environment",Value:i}]}};if(f)R.Properties.FifoQueue=!0,R.Properties.ContentBasedDeduplication=S;if(b)if(C)R.Properties.KmsMasterKeyId=C;else R.Properties.SqsManagedSseEnabled=!0;return{queue:R,logicalId:w}}static createDeadLetterQueue(a,n){let{slug:i,environment:s,maxReceiveCount:c=3}=n,l=r({slug:i,environment:s,resourceType:"dlq"}),u=t(l),h={Type:"AWS::SQS::Queue",Properties:{QueueName:l,MessageRetentionPeriod:1209600,Tags:[{Key:"Name",Value:l},{Key:"Environment",Value:s},{Key:"Type",Value:"DeadLetterQueue"}]}},y={Type:"AWS::SQS::Queue",Properties:{RedrivePolicy:{deadLetterTargetArn:N.GetAtt(u,"Arn"),maxReceiveCount:c}}};return{deadLetterQueue:h,updatedSourceQueue:y,deadLetterLogicalId:u}}static createSchedule(a,n){let{slug:i,environment:s,name:c,description:l,enabled:u=!0}=n,h=c||r({slug:i,environment:s,resourceType:"schedule"}),y=t(h);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:h,Description:l,ScheduleExpression:a,State:u?"ENABLED":"DISABLED",Targets:[]}},logicalId:y}}static scheduleEcsTask(a,n,i){let{slug:s,environment:c,name:l,description:u,enabled:h=!0,taskDefinitionArn:y,clusterArn:f,subnets:S,securityGroups:b=[],assignPublicIp:C=!1,taskCount:T=1,containerOverrides:v}=i,w=l||r({slug:s,environment:c,resourceType:"ecs-schedule"}),R=t(w),k={Id:"1",Arn:f,RoleArn:n,EcsParameters:{TaskDefinitionArn:y,TaskCount:T,LaunchType:"FARGATE",NetworkConfiguration:{awsvpcConfiguration:{Subnets:S,SecurityGroups:b,AssignPublicIp:C?"ENABLED":"DISABLED"}},PlatformVersion:"LATEST"}};if(v&&v.length>0)k.Input=JSON.stringify({containerOverrides:v});return{rule:{Type:"AWS::Events::Rule",Properties:{Name:w,Description:u||`Scheduled ECS task: ${y}`,ScheduleExpression:a,State:h?"ENABLED":"DISABLED",Targets:[k]}},logicalId:R}}static scheduleLambda(a,n){let{slug:i,environment:s,name:c,description:l,enabled:u=!0,functionArn:h,input:y}=n,f=c||r({slug:i,environment:s,resourceType:"lambda-schedule"}),S=t(f),b={Id:"1",Arn:h};if(y)b.Input=JSON.stringify(y);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:f,Description:l||`Scheduled Lambda: ${h}`,ScheduleExpression:a,State:u?"ENABLED":"DISABLED",Targets:[b]}},logicalId:S}}static scheduleSqsMessage(a,n){let{slug:i,environment:s,name:c,description:l,enabled:u=!0,queueArn:h,messageGroupId:y}=n,f=c||r({slug:i,environment:s,resourceType:"sqs-schedule"}),S=t(f),b={Id:"1",Arn:h};if(y)b.SqsParameters={MessageGroupId:y};return{rule:{Type:"AWS::Events::Rule",Properties:{Name:f,Description:l||`Scheduled SQS message: ${h}`,ScheduleExpression:a,State:u?"ENABLED":"DISABLED",Targets:[b]}},logicalId:S}}static addTarget(a,n){if(!a.Properties.Targets)a.Properties.Targets=[];let i={Id:n.id,Arn:n.arn};if(n.roleArn)i.RoleArn=n.roleArn;if(n.input)i.Input=JSON.stringify(n.input);return a.Properties.Targets.push(i),a}static toCronExpression(a){if(a.startsWith("cron(")||a.startsWith("rate("))return a;return`cron(${a})`}static rateExpression(a,n){return`rate(${a} ${n})`}static CronExpressions={EveryMinute:"cron(* * * * ? *)",Every5Minutes:"cron(*/5 * * * ? *)",Every15Minutes:"cron(*/15 * * * ? *)",Every30Minutes:"cron(*/30 * * * ? *)",Hourly:"cron(0 * * * ? *)",Daily:"cron(0 0 * * ? *)",DailyAt9AM:"cron(0 9 * * ? *)",DailyAtMidnight:"cron(0 0 * * ? *)",Weekly:"cron(0 0 ? * SUN *)",Monthly:"cron(0 0 1 * ? *)"};static RateExpressions={Every1Minute:"rate(1 minute)",Every5Minutes:"rate(5 minutes)",Every10Minutes:"rate(10 minutes)",Every15Minutes:"rate(15 minutes)",Every30Minutes:"rate(30 minutes)",Every1Hour:"rate(1 hour)",Every6Hours:"rate(6 hours)",Every12Hours:"rate(12 hours)",Every1Day:"rate(1 day)"};static rateStringToExpression(a){let n=a.toLowerCase().trim(),i=n.match(/^every\s+(\d+)\s+(minute|minutes|hour|hours|day|days)$/i);if(i){let f=parseInt(i[1],10),S=i[2].toLowerCase(),b=S.endsWith("s")&&f===1?S.slice(0,-1):S,C=!S.endsWith("s")&&f>1?`${S}s`:S;return`rate(${f} ${f===1?b:C})`}let s=n.match(/^every\s+(minute|hour|day)$/i);if(s)return`rate(1 ${s[1]})`;let c={"every minute":"rate(1 minute)","every hour":"rate(1 hour)","every day":"rate(1 day)",hourly:"cron(0 * * * ? *)",daily:"cron(0 0 * * ? *)","daily at midnight":"cron(0 0 * * ? *)",weekly:"cron(0 0 ? * SUN *)",monthly:"cron(0 0 1 * ? *)",yearly:"cron(0 0 1 1 ? *)"};if(c[n])return c[n];let l=n.match(/^daily\s+at\s+(\d{1,2})\s*(am|pm)?$/i);if(l){let f=parseInt(l[1],10),S=l[2]?.toLowerCase();if(S==="pm"&&f!==12)f+=12;else if(S==="am"&&f===12)f=0;return`cron(0 ${f} * * ? *)`}let u=n.match(/^at\s+(\d{1,2}):(\d{2})$/i);if(u){let f=parseInt(u[1],10);return`cron(${parseInt(u[2],10)} ${f} * * ? *)`}let h={monday:"MON",tuesday:"TUE",wednesday:"WED",thursday:"THU",friday:"FRI",saturday:"SAT",sunday:"SUN"},y=n.match(/^every\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/i);if(y)return`cron(0 0 ? * ${h[y[1].toLowerCase()]} *)`;return M.toCronExpression(a)}static JobConfig={create:(a)=>{let{name:n,handler:i,retries:s=3,backoff:c="exponential",backoffDelay:l=1000,maxDelay:u=30000,timeout:h=60000,jitter:y=!0}=a;return{name:n,handler:i,retries:s,backoff:c,backoffDelay:l,maxDelay:u,timeout:h,jitter:y}},calculateDelay:(a,n)=>{let{backoff:i,backoffDelay:s,maxDelay:c,jitter:l}=n,u;switch(i){case"linear":u=s*a;break;case"exponential":u=s*2**(a-1);break;case"fixed":default:u=s}if(u=Math.min(u,c||Number.MAX_SAFE_INTEGER),l){let h=u*0.25*Math.random();u+=h}return Math.floor(u)},presets:{fastRetry:{retries:5,backoff:"exponential",backoffDelay:100,maxDelay:5000,jitter:!0},standard:{retries:3,backoff:"exponential",backoffDelay:1000,maxDelay:30000,jitter:!0},longRunning:{retries:2,backoff:"exponential",backoffDelay:5000,maxDelay:60000,timeout:300000,jitter:!0},critical:{retries:10,backoff:"exponential",backoffDelay:500,maxDelay:60000,jitter:!0},noRetry:{retries:0,backoff:"fixed",backoffDelay:0,maxDelay:0,jitter:!1}}};static createJobContainerOverride(a){let{containerName:n,jobClass:i,jobData:s,environment:c={}}=a,l=[{name:"JOB_CLASS",value:i}];if(s)l.push({name:"JOB_DATA",value:JSON.stringify(s)});for(let[u,h]of Object.entries(c))l.push({name:u,value:h});return{name:n,command:["bun","run","app/Jobs/runner.ts"],environment:l}}static createScheduledJob(a){let{slug:n,environment:i,schedule:s,jobClass:c,jobData:l,taskDefinitionArn:u,clusterArn:h,subnets:y,securityGroups:f=[],roleArn:S,containerName:b="app"}=a,C=M.rateStringToExpression(s),T=M.createJobContainerOverride({containerName:b,jobClass:c,jobData:l});return M.scheduleEcsTask(C,S,{slug:n,environment:i,name:`${n}-${c.toLowerCase().replace(/[^a-z0-9]/g,"-")}`,description:`Scheduled job: ${c}`,taskDefinitionArn:u,clusterArn:h,subnets:y,securityGroups:f,containerOverrides:[T]})}static QueuePresets={highThroughput:(a,n)=>M.createQueue({slug:a,environment:n,visibilityTimeout:30,receiveMessageWaitTime:0,delaySeconds:0}),longRunning:(a,n)=>M.createQueue({slug:a,environment:n,visibilityTimeout:300,messageRetentionPeriod:1209600}),fifo:(a,n)=>M.createQueue({slug:a,environment:n,fifo:!0,contentBasedDeduplication:!0}),delayed:(a,n,i=60)=>M.createQueue({slug:a,environment:n,delaySeconds:i})}}class ct{static async discoverJobs(a){let{projectRoot:n,jobsPath:i="app/Jobs"}=a,s=`${n}/${i}`,c=[];try{let l=await import("node:fs"),u=await import("node:path");if(!l.existsSync(s))return[];let h=l.readdirSync(s).filter((y)=>y.endsWith(".ts")&&!y.startsWith("_")&&y!=="runner.ts");for(let y of h){let f=u.join(s,y),S=y.replace(".ts",""),b=l.readFileSync(f,"utf-8"),C=ct.parseJobMetadata(b,S,f);if(C)c.push(C)}}catch{return[]}return c}static parseJobMetadata(a,n,i){let s=a.match(/export\s + const\s + schedule\s*=\s*['"`]([^'"`]+)['"`]/)||a.match(/schedule:\s*['"`]([^'"`]+)['"`]/),c=a.match(/export\s+const\s+enabled\s*=\s*(true|false)/)||a.match(/enabled:\s*(true|false)/),l=a.match(/export\s+const\s+retries\s*=\s*(\d+)/)||a.match(/retries:\s*(\d+)/),u=a.match(/export\s+const\s+timeout\s*=\s*(\d+)/)||a.match(/timeout:\s*(\d+)/),h=a.match(/export\s+const\s+backoff\s*=\s*['"`](linear|exponential|fixed)['"`]/)||a.match(/backoff:\s*['"`](linear|exponential|fixed)['"`]/),y=a.match(/export\s + const\s + description\s*=\s*['"`]([^'"`]+)['"`]/)||a.match(/description:\s*['"`]([^'"`]+)['"`]/);if(!(a.includes("export async function handle")||a.includes("export function handle")||a.includes("export default")))return null;return{name:n,path:i,schedule:s?.[1],handler:`${n}.handle`,enabled:c?.[1]!=="false",retries:l?parseInt(l[1],10):void 0,backoff:h?.[1],timeout:u?parseInt(u[1],10):void 0,description:y?.[1]}}static async discoverActions(a){let{projectRoot:n,actionsPath:i="app/Actions"}=a,s=`${n}/${i}`,c=[];try{let l=await import("node:fs"),u=await import("node:path");if(!l.existsSync(s))return[];let h=l.readdirSync(s).filter((y)=>y.endsWith(".ts")&&!y.startsWith("_"));for(let y of h){let f=u.join(s,y),S=y.replace(".ts",""),b=l.readFileSync(f,"utf-8"),C=ct.parseActionMetadata(b,S,f);if(C)c.push(C)}}catch{return[]}return c}static parseActionMetadata(a,n,i){if(!(a.includes("export async function handle")||a.includes("export function handle")||a.includes("export default")))return null;let s=a.match(/export\s + const\s + description\s*=\s*['"`]([^'"`]+)['"`]/)||a.match(/description:\s*['"`]([^'"`]+)['"`]/);return{name:n,path:i,handler:`${n}.handle`,description:s?.[1]}}static generateScheduledJobResources(a){let{slug:n,environment:i,jobs:s,taskDefinitionArn:c,clusterArn:l,subnets:u,securityGroups:h=[],roleArn:y,containerName:f="app"}=a,S={},b=0;for(let C of s){if(!C.schedule||!C.enabled)continue;let{rule:T,logicalId:v}=M.createScheduledJob({slug:n,environment:i,schedule:C.schedule,jobClass:C.name,taskDefinitionArn:c,clusterArn:l,subnets:u,securityGroups:h,roleArn:y,containerName:f});S[v]=T,b++}return{rules:S,count:b}}static generateJobRunnerScript(){return`#!/usr/bin/env bun
1661
+ `;class He{static LambdaCode={incomingCall:va,voicemail:ur,missedCall:lr};static createConnectInstance(a){let{slug:n,environment:i,instanceAlias:s,inboundCallsEnabled:c=!0,outboundCallsEnabled:l=!0}=a;return{[`${n}ConnectInstance`]:{Type:"AWS::Connect::Instance",Properties:{InstanceAlias:s,IdentityManagementType:"CONNECT_MANAGED",Attributes:{InboundCalls:c,OutboundCalls:l,ContactflowLogs:!0,ContactLens:!0,AutoResolveBestVoices:!0,UseCustomTTSVoices:!1,EarlyMedia:!0}}}}}static createHoursOfOperation(a){return{[`${a.slug}HoursOfOperation`]:{Type:"AWS::Connect::HoursOfOperation",Properties:{InstanceArn:a.instanceArn,Name:a.name,TimeZone:a.timezone,Config:a.schedule.map((n)=>({Day:n.day,StartTime:{Hours:n.startHour,Minutes:n.startMinute},EndTime:{Hours:n.endHour,Minutes:n.endMinute}}))}}}}static createQueue(a){return{[`${a.slug}Queue`]:{Type:"AWS::Connect::Queue",Properties:{InstanceArn:a.instanceArn,Name:a.name,HoursOfOperationArn:a.hoursOfOperationArn,MaxContacts:a.maxContacts||10}}}}static createContactFlow(a){return{[`${a.slug}ContactFlow`]:{Type:"AWS::Connect::ContactFlow",Properties:{InstanceArn:a.instanceArn,Name:a.name,Type:a.type,Content:a.content}}}}static createBasicIvrFlow(a){let n={Version:"2019-10-30",StartAction:"greeting",Actions:[{Identifier:"greeting",Type:"MessageParticipant",Parameters:{Text:a.greeting},Transitions:{NextAction:"transfer_to_queue",Errors:[{NextAction:"disconnect"}]}},{Identifier:"transfer_to_queue",Type:"TransferToQueue",Parameters:{QueueId:a.queueArn},Transitions:{NextAction:a.voicemailLambdaArn?"voicemail":"disconnect",Errors:[{NextAction:"disconnect"}]}},...a.voicemailLambdaArn?[{Identifier:"voicemail",Type:"InvokeLambdaFunction",Parameters:{LambdaFunctionARN:a.voicemailLambdaArn},Transitions:{NextAction:"disconnect",Errors:[{NextAction:"disconnect"}]}}]:[],{Identifier:"disconnect",Type:"DisconnectParticipant",Parameters:{},Transitions:{}}]};return JSON.stringify(n)}static createPhoneLambdaRole(a){return{[`${a.slug}PhoneLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${a.slug}-phone-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:"PhoneLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject"],Resource:"*"},{Effect:"Allow",Action:["transcribe:StartTranscriptionJob","transcribe:GetTranscriptionJob"],Resource:"*"},{Effect:"Allow",Action:["connect:*"],Resource:"*"}]}}]}}}}static createIncomingCallLambda(a){return{[`${a.slug}IncomingCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${a.slug}-incoming-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:a.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:He.LambdaCode.incomingCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:a.notificationTopicArn||"",CALL_LOG_TABLE:a.callLogTable||"",WEBHOOK_URL:a.webhookUrl||""}}}}}}static createVoicemailLambda(a){return{[`${a.slug}VoicemailLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${a.slug}-voicemail`,Runtime:"nodejs20.x",Handler:"index.handler",Role:a.roleArn,Timeout:300,MemorySize:512,Code:{ZipFile:He.LambdaCode.voicemail},Environment:{Variables:{VOICEMAIL_BUCKET:a.voicemailBucket,NOTIFICATION_TOPIC_ARN:a.notificationTopicArn||"",CALL_LOG_TABLE:a.callLogTable||"",TRANSCRIPTION_ENABLED:a.transcriptionEnabled?"true":"false"}}}}}}static createMissedCallLambda(a){return{[`${a.slug}MissedCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${a.slug}-missed-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:a.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:He.LambdaCode.missedCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:a.notificationTopicArn||"",CALL_LOG_TABLE:a.callLogTable||"",WEBHOOK_URL:a.webhookUrl||""}}}}}}static createCallLogTable(a){return{[`${a.slug}CallLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${a.slug}-call-log`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"contactId",AttributeType:"S"}],KeySchema:[{AttributeName:"contactId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createCompleteSetup(a){let n={},i={};Object.assign(n,He.createPhoneLambdaRole({slug:a.slug})),Object.assign(n,He.createCallLogTable({slug:a.slug})),n[`${a.slug}PhoneNotificationTopic`]={Type:"AWS::SNS::Topic",Properties:{TopicName:`${a.slug}-phone-notifications`}},n[`${a.slug}VoicemailBucket`]={Type:"AWS::S3::Bucket",Properties:{BucketName:`${a.slug}-voicemails`,LifecycleConfiguration:{Rules:[{Id:"DeleteOldVoicemails",Status:"Enabled",ExpirationInDays:90}]}}};let s={"Fn::GetAtt":[`${a.slug}PhoneLambdaRole`,"Arn"]},c={Ref:`${a.slug}PhoneNotificationTopic`},l={Ref:`${a.slug}CallLogTable`},u={Ref:`${a.slug}VoicemailBucket`};if(Object.assign(n,He.createIncomingCallLambda({slug:a.slug,roleArn:s,notificationTopicArn:c,callLogTable:l,webhookUrl:a.webhookUrl})),a.voicemailEnabled!==!1)Object.assign(n,He.createVoicemailLambda({slug:a.slug,roleArn:s,voicemailBucket:u,notificationTopicArn:c,callLogTable:l,transcriptionEnabled:a.transcriptionEnabled}));return Object.assign(n,He.createMissedCallLambda({slug:a.slug,roleArn:s,notificationTopicArn:c,callLogTable:l,webhookUrl:a.webhookUrl})),i[`${a.slug}PhoneNotificationTopicArn`]={Description:"Phone notification topic ARN",Value:{Ref:`${a.slug}PhoneNotificationTopic`}},i[`${a.slug}CallLogTableName`]={Description:"Call log table name",Value:{Ref:`${a.slug}CallLogTable`}},i[`${a.slug}VoicemailBucketName`]={Description:"Voicemail bucket name",Value:{Ref:`${a.slug}VoicemailBucket`}},{resources:n,outputs:i}}}class M{static createQueue(a){let{slug:n,environment:i,name:s,delaySeconds:c=0,visibilityTimeout:l=30,messageRetentionPeriod:u=345600,maxMessageSize:h=262144,receiveMessageWaitTime:y=0,fifo:f=!1,contentBasedDeduplication:S=!1,encrypted:b=!0,kmsKeyId:C}=a,T=s||r({slug:n,environment:i,resourceType:"queue"}),v=f?`${T}.fifo`:T,w=t(T),R={Type:"AWS::SQS::Queue",Properties:{QueueName:v,DelaySeconds:c,MaximumMessageSize:h,MessageRetentionPeriod:u,ReceiveMessageWaitTimeSeconds:y,VisibilityTimeout:l,Tags:[{Key:"Name",Value:v},{Key:"Environment",Value:i}]}};if(f)R.Properties.FifoQueue=!0,R.Properties.ContentBasedDeduplication=S;if(b)if(C)R.Properties.KmsMasterKeyId=C;else R.Properties.SqsManagedSseEnabled=!0;return{queue:R,logicalId:w}}static createDeadLetterQueue(a,n){let{slug:i,environment:s,maxReceiveCount:c=3}=n,l=r({slug:i,environment:s,resourceType:"dlq"}),u=t(l),h={Type:"AWS::SQS::Queue",Properties:{QueueName:l,MessageRetentionPeriod:1209600,Tags:[{Key:"Name",Value:l},{Key:"Environment",Value:s},{Key:"Type",Value:"DeadLetterQueue"}]}},y={Type:"AWS::SQS::Queue",Properties:{RedrivePolicy:{deadLetterTargetArn:N.GetAtt(u,"Arn"),maxReceiveCount:c}}};return{deadLetterQueue:h,updatedSourceQueue:y,deadLetterLogicalId:u}}static createSchedule(a,n){let{slug:i,environment:s,name:c,description:l,enabled:u=!0}=n,h=c||r({slug:i,environment:s,resourceType:"schedule"}),y=t(h);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:h,Description:l,ScheduleExpression:a,State:u?"ENABLED":"DISABLED",Targets:[]}},logicalId:y}}static scheduleEcsTask(a,n,i){let{slug:s,environment:c,name:l,description:u,enabled:h=!0,taskDefinitionArn:y,clusterArn:f,subnets:S,securityGroups:b=[],assignPublicIp:C=!1,taskCount:T=1,containerOverrides:v}=i,w=l||r({slug:s,environment:c,resourceType:"ecs-schedule"}),R=t(w),k={Id:"1",Arn:f,RoleArn:n,EcsParameters:{TaskDefinitionArn:y,TaskCount:T,LaunchType:"FARGATE",NetworkConfiguration:{awsvpcConfiguration:{Subnets:S,SecurityGroups:b,AssignPublicIp:C?"ENABLED":"DISABLED"}},PlatformVersion:"LATEST"}};if(v&&v.length>0)k.Input=JSON.stringify({containerOverrides:v});return{rule:{Type:"AWS::Events::Rule",Properties:{Name:w,Description:u||`Scheduled ECS task: ${y}`,ScheduleExpression:a,State:h?"ENABLED":"DISABLED",Targets:[k]}},logicalId:R}}static scheduleLambda(a,n){let{slug:i,environment:s,name:c,description:l,enabled:u=!0,functionArn:h,input:y}=n,f=c||r({slug:i,environment:s,resourceType:"lambda-schedule"}),S=t(f),b={Id:"1",Arn:h};if(y)b.Input=JSON.stringify(y);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:f,Description:l||`Scheduled Lambda: ${h}`,ScheduleExpression:a,State:u?"ENABLED":"DISABLED",Targets:[b]}},logicalId:S}}static scheduleSqsMessage(a,n){let{slug:i,environment:s,name:c,description:l,enabled:u=!0,queueArn:h,messageGroupId:y}=n,f=c||r({slug:i,environment:s,resourceType:"sqs-schedule"}),S=t(f),b={Id:"1",Arn:h};if(y)b.SqsParameters={MessageGroupId:y};return{rule:{Type:"AWS::Events::Rule",Properties:{Name:f,Description:l||`Scheduled SQS message: ${h}`,ScheduleExpression:a,State:u?"ENABLED":"DISABLED",Targets:[b]}},logicalId:S}}static addTarget(a,n){if(!a.Properties.Targets)a.Properties.Targets=[];let i={Id:n.id,Arn:n.arn};if(n.roleArn)i.RoleArn=n.roleArn;if(n.input)i.Input=JSON.stringify(n.input);return a.Properties.Targets.push(i),a}static toCronExpression(a){if(a.startsWith("cron(")||a.startsWith("rate("))return a;return`cron(${a})`}static rateExpression(a,n){return`rate(${a} ${n})`}static CronExpressions={EveryMinute:"cron(* * * * ? *)",Every5Minutes:"cron(*/5 * * * ? *)",Every15Minutes:"cron(*/15 * * * ? *)",Every30Minutes:"cron(*/30 * * * ? *)",Hourly:"cron(0 * * * ? *)",Daily:"cron(0 0 * * ? *)",DailyAt9AM:"cron(0 9 * * ? *)",DailyAtMidnight:"cron(0 0 * * ? *)",Weekly:"cron(0 0 ? * SUN *)",Monthly:"cron(0 0 1 * ? *)"};static RateExpressions={Every1Minute:"rate(1 minute)",Every5Minutes:"rate(5 minutes)",Every10Minutes:"rate(10 minutes)",Every15Minutes:"rate(15 minutes)",Every30Minutes:"rate(30 minutes)",Every1Hour:"rate(1 hour)",Every6Hours:"rate(6 hours)",Every12Hours:"rate(12 hours)",Every1Day:"rate(1 day)"};static rateStringToExpression(a){let n=a.toLowerCase().trim(),i=n.match(/^every\s+(\d+)\s+(minute|minutes|hour|hours|day|days)$/i);if(i){let f=parseInt(i[1],10),S=i[2].toLowerCase(),b=S.endsWith("s")&&f===1?S.slice(0,-1):S,C=!S.endsWith("s")&&f>1?`${S}s`:S;return`rate(${f} ${f===1?b:C})`}let s=n.match(/^every\s+(minute|hour|day)$/i);if(s)return`rate(1 ${s[1]})`;let c={"every minute":"rate(1 minute)","every hour":"rate(1 hour)","every day":"rate(1 day)",hourly:"cron(0 * * * ? *)",daily:"cron(0 0 * * ? *)","daily at midnight":"cron(0 0 * * ? *)",weekly:"cron(0 0 ? * SUN *)",monthly:"cron(0 0 1 * ? *)",yearly:"cron(0 0 1 1 ? *)"};if(c[n])return c[n];let l=n.match(/^daily\s+at\s+(\d{1,2})\s*(am|pm)?$/i);if(l){let f=parseInt(l[1],10),S=l[2]?.toLowerCase();if(S==="pm"&&f!==12)f+=12;else if(S==="am"&&f===12)f=0;return`cron(0 ${f} * * ? *)`}let u=n.match(/^at\s+(\d{1,2}):(\d{2})$/i);if(u){let f=parseInt(u[1],10);return`cron(${parseInt(u[2],10)} ${f} * * ? *)`}let h={monday:"MON",tuesday:"TUE",wednesday:"WED",thursday:"THU",friday:"FRI",saturday:"SAT",sunday:"SUN"},y=n.match(/^every\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/i);if(y)return`cron(0 0 ? * ${h[y[1].toLowerCase()]} *)`;return M.toCronExpression(a)}static JobConfig={create:(a)=>{let{name:n,handler:i,retries:s=3,backoff:c="exponential",backoffDelay:l=1000,maxDelay:u=30000,timeout:h=60000,jitter:y=!0}=a;return{name:n,handler:i,retries:s,backoff:c,backoffDelay:l,maxDelay:u,timeout:h,jitter:y}},calculateDelay:(a,n)=>{let{backoff:i,backoffDelay:s,maxDelay:c,jitter:l}=n,u;switch(i){case"linear":u=s*a;break;case"exponential":u=s*2**(a-1);break;case"fixed":default:u=s}if(u=Math.min(u,c||Number.MAX_SAFE_INTEGER),l){let h=u*0.25*Math.random();u+=h}return Math.floor(u)},presets:{fastRetry:{retries:5,backoff:"exponential",backoffDelay:100,maxDelay:5000,jitter:!0},standard:{retries:3,backoff:"exponential",backoffDelay:1000,maxDelay:30000,jitter:!0},longRunning:{retries:2,backoff:"exponential",backoffDelay:5000,maxDelay:60000,timeout:300000,jitter:!0},critical:{retries:10,backoff:"exponential",backoffDelay:500,maxDelay:60000,jitter:!0},noRetry:{retries:0,backoff:"fixed",backoffDelay:0,maxDelay:0,jitter:!1}}};static createJobContainerOverride(a){let{containerName:n,jobClass:i,jobData:s,environment:c={}}=a,l=[{name:"JOB_CLASS",value:i}];if(s)l.push({name:"JOB_DATA",value:JSON.stringify(s)});for(let[u,h]of Object.entries(c))l.push({name:u,value:h});return{name:n,command:["bun","run","app/Jobs/runner.ts"],environment:l}}static createScheduledJob(a){let{slug:n,environment:i,schedule:s,jobClass:c,jobData:l,taskDefinitionArn:u,clusterArn:h,subnets:y,securityGroups:f=[],roleArn:S,containerName:b="app"}=a,C=M.rateStringToExpression(s),T=M.createJobContainerOverride({containerName:b,jobClass:c,jobData:l});return M.scheduleEcsTask(C,S,{slug:n,environment:i,name:`${n}-${c.toLowerCase().replace(/[^a-z0-9]/g,"-")}`,description:`Scheduled job: ${c}`,taskDefinitionArn:u,clusterArn:h,subnets:y,securityGroups:f,containerOverrides:[T]})}static QueuePresets={highThroughput:(a,n)=>M.createQueue({slug:a,environment:n,visibilityTimeout:30,receiveMessageWaitTime:0,delaySeconds:0}),longRunning:(a,n)=>M.createQueue({slug:a,environment:n,visibilityTimeout:300,messageRetentionPeriod:1209600}),fifo:(a,n)=>M.createQueue({slug:a,environment:n,fifo:!0,contentBasedDeduplication:!0}),delayed:(a,n,i=60)=>M.createQueue({slug:a,environment:n,delaySeconds:i})}}class ct{static async discoverJobs(a){let{projectRoot:n,jobsPath:i="app/Jobs"}=a,s=`${n}/${i}`,c=[];try{let l=await import("node:fs"),u=await import("node:path");if(!l.existsSync(s))return[];let h=l.readdirSync(s).filter((y)=>y.endsWith(".ts")&&!y.startsWith("_")&&y!=="runner.ts");for(let y of h){let f=u.join(s,y),S=y.replace(".ts",""),b=l.readFileSync(f,"utf-8"),C=ct.parseJobMetadata(b,S,f);if(C)c.push(C)}}catch{return[]}return c}static parseJobMetadata(a,n,i){let s=a.match(/export\s + const\s + schedule\s*=\s*['"`]([^'"`]+)['"`]/)||a.match(/schedule:\s*['"`]([^'"`]+)['"`]/),c=a.match(/export\s+const\s+enabled\s*=\s*(true|false)/)||a.match(/enabled:\s*(true|false)/),l=a.match(/export\s+const\s+retries\s*=\s*(\d+)/)||a.match(/retries:\s*(\d+)/),u=a.match(/export\s+const\s+timeout\s*=\s*(\d+)/)||a.match(/timeout:\s*(\d+)/),h=a.match(/export\s+const\s+backoff\s*=\s*['"`](linear|exponential|fixed)['"`]/)||a.match(/backoff:\s*['"`](linear|exponential|fixed)['"`]/),y=a.match(/export\s + const\s + description\s*=\s*['"`]([^'"`]+)['"`]/)||a.match(/description:\s*['"`]([^'"`]+)['"`]/);if(!(a.includes("export async function handle")||a.includes("export function handle")||a.includes("export default")))return null;return{name:n,path:i,schedule:s?.[1],handler:`${n}.handle`,enabled:c?.[1]!=="false",retries:l?parseInt(l[1],10):void 0,backoff:h?.[1],timeout:u?parseInt(u[1],10):void 0,description:y?.[1]}}static async discoverActions(a){let{projectRoot:n,actionsPath:i="app/Actions"}=a,s=`${n}/${i}`,c=[];try{let l=await import("node:fs"),u=await import("node:path");if(!l.existsSync(s))return[];let h=l.readdirSync(s).filter((y)=>y.endsWith(".ts")&&!y.startsWith("_"));for(let y of h){let f=u.join(s,y),S=y.replace(".ts",""),b=l.readFileSync(f,"utf-8"),C=ct.parseActionMetadata(b,S,f);if(C)c.push(C)}}catch{return[]}return c}static parseActionMetadata(a,n,i){if(!(a.includes("export async function handle")||a.includes("export function handle")||a.includes("export default")))return null;let s=a.match(/export\s + const\s + description\s*=\s*['"`]([^'"`]+)['"`]/)||a.match(/description:\s*['"`]([^'"`]+)['"`]/);return{name:n,path:i,handler:`${n}.handle`,description:s?.[1]}}static generateScheduledJobResources(a){let{slug:n,environment:i,jobs:s,taskDefinitionArn:c,clusterArn:l,subnets:u,securityGroups:h=[],roleArn:y,containerName:f="app"}=a,S={},b=0;for(let C of s){if(!C.schedule||!C.enabled)continue;let{rule:T,logicalId:v}=M.createScheduledJob({slug:n,environment:i,schedule:C.schedule,jobClass:C.name,taskDefinitionArn:c,clusterArn:l,subnets:u,securityGroups:h,roleArn:y,containerName:f});S[v]=T,b++}return{rules:S,count:b}}static generateJobRunnerScript(){return`#!/usr/bin/env bun
1662
1662
  /**
1663
1663
  * Job Runner Script
1664
1664
  * This script is invoked by ECS scheduled tasks to run jobs
@@ -2492,16 +2492,16 @@ rpm -U ./amazon-cloudwatch-agent.rpm || true
2492
2492
  # Mount EFS for shared file storage
2493
2493
  `}},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:[s||"*"],allowedMethods:["GET","HEAD"]}]}},cdn:{enabled:!0,origins:[{originId:"static-assets",domainName:`${i}-static.s3.amazonaws.com`,pathPattern:"/static/*"}],customDomain:s?{domain:s,certificateArn:"TO_BE_GENERATED"}:void 0,cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0},databases:h==="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:`${i}-jobs`,batchSize:10}]},"email-sender":{runtime:"nodejs20.x",handler:"dist/workers/email.handler",memory:512,timeout:60,events:[{type:"sqs",queueName:`${i}-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:`${i}-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:[`${i}-app`,`${i}-nginx`,`${i}-workers`]}},security:{certificate:s?{domain:s,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:h==="mysql"?3306:5432,protocol:"tcp",source:"app-sg"}]},...y==="redis"&&{cache:{ingress:[{port:6379,protocol:"tcp",source:"app-sg"}]}}}}}}}function zy(a){let{name:n,slug:i,domain:s,repository:c,phpVersion:l="8.3",size:u="small",database:h=i.replace(/-/g,"_"),databasePassword:y,sslEmail:f,deployStrategy:S="push",provider:b="hetzner"}=a;return{project:{name:n,slug:i,region:"us-east-1"},mode:"server",cloud:{provider:b},environments:{production:{type:"production",domain:s}},infrastructure:{compute:{mode:"server",size:u,runtime:"php",webServer:"nginx",php:{versions:[l],default:l},managedServices:{mysql:!0,redis:!0},firewall:{enabled:!0},autoUpdates:!0,monitoring:!0,backups:{enabled:!0,schedule:"0 2 * * *",retentionCount:7}},appDatabase:{engine:"mysql",name:h,username:h,password:y}},sites:{main:{root:".",type:"laravel",domain:s,phpVersion:l,repository:{...c,strategy:S},scheduler:!0,queues:[{connection:"redis",queue:"default",processes:1}],ssl:{provider:"letsencrypt",email:f}}}}}function Ky(a){let{name:n,slug:i,domain:s,layers:c,phpVersion:l="8.3",architecture:u="x86_64",memory:h=1024,build:y,deploy:f=["migrate --force"],cache:S="dynamodb",scheduler:b="on",region:C="us-east-1"}=a;return{project:{name:n,slug:i,region:C},mode:"serverless",environments:{production:{type:"production",domain:s,app:{kind:"php",runtime:"provided.al2023",phpVersion:l,architecture:u,layers:c,memory:h,build:y,deploy:f,assets:"public",queues:!0,scheduler:b,cache:{driver:S},domain:s}}}}}function Wy(a){return{root:a.root??"packages/ui/dist",deploy:"server",type:"static",domain:a.domain,build:a.build??"cd packages/ui && bun install && bun run build",ssl:{provider:"letsencrypt"},auth:{username:a.username??"admin",password:a.password}}}var lf=bp,uf="./node_modules/@stacksjs/ts-cloud/dist/bin/dashboard-server.js";function gn(a){let n=a.split(".").filter(Boolean);return n.length<=2?a:n.slice(-2).join(".")}function hn(a){let n=2166136261;for(let i=0;i<a.length;i++)n^=a.charCodeAt(i),n=Math.imul(n,16777619);return n>>>0}var pf=20000,gf=12000;function mf(a){return pf+hn(a)%gf}function Ea(a,n){let i=gn(a);if(i===a)return`dashboard.${i}`;for(let s of n)if(s===i)return`dashboard.${i}`;return`dashboard.${a}`}function Pa(a,n){let i=[],s=a.infrastructure?.dns?.domain;if(s&&!a.cloud?.attachTo)i.push(s);if(n&&a.environments?.[n]?.domain)i.push(a.environments[n].domain);for(let c of Object.values(a.sites??{})){let l=c;if(!l||l.redirect)continue;let u=l.domain;if(typeof u==="string")i.push(u);else if(Array.isArray(u))i.push(...u.filter((h)=>typeof h==="string"))}return i.filter((c)=>c&&!c.startsWith("dashboard."))}function hf(a,n,i){if(i)return i;let s=Pa(a,n),c=s[0];if(!c)return null;return Ea(c,s)}function ff(a,n,i){if(i)return[i];let s=Pa(a,n),c=[];for(let l of s){let u=Ea(l,s);if(!c.includes(u))c.push(u)}return c}function Qt(a){return Object.entries(a.sites??{}).some(([n,i])=>{if(!i)return!1;let s=i.root??"";return Nr(n)||s==="ui/dist"||s.endsWith("/ui/dist")||s.endsWith("/dist/ui")})}var wp="dashboard-";function Rp(a){return wp+a.replace(/^dashboard\./,"").replace(/\./g,"-")}function Nr(a){return a==="dashboard"||a.startsWith(wp)}function gi(a,n,i){if(Qt(a))return[];if(a.cloud?.attachTo)return[];let s=i.password?{auth:{username:i.username||"admin",password:i.password,realm:i.realm}}:{},c=i.build===!1||i.build===void 0?{}:{build:i.build};if(i.live!==!1){let l=hf(a,n,i.domain);if(!l)return[];let u=i.port??mf(l),h=a.infrastructure?.appDatabase??a.infrastructure?.compute?.database,y={root:i.uiRoot,deploy:"server",domain:l,preStart:["bun install --production --no-save"],start:`bun ${uf} --box --host 127.0.0.1 --port ${u}`,port:u,cpuWeight:10,ioWeight:10,tasksMax:128,env:{APP_ENV:"production",NODE_ENV:"production",TS_CLOUD_DASHBOARD_TELEMETRY:"1",...h?.password?{TS_CLOUD_DASHBOARD_DB_PASSWORD:h.password}:{}},zeroDowntime:!1,sharedPaths:[lf],healthCheck:{path:"/login"},ssl:{provider:"letsencrypt"}};return[{name:Rp(l),site:y}]}return ff(a,n,i.domain).map((l)=>({name:Rp(l),site:{root:i.uiRoot,deploy:"server",type:"static",domain:l,ssl:{provider:"letsencrypt"},...c,...s}}))}function Jy(a,n,i){return gi(a,n,i)[0]??null}function _t(a,n){let i={...a};for(let s in n){let c=n[s],l=i[s];if(c===void 0)continue;if(Array.isArray(c)&&Array.isArray(l))i[s]=[...l,...c];else if(typeof c==="object"&&c!==null&&!Array.isArray(c)&&typeof l==="object"&&l!==null&&!Array.isArray(l))i[s]=_t(l,c);else i[s]=c}return i}function Dp(a,n){return _t(a,n)}function Xy(...a){return a.reduce((n,i)=>_t(n,i),{})}function Yy(a,n){return(i)=>{let s=a(i);if(typeof n==="function")return Dp(s,n(s,i));return Dp(s,n)}}function kr(a){return{infrastructure:a}}function Zy(a){return kr({monitoring:a})}function eI(a){return kr({security:a})}function tI(a){return kr({databases:a})}function rI(a){return kr({cache:a})}function nI(a){return kr({cdn:a})}function iI(a){return kr({queues:a})}et();function Af(){let a=process.env.AWS_ACCESS_KEY_ID,n=process.env.AWS_SECRET_ACCESS_KEY;if(!a||!n)return null;return{accessKeyId:a,secretAccessKey:n,sessionToken:process.env.AWS_SESSION_TOKEN}}function yf(a){let n=a?.profile||process.env.AWS_PROFILE||"default",i=a?.credentialsFile||Na(Ra(),".aws","credentials");if(!Ia(i))return null;try{let s=Wt(i,"utf-8");return yn(s,n)}catch{return null}}function yn(a,n){let i=a.split(`
2494
2494
  `),s=null,c,l,u;for(let h of i){let y=h.trim();if(!y||y.startsWith("#")||y.startsWith(";"))continue;let f=y.match(/^\[([^\]]+)\]$/);if(f){if(s===n&&c&&l)return{accessKeyId:c,secretAccessKey:l,sessionToken:u};s=f[1],c=void 0,l=void 0,u=void 0;continue}if(s===n){let[S,...b]=y.split("="),C=b.join("=").trim();switch(S.trim().toLowerCase()){case"aws_access_key_id":c=C;break;case"aws_secret_access_key":l=C;break;case"aws_session_token":u=C;break}}}if(s===n&&c&&l)return{accessKeyId:c,secretAccessKey:l,sessionToken:u};return null}async function If(a){let n=a?.timeout??1000,i="http://169.254.169.254";try{let s=await Ye("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}},n);if(!s.ok)return null;let c=await s.text(),l=await Ye("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":c}},n);if(!l.ok)return null;let u=(await l.text()).trim(),h=await Ye(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${u}`,{headers:{"X-aws-ec2-metadata-token":c}},n);if(!h.ok)return null;let y=await h.json();return{accessKeyId:y.AccessKeyId,secretAccessKey:y.SecretAccessKey,sessionToken:y.Token,expiration:new Date(y.Expiration)}}catch{return null}}async function Sf(a){let n=a?.timeout??1000,i=process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,s=process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI,c=null;if(i)c=`http://169.254.170.2${i}`;else if(s)c=s;if(!c)return null;try{let l={},u=process.env.AWS_CONTAINER_AUTHORIZATION_TOKEN;if(u)l.Authorization=u;let h=await Ye(c,{headers:l},n);if(!h.ok)return null;let y=await h.json();return{accessKeyId:y.AccessKeyId,secretAccessKey:y.SecretAccessKey,sessionToken:y.Token,expiration:new Date(y.Expiration)}}catch{return null}}async function Cf(a){let n=a?.timeout??5000,i=process.env.AWS_WEB_IDENTITY_TOKEN_FILE,s=process.env.AWS_ROLE_ARN,c=process.env.AWS_ROLE_SESSION_NAME||"ts-cloud-session";if(!i||!s)return null;try{let l=Wt(i,"utf-8").trim(),u=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"us-east-1",h=u.startsWith("us-gov")?`https://sts.${u}.amazonaws.com`:u==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${u}.amazonaws.com`,y=new URLSearchParams({Action:"AssumeRoleWithWebIdentity",Version:"2011-06-15",RoleArn:s,RoleSessionName:c,WebIdentityToken:l}),f=await Ye(`${h}/?${y.toString()}`,{method:"POST"},n);if(!f.ok)return null;let S=await f.text(),b=ze(S,"AccessKeyId"),C=ze(S,"SecretAccessKey"),T=ze(S,"SessionToken"),v=ze(S,"Expiration");if(!b||!C)return null;return{accessKeyId:b,secretAccessKey:C,sessionToken:T??void 0,expiration:v?new Date(v):void 0}}catch{return null}}async function js(a){let n=Af();if(n)return n;let i=yf(a);if(i)return i;let s=await Cf(a);if(s)return s;let c=await Sf(a);if(c)return c;let l=await If(a);if(l)return l;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 sI(a){let n=null,i=null;return async()=>{if(n){if(!n.expiration)return n;let s=300000;if(n.expiration.getTime()-Date.now()>s)return n}if(i)return i;return i=js(a).then((s)=>(n=s,i=null,s)).catch((s)=>{throw i=null,s}),i}}async function Ye(a,n,i){let s=new AbortController,c=setTimeout(()=>s.abort(),i);try{let l=await fetch(a,{...n,signal:s.signal});return clearTimeout(c),l}catch(l){throw clearTimeout(c),l}}function ze(a,n){let i=new RegExp(`<${n}>([^<]+)</${n}>`),s=a.match(i);return s?s[1]:null}async function bf(a){return js({profile:a})}function Ef(a){let n=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION;if(n)return n;let i=Na(Ra(),".aws","config");if(Ia(i))try{let s=Wt(i,"utf-8"),c=a||process.env.AWS_PROFILE||"default",l=c==="default"?"[default]":`[profile ${c}]`,u=s.split(`
2495
- `),h=!1;for(let y of u){let f=y.trim();if(f.startsWith("[")){h=f===l;continue}if(h&&f.startsWith("region")){let[,S]=f.split("=");if(S)return S.trim()}}}catch{}return"us-east-1"}async function vf(a){let n=a||await js(),i=Ef();await et();let s=i.startsWith("us-gov")?`https://sts.${i}.amazonaws.com`:i==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${i}.amazonaws.com`,c="Action=GetCallerIdentity&Version=2011-06-15",l=x({method:"POST",url:s,body:"Action=GetCallerIdentity&Version=2011-06-15",headers:{"Content-Type":"application/x-www-form-urlencoded"},...n,service:"sts",region:i}),u=await fetch(l.url,{method:l.method,headers:l.headers,body:l.body});if(!u.ok)throw Error(`Failed to get account ID: ${await u.text()}`);let h=await u.text(),y=ze(h,"Account");if(!y)throw Error("Failed to parse account ID from response");return y}await et();await et();var fn=5242880,Pt=5242880,Sn=5242880;class Da{region;endpoint;forcePathStyle;credentials;credentialOptions;retryOptions;constructor(a={}){this.region=a.region||process.env.AWS_REGION||"us-east-1",this.endpoint=a.endpoint||`https://s3.${this.region}.amazonaws.com`,this.forcePathStyle=a.forcePathStyle||!1,this.credentials=a.credentials,this.credentialOptions=a.credentialOptions,this.retryOptions=a.retryOptions||{}}async getCredentials(){if(this.credentials)return this.credentials;return js(this.credentialOptions)}buildUrl(a,n){let i=n?encodeURIComponent(n).replace(/%2F/g,"/"):"";if(this.forcePathStyle)return n?`${this.endpoint}/${a}/${i}`:`${this.endpoint}/${a}`;let s=new URL(this.endpoint);return s.hostname=`${a}.${s.hostname}`,n?`${s.origin}/${i}`:s.origin}async get(a,n,i={}){let s=await this.getCredentials(),c=this.buildUrl(a,n),l={};if(i.range)l.Range=i.range;if(i.ifModifiedSince)l["If-Modified-Since"]=i.ifModifiedSince.toUTCString();if(i.ifMatch)l["If-Match"]=i.ifMatch;if(i.ifNoneMatch)l["If-None-Match"]=i.ifNoneMatch;let u=new URL(c);if(i.responseContentType)u.searchParams.set("response-content-type",i.responseContentType);if(i.responseContentDisposition)u.searchParams.set("response-content-disposition",i.responseContentDisposition);let h=x({method:"GET",url:u.toString(),headers:l,...s,service:"s3",region:this.region}),y=await fetch(h.url,{method:h.method,headers:h.headers});if(!y.ok&&y.status!==304){let f=await y.text();throw new G(`Failed to get object: ${f}`,y.status,a,n)}return y}async getText(a,n,i={}){return(await this.get(a,n,i)).text()}async getJSON(a,n,i={}){return(await this.get(a,n,i)).json()}async getBuffer(a,n,i={}){return(await this.get(a,n,i)).arrayBuffer()}async put(a,n,i,s={}){let c,l;if(typeof i==="string")c=new TextEncoder().encode(i).length,l=i;else if(i instanceof ArrayBuffer)c=i.byteLength,l=i;else if(i instanceof Uint8Array)c=i.byteLength,l=i;else if(i instanceof Blob)c=i.size,l=i;else return this.uploadMultipart(a,n,i,{...s,partSize:Pt});if(c>Sn){let u=Cn(l).stream();return this.uploadMultipart(a,n,u,{...s,partSize:Pt})}return this.putSimple(a,n,l,c,s)}async putSimple(a,n,i,s,c){let l=await this.getCredentials(),u=this.buildUrl(a,n),h={"Content-Length":String(s),"Content-Type":c.contentType||la(n)};if(c.contentEncoding)h["Content-Encoding"]=c.contentEncoding;if(c.cacheControl)h["Cache-Control"]=c.cacheControl;if(c.contentDisposition)h["Content-Disposition"]=c.contentDisposition;if(c.storageClass)h["x-amz-storage-class"]=c.storageClass;if(c.serverSideEncryption)h["x-amz-server-side-encryption"]=c.serverSideEncryption;if(c.acl)h["x-amz-acl"]=c.acl;if(c.tagging)h["x-amz-tagging"]=c.tagging;if(c.metadata)for(let[b,C]of Object.entries(c.metadata))h[`x-amz-meta-${b.toLowerCase()}`]=C;let y;if(typeof i==="string")y=i;else if(i instanceof Blob)y=await i.text();else y=new TextDecoder().decode(i instanceof ArrayBuffer?new Uint8Array(i):i);let f=x({method:"PUT",url:u,headers:h,body:y,...l,service:"s3",region:this.region}),S=await fetch(f.url,{method:f.method,headers:f.headers,body:i});if(!S.ok){let b=await S.text();throw new G(`Failed to put object: ${b}`,S.status,a,n)}return{etag:(S.headers.get("ETag")||"").replace(/"/g,"")}}async delete(a,n){let i=await this.getCredentials(),s=this.buildUrl(a,n),c=x({method:"DELETE",url:s,...i,service:"s3",region:this.region}),l=await fetch(c.url,{method:c.method,headers:c.headers});if(!l.ok&&l.status!==204){let u=await l.text();throw new G(`Failed to delete object: ${u}`,l.status,a,n)}}async deleteMany(a,n){let i=await this.getCredentials(),s=`${this.buildUrl(a)}?delete`,c=`<?xml version="1.0" encoding="UTF-8"?><Delete><Quiet>false</Quiet>${n.map((T)=>`<Object><Key>${An(T)}</Key></Object>`).join("")}</Delete>`,l=x({method:"POST",url:s,headers:{"Content-Type":"application/xml"},body:c,...i,service:"s3",region:this.region}),u=await fetch(l.url,{method:l.method,headers:l.headers,body:c});if(!u.ok){let T=await u.text();throw new G(`Failed to delete objects: ${T}`,u.status,a)}let h=await u.text(),y=[],f=[],S=/<Deleted><Key>([^<]+)<\/Key>/g,b;while((b=S.exec(h))!==null)y.push(b[1]);let C=/<Error><Key>([^<]+)<\/Key><Code>([^<]+)<\/Code><Message>([^<]+)<\/Message>/g;while((b=C.exec(h))!==null)f.push({key:b[1],error:`${b[2]}: ${b[3]}`});return{deleted:y,errors:f}}async list(a,n={}){let i=await this.getCredentials(),s=new URL(this.buildUrl(a));if(s.searchParams.set("list-type","2"),n.prefix)s.searchParams.set("prefix",n.prefix);if(n.delimiter)s.searchParams.set("delimiter",n.delimiter);if(n.maxKeys)s.searchParams.set("max-keys",String(n.maxKeys));if(n.continuationToken)s.searchParams.set("continuation-token",n.continuationToken);if(n.startAfter)s.searchParams.set("start-after",n.startAfter);let c=x({method:"GET",url:s.toString(),...i,service:"s3",region:this.region}),l=await fetch(c.url,{method:c.method,headers:c.headers});if(!l.ok){let h=await l.text();throw new G(`Failed to list objects: ${h}`,l.status,a)}let u=await l.text();return bn(u)}async*listAll(a,n={}){let i;do{let s=await this.list(a,{...n,continuationToken:i});for(let c of s.contents)yield c;i=s.nextContinuationToken}while(i)}async head(a,n){let i=await this.getCredentials(),s=this.buildUrl(a,n),c=x({method:"HEAD",url:s,...i,service:"s3",region:this.region}),l=await fetch(c.url,{method:c.method,headers:c.headers});if(l.status===404)return null;if(!l.ok){let h=await l.text();throw new G(`Failed to head object: ${h}`,l.status,a,n)}let u={};return l.headers.forEach((h,y)=>{if(y.toLowerCase().startsWith("x-amz-meta-"))u[y.slice(11)]=h}),{contentLength:Number(l.headers.get("Content-Length")||0),contentType:l.headers.get("Content-Type")||"application/octet-stream",etag:(l.headers.get("ETag")||"").replace(/"/g,""),lastModified:new Date(l.headers.get("Last-Modified")||0),metadata:u,storageClass:l.headers.get("x-amz-storage-class")||void 0,serverSideEncryption:l.headers.get("x-amz-server-side-encryption")||void 0}}async exists(a,n){return await this.head(a,n)!==null}async copy(a,n,i,s,c={}){let l=await this.getCredentials(),u=this.buildUrl(i,s),h={"x-amz-copy-source":`/${a}/${encodeURIComponent(n)}`};if(c.metadataDirective)h["x-amz-metadata-directive"]=c.metadataDirective;if(c.contentType)h["Content-Type"]=c.contentType;if(c.storageClass)h["x-amz-storage-class"]=c.storageClass;if(c.acl)h["x-amz-acl"]=c.acl;if(c.metadata)for(let[b,C]of Object.entries(c.metadata))h[`x-amz-meta-${b.toLowerCase()}`]=C;let y=x({method:"PUT",url:u,headers:h,...l,service:"s3",region:this.region}),f=await fetch(y.url,{method:y.method,headers:y.headers});if(!f.ok){let b=await f.text();throw new G(`Failed to copy object: ${b}`,f.status,i,s)}let S=(await f.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:S?S[1]:""}}async getPresignedUrl(a,n,i={}){let s=await this.getCredentials(),c=this.buildUrl(a,n);return rf({url:c,method:i.method||"GET",expiresIn:i.expiresIn||3600,...s,service:"s3",region:this.region})}async uploadMultipart(a,n,i,s={}){let c=await this.getCredentials(),l=Math.max(s.partSize||Pt,fn),u,h;if(i instanceof ReadableStream)u=i;else if(i instanceof Blob)u=i.stream(),h=i.size;else{let S=new Blob([i]);u=S.stream(),h=S.size}let{uploadId:y,baseUrl:f}=await this.initiateMultipartUpload(a,n,s);try{let S=await this.uploadParts(a,n,f,y,u,l,c,h,s.concurrency||4,s.onProgress);return await this.completeMultipartUpload(a,n,f,y,S)}catch(S){throw await this.abortMultipartUpload(a,n,y,f).catch(()=>{}),S}}async initiateMultipartUpload(a,n,i){let s=await this.getCredentials(),c=this.buildUrl(a,n),l=`${c}?uploads`,u={"Content-Type":i.contentType||la(n)};if(i.storageClass)u["x-amz-storage-class"]=i.storageClass;if(i.serverSideEncryption)u["x-amz-server-side-encryption"]=i.serverSideEncryption;if(i.acl)u["x-amz-acl"]=i.acl;if(i.metadata)for(let[b,C]of Object.entries(i.metadata))u[`x-amz-meta-${b.toLowerCase()}`]=C;let h=x({method:"POST",url:l,headers:u,...s,service:"s3",region:this.region}),y=await fetch(h.url,{method:h.method,headers:h.headers});if(!y.ok){let b=await y.text();throw new G(`Failed to initiate multipart upload: ${b}`,y.status,a,n)}let f=(await y.text()).match(/<UploadId>([^<]+)<\/UploadId>/);if(!f)throw new G("Failed to parse upload ID from response",0,a,n);let S=c;if(y.url)try{let b=new URL(y.url);b.search="",S=b.toString()}catch{}return{uploadId:f[1],baseUrl:S}}async uploadParts(a,n,i,s,c,l,u,h,y,f){let S=[],b=c.getReader(),C=1,T=new Uint8Array(0),v=0,w=h?Math.ceil(h/l):void 0,R=new Map,k=async(P,V)=>{let B=`${i}?partNumber=${V}&uploadId=${encodeURIComponent(s)}`,j={"Content-Length":String(P.byteLength),"x-amz-content-sha256":"UNSIGNED-PAYLOAD"},J=x({method:"PUT",url:B,headers:j,...u,service:"s3",region:this.region}),K=await fetch(J.url,{method:J.method,headers:J.headers,body:P,redirect:"error"});if(!K.ok){let te=await K.text();throw new G(`Failed to upload part ${V}: ${te}`,K.status,a,n)}let ee=(K.headers.get("ETag")||"").replace(/"/g,"");if(!ee)throw new G(`Missing ETag for part ${V}`,K.status,a,n);return{partNumber:V,etag:ee}},W=async()=>{let P=await Promise.race(R.values());R.delete(P.partNumber),S.push(P)};while(!0){let{done:P,value:V}=await b.read();if(V){let B=new Uint8Array(T.length+V.length);B.set(T),B.set(V,T.length),T=B}while(T.length>=l||P&&T.length>0){let B=T.slice(0,l);T=T.slice(l);let j=C++;if(R.size>=y)await W();if(R.set(j,k(B,j)),v+=B.byteLength,f)f({loaded:v,total:h||v,part:j,totalParts:w||j})}if(P)break}while(R.size>0)await W();return S.sort((P,V)=>P.partNumber-V.partNumber),S}async completeMultipartUpload(a,n,i,s,c){let l=await this.getCredentials(),u=`${i}?uploadId=${encodeURIComponent(s)}`,h=`<?xml version="1.0" encoding="UTF-8"?><CompleteMultipartUpload>${c.map((b)=>`<Part><PartNumber>${b.partNumber}</PartNumber><ETag>"${b.etag}"</ETag></Part>`).join("")}</CompleteMultipartUpload>`,y=x({method:"POST",url:u,headers:{"Content-Type":"application/xml"},body:h,...l,service:"s3",region:this.region}),f=await fetch(y.url,{method:y.method,headers:y.headers,body:h});if(!f.ok){let b=await f.text();throw new G(`Failed to complete multipart upload: ${b}`,f.status,a,n)}let S=(await f.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:S?S[1]:""}}async abortMultipartUpload(a,n,i,s){let c=await this.getCredentials(),l=`${s??this.buildUrl(a,n)}?uploadId=${encodeURIComponent(i)}`,u=x({method:"DELETE",url:l,...c,service:"s3",region:this.region});await fetch(u.url,{method:u.method,headers:u.headers})}async emptyAndDeleteBucket(a){let n=[];for await(let l of this.listAll(a,{}))if(n.push(l.key),n.length>=1000)await this.deleteMany(a,n),n=[];if(n.length>0)await this.deleteMany(a,n);let i=await this.getCredentials(),s=this.buildUrl(a),c=x({method:"DELETE",url:s,...i,service:"s3",region:this.region});await fetch(c.url,{method:c.method,headers:c.headers})}}class G extends Error{statusCode;bucket;key;constructor(a,n,i,s){super(a);this.statusCode=n,this.bucket=i,this.key=s,this.name="S3Error"}}function bn(a){let n=[],i=[],s=/<Contents>([\s\S]*?)<\/Contents>/g,c;while((c=s.exec(a))!==null){let u=c[1];n.push({key:le(u,"Key")||"",lastModified:new Date(le(u,"LastModified")||0),etag:(le(u,"ETag")||"").replace(/"/g,""),size:Number(le(u,"Size")||0),storageClass:le(u,"StorageClass")||"STANDARD"})}let l=/<CommonPrefixes><Prefix>([^<]+)<\/Prefix><\/CommonPrefixes>/g;while((c=l.exec(a))!==null)i.push(c[1]);return{contents:n,commonPrefixes:i,isTruncated:le(a,"IsTruncated")==="true",continuationToken:le(a,"ContinuationToken")||void 0,nextContinuationToken:le(a,"NextContinuationToken")||void 0,keyCount:Number(le(a,"KeyCount")||0),maxKeys:Number(le(a,"MaxKeys")||1000),prefix:le(a,"Prefix")||void 0,delimiter:le(a,"Delimiter")||void 0}}function le(a,n){let i=new RegExp(`<${n}>([^<]*)</${n}>`),s=a.match(i);return s?s[1]:null}function An(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function la(a){let n=a.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"}[n||""]||"application/octet-stream"}function Cn(a){if(a instanceof Blob)return a;if(typeof a==="string")return new Blob([a],{type:"text/plain"});return new Blob([a])}function oI(a){return new Da(a)}await et();class He extends Error{code;solution;details;constructor(a,n,i,s){super(a);this.code=n,this.solution=i,this.details=s,this.name="CloudError",Error.captureStackTrace?.(this,He)}toString(){let a=`${this.name} [${this.code}]: ${this.message}`;if(this.solution)a+=`
2495
+ `),h=!1;for(let y of u){let f=y.trim();if(f.startsWith("[")){h=f===l;continue}if(h&&f.startsWith("region")){let[,S]=f.split("=");if(S)return S.trim()}}}catch{}return"us-east-1"}async function vf(a){let n=a||await js(),i=Ef();await et();let s=i.startsWith("us-gov")?`https://sts.${i}.amazonaws.com`:i==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${i}.amazonaws.com`,c="Action=GetCallerIdentity&Version=2011-06-15",l=x({method:"POST",url:s,body:"Action=GetCallerIdentity&Version=2011-06-15",headers:{"Content-Type":"application/x-www-form-urlencoded"},...n,service:"sts",region:i}),u=await fetch(l.url,{method:l.method,headers:l.headers,body:l.body});if(!u.ok)throw Error(`Failed to get account ID: ${await u.text()}`);let h=await u.text(),y=ze(h,"Account");if(!y)throw Error("Failed to parse account ID from response");return y}await et();await et();var fn=5242880,Pt=5242880,Sn=5242880;class Da{region;endpoint;forcePathStyle;credentials;credentialOptions;retryOptions;constructor(a={}){this.region=a.region||process.env.AWS_REGION||"us-east-1",this.endpoint=a.endpoint||`https://s3.${this.region}.amazonaws.com`,this.forcePathStyle=a.forcePathStyle||!1,this.credentials=a.credentials,this.credentialOptions=a.credentialOptions,this.retryOptions=a.retryOptions||{}}async getCredentials(){if(this.credentials)return this.credentials;return js(this.credentialOptions)}buildUrl(a,n){let i=n?encodeURIComponent(n).replace(/%2F/g,"/"):"";if(this.forcePathStyle)return n?`${this.endpoint}/${a}/${i}`:`${this.endpoint}/${a}`;let s=new URL(this.endpoint);return s.hostname=`${a}.${s.hostname}`,n?`${s.origin}/${i}`:s.origin}async get(a,n,i={}){let s=await this.getCredentials(),c=this.buildUrl(a,n),l={};if(i.range)l.Range=i.range;if(i.ifModifiedSince)l["If-Modified-Since"]=i.ifModifiedSince.toUTCString();if(i.ifMatch)l["If-Match"]=i.ifMatch;if(i.ifNoneMatch)l["If-None-Match"]=i.ifNoneMatch;let u=new URL(c);if(i.responseContentType)u.searchParams.set("response-content-type",i.responseContentType);if(i.responseContentDisposition)u.searchParams.set("response-content-disposition",i.responseContentDisposition);let h=x({method:"GET",url:u.toString(),headers:l,...s,service:"s3",region:this.region}),y=await fetch(h.url,{method:h.method,headers:h.headers});if(!y.ok&&y.status!==304){let f=await y.text();throw new G(`Failed to get object: ${f}`,y.status,a,n)}return y}async getText(a,n,i={}){return(await this.get(a,n,i)).text()}async getJSON(a,n,i={}){return(await this.get(a,n,i)).json()}async getBuffer(a,n,i={}){return(await this.get(a,n,i)).arrayBuffer()}async put(a,n,i,s={}){let c,l;if(typeof i==="string")c=new TextEncoder().encode(i).length,l=i;else if(i instanceof ArrayBuffer)c=i.byteLength,l=i;else if(i instanceof Uint8Array)c=i.byteLength,l=i;else if(i instanceof Blob)c=i.size,l=i;else return this.uploadMultipart(a,n,i,{...s,partSize:Pt});if(c>Sn){let u=Cn(l).stream();return this.uploadMultipart(a,n,u,{...s,partSize:Pt})}return this.putSimple(a,n,l,c,s)}async putSimple(a,n,i,s,c){let l=await this.getCredentials(),u=this.buildUrl(a,n),h={"Content-Length":String(s),"Content-Type":c.contentType||la(n)};if(c.contentEncoding)h["Content-Encoding"]=c.contentEncoding;if(c.cacheControl)h["Cache-Control"]=c.cacheControl;if(c.contentDisposition)h["Content-Disposition"]=c.contentDisposition;if(c.storageClass)h["x-amz-storage-class"]=c.storageClass;if(c.serverSideEncryption)h["x-amz-server-side-encryption"]=c.serverSideEncryption;if(c.acl)h["x-amz-acl"]=c.acl;if(c.tagging)h["x-amz-tagging"]=c.tagging;if(c.metadata)for(let[b,C]of Object.entries(c.metadata))h[`x-amz-meta-${b.toLowerCase()}`]=C;let y;if(typeof i==="string")y=i;else if(i instanceof Blob)y=await i.text();else y=new TextDecoder().decode(i instanceof ArrayBuffer?new Uint8Array(i):i);let f=x({method:"PUT",url:u,headers:h,body:y,...l,service:"s3",region:this.region}),S=await fetch(f.url,{method:f.method,headers:f.headers,body:i});if(!S.ok){let b=await S.text();throw new G(`Failed to put object: ${b}`,S.status,a,n)}return{etag:(S.headers.get("ETag")||"").replace(/"/g,"")}}async delete(a,n){let i=await this.getCredentials(),s=this.buildUrl(a,n),c=x({method:"DELETE",url:s,...i,service:"s3",region:this.region}),l=await fetch(c.url,{method:c.method,headers:c.headers});if(!l.ok&&l.status!==204){let u=await l.text();throw new G(`Failed to delete object: ${u}`,l.status,a,n)}}async deleteMany(a,n){let i=await this.getCredentials(),s=`${this.buildUrl(a)}?delete`,c=`<?xml version="1.0" encoding="UTF-8"?><Delete><Quiet>false</Quiet>${n.map((T)=>`<Object><Key>${An(T)}</Key></Object>`).join("")}</Delete>`,l=x({method:"POST",url:s,headers:{"Content-Type":"application/xml"},body:c,...i,service:"s3",region:this.region}),u=await fetch(l.url,{method:l.method,headers:l.headers,body:c});if(!u.ok){let T=await u.text();throw new G(`Failed to delete objects: ${T}`,u.status,a)}let h=await u.text(),y=[],f=[],S=/<Deleted><Key>([^<]+)<\/Key>/g,b;while((b=S.exec(h))!==null)y.push(b[1]);let C=/<Error><Key>([^<]+)<\/Key><Code>([^<]+)<\/Code><Message>([^<]+)<\/Message>/g;while((b=C.exec(h))!==null)f.push({key:b[1],error:`${b[2]}: ${b[3]}`});return{deleted:y,errors:f}}async list(a,n={}){let i=await this.getCredentials(),s=new URL(this.buildUrl(a));if(s.searchParams.set("list-type","2"),n.prefix)s.searchParams.set("prefix",n.prefix);if(n.delimiter)s.searchParams.set("delimiter",n.delimiter);if(n.maxKeys)s.searchParams.set("max-keys",String(n.maxKeys));if(n.continuationToken)s.searchParams.set("continuation-token",n.continuationToken);if(n.startAfter)s.searchParams.set("start-after",n.startAfter);let c=x({method:"GET",url:s.toString(),...i,service:"s3",region:this.region}),l=await fetch(c.url,{method:c.method,headers:c.headers});if(!l.ok){let h=await l.text();throw new G(`Failed to list objects: ${h}`,l.status,a)}let u=await l.text();return bn(u)}async*listAll(a,n={}){let i;do{let s=await this.list(a,{...n,continuationToken:i});for(let c of s.contents)yield c;i=s.nextContinuationToken}while(i)}async head(a,n){let i=await this.getCredentials(),s=this.buildUrl(a,n),c=x({method:"HEAD",url:s,...i,service:"s3",region:this.region}),l=await fetch(c.url,{method:c.method,headers:c.headers});if(l.status===404)return null;if(!l.ok){let h=await l.text();throw new G(`Failed to head object: ${h}`,l.status,a,n)}let u={};return l.headers.forEach((h,y)=>{if(y.toLowerCase().startsWith("x-amz-meta-"))u[y.slice(11)]=h}),{contentLength:Number(l.headers.get("Content-Length")||0),contentType:l.headers.get("Content-Type")||"application/octet-stream",etag:(l.headers.get("ETag")||"").replace(/"/g,""),lastModified:new Date(l.headers.get("Last-Modified")||0),metadata:u,storageClass:l.headers.get("x-amz-storage-class")||void 0,serverSideEncryption:l.headers.get("x-amz-server-side-encryption")||void 0}}async exists(a,n){return await this.head(a,n)!==null}async copy(a,n,i,s,c={}){let l=await this.getCredentials(),u=this.buildUrl(i,s),h={"x-amz-copy-source":`/${a}/${encodeURIComponent(n)}`};if(c.metadataDirective)h["x-amz-metadata-directive"]=c.metadataDirective;if(c.contentType)h["Content-Type"]=c.contentType;if(c.storageClass)h["x-amz-storage-class"]=c.storageClass;if(c.acl)h["x-amz-acl"]=c.acl;if(c.metadata)for(let[b,C]of Object.entries(c.metadata))h[`x-amz-meta-${b.toLowerCase()}`]=C;let y=x({method:"PUT",url:u,headers:h,...l,service:"s3",region:this.region}),f=await fetch(y.url,{method:y.method,headers:y.headers});if(!f.ok){let b=await f.text();throw new G(`Failed to copy object: ${b}`,f.status,i,s)}let S=(await f.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:S?S[1]:""}}async getPresignedUrl(a,n,i={}){let s=await this.getCredentials(),c=this.buildUrl(a,n);return rf({url:c,method:i.method||"GET",expiresIn:i.expiresIn||3600,...s,service:"s3",region:this.region})}async uploadMultipart(a,n,i,s={}){let c=await this.getCredentials(),l=Math.max(s.partSize||Pt,fn),u,h;if(i instanceof ReadableStream)u=i;else if(i instanceof Blob)u=i.stream(),h=i.size;else{let S=new Blob([i]);u=S.stream(),h=S.size}let{uploadId:y,baseUrl:f}=await this.initiateMultipartUpload(a,n,s);try{let S=await this.uploadParts(a,n,f,y,u,l,c,h,s.concurrency||4,s.onProgress);return await this.completeMultipartUpload(a,n,f,y,S)}catch(S){throw await this.abortMultipartUpload(a,n,y,f).catch(()=>{}),S}}async initiateMultipartUpload(a,n,i){let s=await this.getCredentials(),c=this.buildUrl(a,n),l=`${c}?uploads`,u={"Content-Type":i.contentType||la(n)};if(i.storageClass)u["x-amz-storage-class"]=i.storageClass;if(i.serverSideEncryption)u["x-amz-server-side-encryption"]=i.serverSideEncryption;if(i.acl)u["x-amz-acl"]=i.acl;if(i.metadata)for(let[b,C]of Object.entries(i.metadata))u[`x-amz-meta-${b.toLowerCase()}`]=C;let h=x({method:"POST",url:l,headers:u,...s,service:"s3",region:this.region}),y=await fetch(h.url,{method:h.method,headers:h.headers});if(!y.ok){let b=await y.text();throw new G(`Failed to initiate multipart upload: ${b}`,y.status,a,n)}let f=(await y.text()).match(/<UploadId>([^<]+)<\/UploadId>/);if(!f)throw new G("Failed to parse upload ID from response",0,a,n);let S=c;if(y.url)try{let b=new URL(y.url);b.search="",S=b.toString()}catch{}return{uploadId:f[1],baseUrl:S}}async uploadParts(a,n,i,s,c,l,u,h,y,f){let S=[],b=c.getReader(),C=1,T=new Uint8Array(0),v=0,w=h?Math.ceil(h/l):void 0,R=new Map,k=async(P,V)=>{let B=`${i}?partNumber=${V}&uploadId=${encodeURIComponent(s)}`,j={"Content-Length":String(P.byteLength),"x-amz-content-sha256":"UNSIGNED-PAYLOAD"},J=x({method:"PUT",url:B,headers:j,...u,service:"s3",region:this.region}),K=await fetch(J.url,{method:J.method,headers:J.headers,body:P,redirect:"error"});if(!K.ok){let te=await K.text();throw new G(`Failed to upload part ${V}: ${te}`,K.status,a,n)}let ee=(K.headers.get("ETag")||"").replace(/"/g,"");if(!ee)throw new G(`Missing ETag for part ${V}`,K.status,a,n);return{partNumber:V,etag:ee}},W=async()=>{let P=await Promise.race(R.values());R.delete(P.partNumber),S.push(P)};while(!0){let{done:P,value:V}=await b.read();if(V){let B=new Uint8Array(T.length+V.length);B.set(T),B.set(V,T.length),T=B}while(T.length>=l||P&&T.length>0){let B=T.slice(0,l);T=T.slice(l);let j=C++;if(R.size>=y)await W();if(R.set(j,k(B,j)),v+=B.byteLength,f)f({loaded:v,total:h||v,part:j,totalParts:w||j})}if(P)break}while(R.size>0)await W();return S.sort((P,V)=>P.partNumber-V.partNumber),S}async completeMultipartUpload(a,n,i,s,c){let l=await this.getCredentials(),u=`${i}?uploadId=${encodeURIComponent(s)}`,h=`<?xml version="1.0" encoding="UTF-8"?><CompleteMultipartUpload>${c.map((b)=>`<Part><PartNumber>${b.partNumber}</PartNumber><ETag>"${b.etag}"</ETag></Part>`).join("")}</CompleteMultipartUpload>`,y=x({method:"POST",url:u,headers:{"Content-Type":"application/xml"},body:h,...l,service:"s3",region:this.region}),f=await fetch(y.url,{method:y.method,headers:y.headers,body:h});if(!f.ok){let b=await f.text();throw new G(`Failed to complete multipart upload: ${b}`,f.status,a,n)}let S=(await f.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:S?S[1]:""}}async abortMultipartUpload(a,n,i,s){let c=await this.getCredentials(),l=`${s??this.buildUrl(a,n)}?uploadId=${encodeURIComponent(i)}`,u=x({method:"DELETE",url:l,...c,service:"s3",region:this.region});await fetch(u.url,{method:u.method,headers:u.headers})}async emptyAndDeleteBucket(a){let n=[];for await(let l of this.listAll(a,{}))if(n.push(l.key),n.length>=1000)await this.deleteMany(a,n),n=[];if(n.length>0)await this.deleteMany(a,n);let i=await this.getCredentials(),s=this.buildUrl(a),c=x({method:"DELETE",url:s,...i,service:"s3",region:this.region});await fetch(c.url,{method:c.method,headers:c.headers})}}class G extends Error{statusCode;bucket;key;constructor(a,n,i,s){super(a);this.statusCode=n,this.bucket=i,this.key=s,this.name="S3Error"}}function bn(a){let n=[],i=[],s=/<Contents>([\s\S]*?)<\/Contents>/g,c;while((c=s.exec(a))!==null){let u=c[1];n.push({key:le(u,"Key")||"",lastModified:new Date(le(u,"LastModified")||0),etag:(le(u,"ETag")||"").replace(/"/g,""),size:Number(le(u,"Size")||0),storageClass:le(u,"StorageClass")||"STANDARD"})}let l=/<CommonPrefixes><Prefix>([^<]+)<\/Prefix><\/CommonPrefixes>/g;while((c=l.exec(a))!==null)i.push(c[1]);return{contents:n,commonPrefixes:i,isTruncated:le(a,"IsTruncated")==="true",continuationToken:le(a,"ContinuationToken")||void 0,nextContinuationToken:le(a,"NextContinuationToken")||void 0,keyCount:Number(le(a,"KeyCount")||0),maxKeys:Number(le(a,"MaxKeys")||1000),prefix:le(a,"Prefix")||void 0,delimiter:le(a,"Delimiter")||void 0}}function le(a,n){let i=new RegExp(`<${n}>([^<]*)</${n}>`),s=a.match(i);return s?s[1]:null}function An(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function la(a){let n=a.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"}[n||""]||"application/octet-stream"}function Cn(a){if(a instanceof Blob)return a;if(typeof a==="string")return new Blob([a],{type:"text/plain"});return new Blob([a])}function oI(a){return new Da(a)}await et();class Ge extends Error{code;solution;details;constructor(a,n,i,s){super(a);this.code=n,this.solution=i,this.details=s,this.name="CloudError",Error.captureStackTrace?.(this,Ge)}toString(){let a=`${this.name} [${this.code}]: ${this.message}`;if(this.solution)a+=`
2496
2496
 
2497
2497
  \uD83D\uDCA1 Solution: ${this.solution}`;if(this.details&&Object.keys(this.details).length>0){a+=`
2498
2498
 
2499
2499
  Details:`;for(let[n,i]of Object.entries(this.details))a+=`
2500
- ${n}: ${JSON.stringify(i)}`}return a}}class zs extends He{constructor(a,n,i){super(a,"CONFIG_ERROR",n,i);this.name="ConfigurationError"}}class Ht extends He{constructor(a,n,i){super(a,"CREDENTIAL_ERROR",n,i);this.name="CredentialError"}}class Tf extends He{constructor(a,n,i){super(a,"DEPLOYMENT_ERROR",n,i);this.name="DeploymentError"}}class Pp extends He{constructor(a,n,i){super(a,"VALIDATION_ERROR",n,i);this.name="ValidationError"}}class wf extends He{statusCode;constructor(a,n,i,s){super(a,"AWS_API_ERROR",i,s);this.statusCode=n,this.name="AWSAPIError"}}var Rf={NO_CREDENTIALS:{message:"AWS credentials not found",solution:`Configure AWS credentials using one of these methods:
2500
+ ${n}: ${JSON.stringify(i)}`}return a}}class zs extends Ge{constructor(a,n,i){super(a,"CONFIG_ERROR",n,i);this.name="ConfigurationError"}}class Ht extends Ge{constructor(a,n,i){super(a,"CREDENTIAL_ERROR",n,i);this.name="CredentialError"}}class Tf extends Ge{constructor(a,n,i){super(a,"DEPLOYMENT_ERROR",n,i);this.name="DeploymentError"}}class Pp extends Ge{constructor(a,n,i){super(a,"VALIDATION_ERROR",n,i);this.name="ValidationError"}}class wf extends Ge{statusCode;constructor(a,n,i,s){super(a,"AWS_API_ERROR",i,s);this.statusCode=n,this.name="AWSAPIError"}}var Rf={NO_CREDENTIALS:{message:"AWS credentials not found",solution:`Configure AWS credentials using one of these methods:
2501
2501
  1. Set environment variables: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
2502
2502
  2. Create ~/.aws/credentials file with your credentials
2503
2503
  3. Use an IAM role (for EC2 instances)
2504
- 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 Df(a){return Rf[a]}function Np(a,n){let i=Df(a);return new He(i.message,a,i.solution,n)}class Z{static verboseMode=!1;static debugMode=!1;static setVerbose(a){this.verboseMode=a}static setDebug(a){this.debugMode=a}static verbose(a,...n){if(this.verboseMode)console.log(`[VERBOSE] ${a}`,...n)}static debug(a,...n){if(this.debugMode)console.log(`[DEBUG] ${a}`,...n)}static info(a,...n){console.log(`ℹ ${a}`,...n)}static warn(a,...n){console.warn(`⚠ ${a}`,...n)}static error(a,n){if(console.error(`✖ ${a}`),n){if(n instanceof He)console.error(n.toString());else console.error(n.message);if(this.debugMode&&n.stack)console.error(`
2504
+ 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 Df(a){return Rf[a]}function Np(a,n){let i=Df(a);return new Ge(i.message,a,i.solution,n)}class Z{static verboseMode=!1;static debugMode=!1;static setVerbose(a){this.verboseMode=a}static setDebug(a){this.debugMode=a}static verbose(a,...n){if(this.verboseMode)console.log(`[VERBOSE] ${a}`,...n)}static debug(a,...n){if(this.debugMode)console.log(`[DEBUG] ${a}`,...n)}static info(a,...n){console.log(`ℹ ${a}`,...n)}static warn(a,...n){console.warn(`⚠ ${a}`,...n)}static error(a,n){if(console.error(`✖ ${a}`),n){if(n instanceof Ge)console.error(n.toString());else console.error(n.message);if(this.debugMode&&n.stack)console.error(`
2505
2505
  Stack trace:`),console.error(n.stack)}}static success(a){console.log(`✔ ${a}`)}}function aI(a){if(!a)throw Np("MISSING_CONFIG");if(!a.project)throw new zs("Missing required field: project","Add a project configuration with name, slug, and region",{field:"project"});if(!a.project.name)throw new zs("Missing required field: project.name","Add a project name to your configuration",{field:"project.name"});if(!a.project.slug)throw new zs("Missing required field: project.slug","Add a project slug (lowercase, alphanumeric with hyphens)",{field:"project.slug"});if(!/^[a-z0-9-]+$/.test(a.project.slug))throw new Pp("Invalid project slug format","Use only lowercase letters, numbers, and hyphens",{slug:a.project.slug});if(a.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(a.project.region))throw Np("INVALID_REGION",{region:a.project.region})}Z.success("Configuration validation passed")}function cI(a){let n=[];if(a.environments?.production&&a.infrastructure?.database){let i=a.infrastructure.database;if((i.postgres||i.mysql)&&!i.postgres?.multiAZ&&!i.mysql?.multiAZ)n.push("Production database should use Multi-AZ for high availability")}if(a.infrastructure?.storage){for(let[i,s]of Object.entries(a.infrastructure.storage))if(s.encryption===!1)n.push(`Storage "${i}" is not encrypted - consider enabling encryption for security`)}if(a.infrastructure?.storage){for(let[i,s]of Object.entries(a.infrastructure.storage))if(s.public===!0)n.push(`Storage "${i}" is publicly accessible - ensure this is intentional`)}if(a.infrastructure?.database){let i=a.infrastructure.database;if(i.postgres||i.mysql){let s=i.postgres?.backupRetentionDays||i.mysql?.backupRetentionDays;if(!s||s<7)n.push("Database backup retention is less than 7 days - consider increasing for production")}}if(!a.infrastructure?.monitoring)n.push("No monitoring configured - consider adding CloudWatch alarms");return n}async function dI(a="default"){try{Z.verbose("Resolving AWS credentials...");let n=await bf(a);if(!n.accessKeyId||!n.secretAccessKey)throw new Ht("AWS credentials are incomplete","Ensure both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set");Z.verbose("Credentials resolved successfully"),Z.debug("Access Key ID:",n.accessKeyId.substring(0,8)+"..."),Z.verbose("Testing credentials with GetCallerIdentity...");let i;try{i=await vf(n),Z.verbose("Credentials are valid"),Z.debug("Account ID:",i)}catch(s){if(s instanceof Error)if(s.message.includes("InvalidClientTokenId"))throw new Ht("Invalid AWS access key ID","Check that your AWS_ACCESS_KEY_ID is correct");else if(s.message.includes("SignatureDoesNotMatch"))throw new Ht("Invalid AWS secret access key","Check that your AWS_SECRET_ACCESS_KEY is correct");else if(s.message.includes("ExpiredToken"))throw new Ht("AWS credentials have expired","Refresh your temporary credentials or use long-term credentials");else throw new Ht(`Failed to validate credentials: ${s.message}`,"Verify your AWS credentials are correct and have the necessary permissions");throw s}return{valid:!0,accountId:i,region:n.region}}catch(n){if(n instanceof Ht)throw n;return{valid:!1,error:n instanceof Error?n.message:"Unknown error"}}}async function lI(a,n){return{allowed:n,denied:[]}}function Pf(a){let n=new Set(["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:GetTemplate","cloudformation:ListStacks"]);if(a.infrastructure){if(a.infrastructure.storage)n.add("s3:CreateBucket"),n.add("s3:DeleteBucket"),n.add("s3:PutBucketPolicy"),n.add("s3:PutBucketVersioning"),n.add("s3:PutBucketEncryption"),n.add("s3:PutObject"),n.add("s3:GetObject");if(a.infrastructure.compute){if(a.infrastructure.compute.server)n.add("ec2:RunInstances"),n.add("ec2:TerminateInstances"),n.add("ec2:DescribeInstances"),n.add("autoscaling:CreateAutoScalingGroup"),n.add("autoscaling:UpdateAutoScalingGroup"),n.add("autoscaling:DeleteAutoScalingGroup"),n.add("elasticloadbalancing:CreateLoadBalancer"),n.add("elasticloadbalancing:DeleteLoadBalancer");if(a.infrastructure.compute.fargate)n.add("ecs:CreateCluster"),n.add("ecs:DeleteCluster"),n.add("ecs:CreateService"),n.add("ecs:UpdateService"),n.add("ecs:DeleteService"),n.add("ecs:RegisterTaskDefinition")}if(a.infrastructure.database){if(a.infrastructure.database.postgres||a.infrastructure.database.mysql)n.add("rds:CreateDBInstance"),n.add("rds:DeleteDBInstance"),n.add("rds:ModifyDBInstance"),n.add("rds:DescribeDBInstances");if(a.infrastructure.database.dynamodb)n.add("dynamodb:CreateTable"),n.add("dynamodb:DeleteTable"),n.add("dynamodb:UpdateTable"),n.add("dynamodb:DescribeTable")}if(a.infrastructure.functions)n.add("lambda:CreateFunction"),n.add("lambda:DeleteFunction"),n.add("lambda:UpdateFunctionCode"),n.add("lambda:UpdateFunctionConfiguration"),n.add("lambda:AddPermission");if(a.infrastructure.cdn)n.add("cloudfront:CreateDistribution"),n.add("cloudfront:UpdateDistribution"),n.add("cloudfront:DeleteDistribution"),n.add("cloudfront:GetDistribution");if(a.infrastructure.network)n.add("ec2:CreateVpc"),n.add("ec2:DeleteVpc"),n.add("ec2:CreateSubnet"),n.add("ec2:DeleteSubnet"),n.add("ec2:CreateInternetGateway"),n.add("ec2:DeleteInternetGateway"),n.add("ec2:CreateNatGateway"),n.add("ec2:DeleteNatGateway"),n.add("ec2:CreateRouteTable"),n.add("ec2:DeleteRouteTable"),n.add("ec2:CreateSecurityGroup"),n.add("ec2:DeleteSecurityGroup")}return n.add("iam:CreateRole"),n.add("iam:DeleteRole"),n.add("iam:AttachRolePolicy"),n.add("iam:DetachRolePolicy"),n.add("iam:PutRolePolicy"),n.add("iam:GetRole"),n.add("iam:PassRole"),Array.from(n).sort()}function uI(a){let n=Pf(a);return JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Action:n,Resource:"*"}]},null,2)}var q={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 pI(a){let n=[];if(Z.verbose("Checking AWS service quotas..."),a.infrastructure?.compute?.server){let s=a.infrastructure.compute.server.autoScaling?.max||1;n.push({service:"EC2",quotaName:"Running On-Demand Instances",currentValue:s,limit:q.ec2["Running On-Demand Instances"],percentage:s/q.ec2["Running On-Demand Instances"]*100,warning:s>q.ec2["Running On-Demand Instances"]*0.8})}if(a.infrastructure?.network?.vpc)n.push({service:"EC2",quotaName:"VPCs",currentValue:1,limit:q.ec2.VPCs,percentage:1/q.ec2.VPCs*100,warning:!1});if(a.infrastructure?.database?.postgres||a.infrastructure?.database?.mysql)n.push({service:"RDS",quotaName:"DB Instances",currentValue:1,limit:q.rds["DB Instances"],percentage:1/q.rds["DB Instances"]*100,warning:!1});if(a.infrastructure?.storage){let s=Object.keys(a.infrastructure.storage).length;n.push({service:"S3",quotaName:"Buckets",currentValue:s,limit:q.s3.Buckets,percentage:s/q.s3.Buckets*100,warning:s>q.s3.Buckets*0.8})}if(a.infrastructure?.functions){let s=0;for(let c of Object.values(a.infrastructure.functions))if(Array.isArray(c))s+=c.length;n.push({service:"Lambda",quotaName:"Functions (estimated)",currentValue:s,limit:1000,percentage:s/1000*100,warning:s>800})}if(a.infrastructure?.database?.dynamodb){let s=a.infrastructure.database.dynamodb.tables?.length||0;n.push({service:"DynamoDB",quotaName:"Tables",currentValue:s,limit:q.dynamodb.Tables,percentage:s/q.dynamodb.Tables*100,warning:s>q.dynamodb.Tables*0.8})}let i=n.filter((s)=>s.warning);if(i.length>0){Z.warn("Service quota warnings detected:");for(let s of i)Z.warn(` ${s.service} - ${s.quotaName}: ${s.currentValue}/${s.limit} (${s.percentage.toFixed(1)}%)`)}else Z.verbose("All service quotas are within limits");return n}function gI(a){if(a.length===0)return"No quotas to check";let n=`Service Quota Usage:
2506
2506
 
2507
2507
  `,i=a.reduce((s,c)=>{if(!s[c.service])s[c.service]=[];return s[c.service].push(c),s},{});for(let[s,c]of Object.entries(i)){n+=`${s}:
@@ -7352,4 +7352,4 @@ php_admin_value[error_log] = /dev/stderr
7352
7352
  php_admin_flag[log_errors] = on
7353
7353
  clear_env = no
7354
7354
  `}function Ti(){return Ua(bi(Ci(import.meta.url)),"runtime-assets")}function Ai(){let a=Ti(),n=(i)=>Si(Ua(a,i),"utf-8");return[{path:"bootstrap",contents:n("bootstrap"),mode:493},{path:"tscloud/runtime.php",contents:n("runtime.php"),mode:420},{path:"tscloud/octane-runtime.php",contents:n("octane-runtime.php"),mode:420},{path:"tscloud/cli-runtime.php",contents:n("cli-runtime.php"),mode:420},{path:"tscloud/fastcgi-client.php",contents:n("fastcgi-client.php"),mode:420},{path:"tscloud/php-fpm.conf",contents:cA(),mode:420}]}function yd(a={}){let n=a.cacheDriver??"dynamodb";return{APP_ENV:"production",LOG_CHANNEL:"stderr",CACHE_STORE:n,CACHE_DRIVER:n,SESSION_DRIVER:n,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 dA=["composer install --no-dev --optimize-autoloader --no-interaction","php artisan config:cache","php artisan route:cache","php artisan event:cache","php artisan view:cache"];function*Va(a){for(let n of Pi(a)){let i=Me(a,n);if(Fa(i).isDirectory())yield*Va(i);else yield i}}function HC(a={}){let n=a.architecture??"x86_64",i=a.platform??(n==="arm64"?"linux/arm64":"linux/amd64"),s=a.onStep??(()=>{}),c=Ei(Me(Di(),"tscloud-php-layer-")),l="tscloud-php-layer:build";try{Ni(Me(c,"Dockerfile"),Yf(a)),s("Building PHP runtime image (docker)"),ot("docker",["build","--platform",i,"-t","tscloud-php-layer:build",c],{stdio:"inherit"}),s("Extracting /opt/php from image");let u=ot("docker",["create","--platform",i,"tscloud-php-layer:build"],{encoding:"utf-8"}).trim(),h=Me(c,"opt");wi(h,{recursive:!0});try{ot("docker",["cp",`${u}:/opt/php`,Me(h,"php")],{stdio:"inherit"})}finally{ot("docker",["rm",u],{stdio:"ignore"})}if(!vi(Me(h,"php","bin","php")))throw Error("layer build produced no /opt/php/bin/php");let y=[];for(let b of Va(h)){let C=ki(h,b).replace(/\\/g,"/"),T=Fa(b).mode&73?493:420;y.push({name:C,data:Ii(b),mode:T})}s("Injecting runtime assets");let f=new Set(Ai().map((b)=>b.path)),S=y.filter((b)=>!f.has(b.name));for(let b of Ai())S.push({name:b.path,data:b.contents,mode:b.mode});return s("Packaging layer ZIP"),{zip:hi(S),architecture:n,fileCount:S.length}}finally{Ri(c,{recursive:!0,force:!0})}}var lA=[".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 Bi(a,n){return n.some((i)=>a===i||a.startsWith(`${i}/`))}function*Ha(a,n,i){for(let s of Mi(a)){let c=Oi(a,s),l=Ka(n,c).replace(/\\/g,"/");if(Bi(l,i))continue;if(ja(c).isDirectory())yield*Ha(c,n,i);else yield c}}function to(a){if(a.skipBuild)return;let n=na(a.projectRoot??process.cwd()),i=a.app.build??dA;for(let s of i)a.onStep?.(`build: ${s}`),$i(s,{stdio:"inherit",cwd:n})}function ro(a,n=[]){let i=na(a),s=[...lA,Qs(),...n],c=[];for(let l of Ha(i,i,s)){let u=Ka(i,l).replace(/\\/g,"/"),h=(ja(l).mode&73)!==0;c.push({name:u,data:xi(l),mode:h?493:420})}return c}function Id(a){let n=na(a.projectRoot??process.cwd());to(a),a.onStep?.("packaging application tree");let i=ro(n,a.exclude);if(!i.length)throw Error(`No files to package under ${n}`);let s=hi(i),c=a.app.handlers?.http??"public/index.php";return{zip:s,sha256:Li("sha256").update(s).digest("hex"),handlers:{http:c,queue:a.app.handlers?.queue??c,cli:a.app.handlers?.cli??c},fileCount:i.length}}class Fg{optimizations=new Map;imageConfigs=new Map;ssgConfigs=new Map;prerenderConfigs=new Map;counter=0;createAssetOptimization(a){let n=`asset-opt-${Date.now()}-${this.counter++}`,i={id:n,...a};return this.optimizations.set(n,i),i}createImageOptimization(a){let n=`image-opt-${Date.now()}-${this.counter++}`,i={id:n,...a};return this.imageConfigs.set(n,i),i}createSSGConfig(a){let n=`ssg-${Date.now()}-${this.counter++}`,i={id:n,...a};return this.ssgConfigs.set(n,i),i}createPrerenderConfig(a){let n=`prerender-${Date.now()}-${this.counter++}`,i={id:n,...a};return this.prerenderConfigs.set(n,i),i}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 GC=new Fg;class Ug{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(a,n){let i=`lifecycle-${Date.now()}-${this.counter++}`,s={id:i,transitions:a,expiration:n};return this.policies.set(i,s),s}enableVersioning(a=!1){let n=`versioning-${Date.now()}-${this.counter++}`,i={id:n,enabled:!0,mfaDelete:a};return this.versioningConfigs.set(n,i),i}createReplicationRule(a,n,i){let s=`replication-${Date.now()}-${this.counter++}`,c={id:s,sourceRegion:a,destRegion:n,destBucket:i};return this.replicationRules.set(s,c),c}createIntelligentTiering(a,n){let i=`tiering-${Date.now()}-${this.counter++}`,s={id:i,archiveDays:a,deepArchiveDays:n};return this.tieringConfigs.set(i,s),s}enableObjectLock(a){let n=`object-lock-${Date.now()}-${this.counter++}`,i={id:n,bucketName:a.bucketName,mode:a.mode||"COMPLIANCE",retentionDays:a.retentionDays,retentionYears:a.retentionYears,legalHoldEnabled:a.legalHoldEnabled||!1};return this.objectLocks.set(n,i),i}enableTransferAcceleration(a){let n=`transfer-accel-${Date.now()}-${this.counter++}`,i={id:n,bucketName:a,enabled:!0,endpoint:`${a}.s3-accelerate.amazonaws.com`};return this.transferAcceleration.set(n,i),i}createAccessPoint(a){let n=`access-point-${Date.now()}-${this.counter++}`,i={id:n,name:a.name,bucketName:a.bucketName,vpcId:a.vpcId,publicAccessBlock:a.publicAccessBlock!==!1,policy:a.policy};return this.accessPoints.set(n,i),i}createGlacierArchive(a){let n=`glacier-${Date.now()}-${this.counter++}`,i={id:n,bucketName:a.bucketName,archiveType:a.archiveType,transitionDays:a.transitionDays,restoreConfig:a.restoreTier?{tier:a.restoreTier,days:a.restoreDays||7}:void 0};return this.glacierConfigs.set(n,i),i}createInventory(a){let n=`inventory-${Date.now()}-${this.counter++}`,i={id:n,sourceBucket:a.sourceBucket,destinationBucket:a.destinationBucket,schedule:a.schedule||"Daily",format:a.format||"CSV",includedFields:a.includedFields||["Size","LastModifiedDate","StorageClass","ETag"],prefix:a.prefix};return this.inventories.set(n,i),i}createBatchOperation(a){let n=`batch-op-${Date.now()}-${this.counter++}`,i={id:n,operation:a.operation,manifestBucket:a.manifestBucket,manifestKey:a.manifestKey,priority:a.priority||10,status:"pending"};return this.batchOps.set(n,i),i}executeBatchOperation(a){let n=this.batchOps.get(a);if(!n)throw Error(`Batch operation not found: ${a}`);return n.status="in_progress",n.totalObjects=1000,n.processedObjects=0,n}getBatchOperationStatus(a){return this.batchOps.get(a)}createLambdaNotification(a){let n=`event-${Date.now()}-${this.counter++}`,i={id:n,bucketName:a.bucketName,events:a.events,destination:{type:"Lambda",arn:a.lambdaArn},filter:a.prefix||a.suffix?{prefix:a.prefix,suffix:a.suffix}:void 0};return this.eventNotifications.set(n,i),i}createSQSNotification(a){let n=`event-${Date.now()}-${this.counter++}`,i={id:n,bucketName:a.bucketName,events:a.events,destination:{type:"SQS",arn:a.queueArn},filter:a.prefix||a.suffix?{prefix:a.prefix,suffix:a.suffix}:void 0};return this.eventNotifications.set(n,i),i}createSNSNotification(a){let n=`event-${Date.now()}-${this.counter++}`,i={id:n,bucketName:a.bucketName,events:a.events,destination:{type:"SNS",arn:a.topicArn},filter:a.prefix||a.suffix?{prefix:a.prefix,suffix:a.suffix}:void 0};return this.eventNotifications.set(n,i),i}generateObjectLockCF(a){let n={ObjectLockEnabled:"Enabled",ObjectLockConfiguration:{ObjectLockEnabled:"Enabled",Rule:{DefaultRetention:{Mode:a.mode}}}};if(a.retentionDays)n.ObjectLockConfiguration.Rule.DefaultRetention.Days=a.retentionDays;if(a.retentionYears)n.ObjectLockConfiguration.Rule.DefaultRetention.Years=a.retentionYears;return n}generateTransferAccelerationCF(a){return{AccelerateConfiguration:{AccelerationStatus:a.enabled?"Enabled":"Suspended"}}}generateAccessPointCF(a){return{Type:"AWS::S3::AccessPoint",Properties:{Name:a.name,Bucket:a.bucketName,...a.vpcId&&{VpcConfiguration:{VpcId:a.vpcId}},PublicAccessBlockConfiguration:a.publicAccessBlock?{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0}:void 0,...a.policy&&{Policy:a.policy}}}}generateInventoryCF(a){return{Type:"AWS::S3::Bucket",Properties:{InventoryConfigurations:[{Id:a.id,Destination:{BucketArn:`arn:aws:s3:::${a.destinationBucket}`,Format:a.format},Enabled:!0,IncludedObjectVersions:"Current",OptionalFields:a.includedFields,ScheduleFrequency:a.schedule,...a.prefix&&{Prefix:a.prefix}}]}}}generateEventNotificationCF(a){let n=a.destination.type==="Lambda"?"LambdaConfigurations":a.destination.type==="SQS"?"QueueConfigurations":"TopicConfigurations",i=a.destination.type==="Lambda"?"Function":a.destination.type==="SQS"?"Queue":"Topic",s={Event:a.events[0],[i]:a.destination.arn};if(a.filter)s.Filter={S3Key:{Rules:[...a.filter.prefix?[{Name:"prefix",Value:a.filter.prefix}]:[],...a.filter.suffix?[{Name:"suffix",Value:a.filter.suffix}]:[]]}};return{NotificationConfiguration:{[n]:[s]}}}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 qC=new Ug;class Qg{checks=new Map;synthetics=new Map;uptimeTrackers=new Map;counter=0;createHealthCheck(a,n=30,i=10){let s=`health-${Date.now()}-${this.counter++}`,c={id:s,url:a,interval:n,timeout:i,status:"healthy"};return this.checks.set(s,c),c}createSyntheticMonitor(a,n,i,s){let c=`synthetic-${Date.now()}-${this.counter++}`,l={id:c,name:a,script:n,frequency:i,locations:s};return this.synthetics.set(c,l),l}trackUptime(a,n,i){let s=`uptime-${Date.now()}-${this.counter++}`,c=n/(n+i)*100,l={id:s,resource:a,uptime:n,downtime:i,availability:c};return this.uptimeTrackers.set(s,l),l}clear(){this.checks.clear(),this.synthetics.clear(),this.uptimeTrackers.clear()}}var VC=new Qg;class Hg{wafRules=new Map;shieldProtections=new Map;securityGroups=new Map;nacls=new Map;counter=0;createWAFRule(a,n,i,s){let c=`waf-${Date.now()}-${this.counter++}`,l={id:c,name:a,priority:n,action:i,conditions:s};return this.wafRules.set(c,l),l}enableShield(a,n="standard"){let i=`shield-${Date.now()}-${this.counter++}`,s={id:i,resourceArn:a,protectionType:n};return this.shieldProtections.set(i,s),s}createSecurityGroup(a,n,i){let s=`sg-${Date.now()}-${this.counter++}`,c={id:s,name:a,vpcId:n,rules:i};return this.securityGroups.set(s,c),c}createNACL(a,n){let i=`nacl-${Date.now()}-${this.counter++}`,s={id:i,vpcId:a,rules:n};return this.nacls.set(i,s),s}clear(){this.wafRules.clear(),this.shieldProtections.clear(),this.securityGroups.clear(),this.nacls.clear()}}var jC=new Hg;class Gg{strategies=new Map;allocations=new Map;groups=new Map;counter=0;createTaggingStrategy(a,n){let i=`tagging-${Date.now()}-${this.counter++}`,s={id:i,tags:a,resources:n};return this.strategies.set(i,s),s}createCostAllocation(a,n){let i=`cost-${Date.now()}-${this.counter++}`,s={id:i,tagKey:a,allocations:n};return this.allocations.set(i,s),s}createResourceGroup(a,n,i){let s=`group-${Date.now()}-${this.counter++}`,c={id:s,name:a,query:{resourceTypeFilters:n,tagFilters:i}};return this.groups.set(s,c),c}clear(){this.strategies.clear(),this.allocations.clear(),this.groups.clear()}}var zC=new Gg;
7355
- export{Sp,x,Cp,rf,uy,nf,py,gy,my,hy,fy,Ay,yy,Iy,Sy,Cy,bp,Ep,Wc,Jc,Qs,_,d,Xc,vp,O,Yc,p,sf,ui,Zc,ed,ce,td,by,r,t,Ey,vy,g,Ty,wy,Ry,Dy,Py,Mt,rd,Hs,of,Ny,ky,Se,Fe,Ce,L,I,o,A,Ue,m,af,Qe,M,ct,By,cf,F,nd,be,Ft,Gs,X,id,Y,df,qs,U,Q,D,pi,E,Ut,dt,H,e,Vs,xy,Tp,sd,_y,Oy,Ly,$y,od,My,Fy,Uy,Qy,Hy,Gy,qy,Vy,jy,zy,Ky,Wy,lf,uf,pf,gf,mf,hf,ff,Qt,wp,Rp,Nr,gi,Jy,Dp,Xy,Yy,kr,Zy,eI,tI,rI,nI,iI,Af,yf,If,Sf,Cf,js,sI,bf,Ef,vf,G,oI,He,zs,Ht,Tf,Pp,wf,Rf,Df,Np,Z,aI,cI,dI,lI,Pf,uI,q,pI,gI,mI,kp,Bp,hI,xp,_p,fI,yI,II,SI,CI,Nf,ad,bI,EI,vI,TI,wI,kf,Bf,RI,DI,PI,NI,kI,BI,xI,_I,OI,Op,cd,LI,$I,MI,FI,Lp,$p,Mp,UI,Fp,QI,HI,GI,qI,Up,VI,jI,zI,KI,WI,JI,XI,YI,xf,_f,Of,Lf,Qp,ZI,eS,tS,rS,nS,iS,sS,oS,aS,$f,Mf,Ff,Uf,cS,dS,Hp,lS,Gp,qp,Vp,jp,uS,pS,gS,mS,Ee,mi,hS,fS,AS,yS,IS,SS,CS,bS,Qf,ES,vS,zp,Kp,TS,wS,Hf,RS,DS,PS,NS,kS,BS,xS,_S,OS,LS,$S,MS,FS,US,QS,HS,GS,qS,VS,jS,zS,Wp,KS,Jp,WS,Xp,JS,Yp,XS,Zp,YS,Br,ZS,eg,eC,Ks,tC,tg,rC,rg,nC,ng,iC,ig,sC,sg,oC,xr,aC,og,cC,ag,dC,cg,lC,dg,uC,lg,pC,ug,gC,pg,mC,gg,hC,mg,fC,hg,AC,fg,yC,Ag,IC,yg,SC,Ig,CC,Sg,bC,Cg,EC,bg,vC,Eg,TC,vg,wC,Tg,RC,wg,DC,Rg,PC,Dg,NC,Pg,kC,Ng,BC,Gf,qf,Vf,jf,kg,xC,Bg,_C,xg,OC,_g,LC,hi,zf,Kf,Ws,dd,_r,Wf,Js,Gt,ld,ud,Jf,Xf,Og,Yf,pd,Lg,$C,MC,Xs,Ys,Zs,gd,fi,md,hd,eo,fd,Ad,$g,Zf,eA,tA,FC,rA,nA,UC,iA,Mg,sA,oA,aA,QC,cA,Ai,yd,dA,HC,lA,to,ro,Id,Fg,GC,Ug,qC,Qg,VC,Hg,jC,Gg,zC};
7355
+ export{Sp,x,Cp,rf,uy,nf,py,gy,my,hy,fy,Ay,yy,Iy,Sy,Cy,bp,Ep,Wc,Jc,Qs,_,d,Xc,vp,O,Yc,p,sf,ui,Zc,ed,ce,td,by,r,t,Ey,vy,g,Ty,wy,Ry,Dy,Py,Mt,rd,Hs,of,Ny,ky,Se,Ue,Ce,L,I,o,A,Qe,m,af,He,M,ct,By,cf,F,nd,be,Ft,Gs,X,id,Y,df,qs,U,Q,D,pi,E,Ut,dt,H,e,Vs,xy,Tp,sd,_y,Oy,Ly,$y,od,My,Fy,Uy,Qy,Hy,Gy,qy,Vy,jy,zy,Ky,Wy,lf,uf,pf,gf,mf,hf,ff,Qt,wp,Rp,Nr,gi,Jy,Dp,Xy,Yy,kr,Zy,eI,tI,rI,nI,iI,Af,yf,If,Sf,Cf,js,sI,bf,Ef,vf,G,oI,Ge,zs,Ht,Tf,Pp,wf,Rf,Df,Np,Z,aI,cI,dI,lI,Pf,uI,q,pI,gI,mI,kp,Bp,hI,xp,_p,fI,yI,II,SI,CI,Nf,ad,bI,EI,vI,TI,wI,kf,Bf,RI,DI,PI,NI,kI,BI,xI,_I,OI,Op,cd,LI,$I,MI,FI,Lp,$p,Mp,UI,Fp,QI,HI,GI,qI,Up,VI,jI,zI,KI,WI,JI,XI,YI,xf,_f,Of,Lf,Qp,ZI,eS,tS,rS,nS,iS,sS,oS,aS,$f,Mf,Ff,Uf,cS,dS,Hp,lS,Gp,qp,Vp,jp,uS,pS,gS,mS,Ee,mi,hS,fS,AS,yS,IS,SS,CS,bS,Qf,ES,vS,zp,Kp,TS,wS,Hf,RS,DS,PS,NS,kS,BS,xS,_S,OS,LS,$S,MS,FS,US,QS,HS,GS,qS,VS,jS,zS,Wp,KS,Jp,WS,Xp,JS,Yp,XS,Zp,YS,Br,ZS,eg,eC,Ks,tC,tg,rC,rg,nC,ng,iC,ig,sC,sg,oC,xr,aC,og,cC,ag,dC,cg,lC,dg,uC,lg,pC,ug,gC,pg,mC,gg,hC,mg,fC,hg,AC,fg,yC,Ag,IC,yg,SC,Ig,CC,Sg,bC,Cg,EC,bg,vC,Eg,TC,vg,wC,Tg,RC,wg,DC,Rg,PC,Dg,NC,Pg,kC,Ng,BC,Gf,qf,Vf,jf,kg,xC,Bg,_C,xg,OC,_g,LC,hi,zf,Kf,Ws,dd,_r,Wf,Js,Gt,ld,ud,Jf,Xf,Og,Yf,pd,Lg,$C,MC,Xs,Ys,Zs,gd,fi,md,hd,eo,fd,Ad,$g,Zf,eA,tA,FC,rA,nA,UC,iA,Mg,sA,oA,aA,QC,cA,Ai,yd,dA,HC,lA,to,ro,Id,Fg,GC,Ug,qC,Qg,VC,Hg,jC,Gg,zC};