@stacksjs/ts-cloud 0.11.7 → 0.12.0

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 (102) hide show
  1. package/dist/aws/index.js +1 -1
  2. package/dist/bin/{chunk-znnawt0k.js → chunk-71t1gmsq.js} +1 -1
  3. package/dist/bin/{chunk-4xhj37nj.js → chunk-8ewncfce.js} +1 -1
  4. package/dist/bin/{chunk-8khgprf6.js → chunk-9kf0np8j.js} +1 -1
  5. package/dist/bin/chunk-cxt74wsj.js +1 -0
  6. package/dist/bin/{chunk-j447p8t4.js → chunk-g6baf9c5.js} +84 -84
  7. package/dist/bin/{chunk-zsf6pccz.js → chunk-q5cmfpzt.js} +1 -1
  8. package/dist/bin/{chunk-r6b3pq31.js → chunk-rtecnmts.js} +1 -1
  9. package/dist/bin/{chunk-5nsqz5n3.js → chunk-rv18092e.js} +1 -1
  10. package/dist/bin/{chunk-yw6f160x.js → chunk-ta7sh0cc.js} +1 -1
  11. package/dist/bin/{chunk-cbsys5v8.js → chunk-tfbs8k8v.js} +1 -1
  12. package/dist/bin/{chunk-g0fm1xcs.js → chunk-xkfrqqcs.js} +1 -1
  13. package/dist/bin/cli.js +99 -93
  14. package/dist/bin/dashboard-server.js +1 -1
  15. package/dist/chunk-13qjvbqh.js +2 -0
  16. package/dist/{chunk-nk7sav4r.js → chunk-152he7m3.js} +1 -1
  17. package/dist/{chunk-dr4pj8hp.js → chunk-3mgj3hrh.js} +1 -1
  18. package/dist/chunk-6kpbveb8.js +5 -0
  19. package/dist/{chunk-aw0cgv5w.js → chunk-86ss83s2.js} +1 -1
  20. package/dist/chunk-a84gmpyh.js +1 -0
  21. package/dist/{chunk-ywjkyg8p.js → chunk-b087qsyf.js} +99 -99
  22. package/dist/{chunk-zam6ecam.js → chunk-h42zck7h.js} +2 -2
  23. package/dist/{chunk-zz52xje8.js → chunk-jm5mg890.js} +1 -1
  24. package/dist/{chunk-kasdm9tx.js → chunk-m8fs0233.js} +1 -1
  25. package/dist/chunk-nms5q44e.js +1 -0
  26. package/dist/{chunk-aw0spg20.js → chunk-nzqxdkch.js} +2 -2
  27. package/dist/{chunk-rd38qdnf.js → chunk-qm32ytbr.js} +1 -1
  28. package/dist/{chunk-q0rc1ax9.js → chunk-t0xgmhd6.js} +1 -1
  29. package/dist/{chunk-q9q6cmt0.js → chunk-t3t9ymec.js} +1 -1
  30. package/dist/{chunk-5vt93kxx.js → chunk-y2v22hkv.js} +1 -1
  31. package/dist/deploy/index.js +1 -1
  32. package/dist/dns/index.js +1 -1
  33. package/dist/drivers/index.js +1 -1
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.js +52 -52
  36. package/dist/operations/drained-sites.d.ts +56 -0
  37. package/dist/operations/drained-sites.test.d.ts +1 -0
  38. package/dist/pages/cloudflare-pages.d.ts +227 -0
  39. package/dist/pages/cloudflare-pages.test.d.ts +1 -0
  40. package/dist/pages/index.d.ts +2 -0
  41. package/dist/protection/index.js +1 -1
  42. package/dist/push/index.js +1 -1
  43. package/dist/spend/index.js +1 -1
  44. package/dist/ui/404.html +1 -1
  45. package/dist/ui/accept-invitation.html +1 -1
  46. package/dist/ui/access-denied.html +1 -1
  47. package/dist/ui/account/automation.html +5 -5
  48. package/dist/ui/account/security.html +2 -2
  49. package/dist/ui/applications/compose.html +6 -6
  50. package/dist/ui/applications/new.html +2 -2
  51. package/dist/ui/data/backups.html +6 -6
  52. package/dist/ui/data/services.html +6 -6
  53. package/dist/ui/data/volumes.html +6 -6
  54. package/dist/ui/index.html +6 -6
  55. package/dist/ui/infrastructure/topology.html +5 -5
  56. package/dist/ui/integrations.html +1 -1
  57. package/dist/ui/operations/alerts.html +6 -6
  58. package/dist/ui/operations/configuration.html +6 -6
  59. package/dist/ui/operations/jobs.html +6 -6
  60. package/dist/ui/operations/maintenance.html +6 -6
  61. package/dist/ui/operations/observability.html +6 -6
  62. package/dist/ui/operations/previews.html +6 -6
  63. package/dist/ui/operations/queue.html +5 -5
  64. package/dist/ui/operations/regions.html +6 -6
  65. package/dist/ui/operations/releases.html +6 -6
  66. package/dist/ui/operations/spend.html +6 -6
  67. package/dist/ui/operations/workloads.html +6 -6
  68. package/dist/ui/security.html +2 -2
  69. package/dist/ui/server/actions.html +6 -6
  70. package/dist/ui/server/activity.html +2 -2
  71. package/dist/ui/server/capacity.html +6 -6
  72. package/dist/ui/server/database.html +6 -6
  73. package/dist/ui/server/deployments.html +6 -6
  74. package/dist/ui/server/diagnostics.html +2 -2
  75. package/dist/ui/server/firewall.html +6 -6
  76. package/dist/ui/server/fleet.html +6 -6
  77. package/dist/ui/server/logs.html +6 -6
  78. package/dist/ui/server/metrics.html +6 -6
  79. package/dist/ui/server/security.html +2 -2
  80. package/dist/ui/server/services.html +1 -1
  81. package/dist/ui/server/sites.html +6 -6
  82. package/dist/ui/server/ssh-keys.html +6 -6
  83. package/dist/ui/server/team.html +6 -6
  84. package/dist/ui/server/terminal.html +2 -2
  85. package/dist/ui/serverless/alarms.html +5 -5
  86. package/dist/ui/serverless/assets.html +1 -1
  87. package/dist/ui/serverless/cost.html +2 -2
  88. package/dist/ui/serverless/data.html +5 -5
  89. package/dist/ui/serverless/deployments.html +1 -1
  90. package/dist/ui/serverless/firewall.html +2 -2
  91. package/dist/ui/serverless/functions.html +6 -6
  92. package/dist/ui/serverless/logs.html +6 -6
  93. package/dist/ui/serverless/metrics.html +1 -1
  94. package/dist/ui/serverless/queues.html +6 -6
  95. package/dist/ui/serverless/secrets.html +6 -6
  96. package/dist/ui/serverless/traces.html +6 -6
  97. package/dist/ui/serverless.html +6 -6
  98. package/package.json +4 -3
  99. package/dist/bin/chunk-wkx799z2.js +0 -1
  100. package/dist/chunk-95e6aeqz.js +0 -1
  101. package/dist/chunk-p10xt3jb.js +0 -1
  102. package/dist/chunk-z2qqwy7e.js +0 -2
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
- import{$ as Gg,$a as LC,$b as LS,$c as rA,A as xf,Aa as cC,Ab as cS,B as Lf,Ba as lC,Bb as lS,Bc as Ri,C as Mf,Ca as dC,Cb as dS,Cc as Ti,D as Ff,Da as uC,Db as uS,Dc as $i,E as bg,Ea as pC,Eb as pS,Ec as Pi,F as Rg,Fa as mC,Fb as mS,Fc as Ii,G as Tg,Ga as fC,Gb as fS,Gc as Di,H as $g,Ha as gC,Hb as gS,Hc as Ei,I as Pg,Ia as hC,Ib as hS,J as Ig,Ja as yC,Jb as yS,K as Dg,Ka as CC,Kb as CS,L as Eg,La as SC,Lb as SS,M as wg,Ma as AC,Mb as AS,N as vg,Na as bC,Nb as bS,O as Og,Oa as RC,Ob as RS,P as Ng,Pa as TC,Pb as TS,Pc as GS,Q as kg,Qa as $C,Qb as $S,Qc as US,R as xg,Ra as PC,Rb as PS,Rc as KS,S as Lg,Sa as IC,Sb as IS,Sc as qS,T as Mg,Ta as DC,Tb as DS,Tc as ZS,U as Fg,Ua as EC,Ub as ES,Uc as jS,V as Vg,Va as wC,Vb as wS,Vc as JS,W as _g,Wa as vC,Wb as vS,Wc as YS,X as Bg,Xa as OC,Xb as OS,Xc as QS,Y as Wg,Ya as NC,Yb as NS,Yc as XS,Z as Hg,Za as kC,Zb as kS,Zc as eA,_ as zg,_a as xC,_b as xS,_c as tA,a as Um,aa as Ug,ab as MC,ac as MS,ad as nA,b as Km,ba as Kg,bb as FC,bc as FS,bd as iA,c as qm,ca as Vy,cb as VC,cc as VS,cd as oA,d as Zm,da as _y,db as _C,dc as _S,dd as aA,e as jm,ea as By,eb as BC,ec as BS,ed as sA,f as Jm,fa as Wy,fb as WC,fc as WS,fd as cA,g as Ym,ga as Hy,gb as HC,gc as HS,gd as lA,h as Qm,ha as zy,hb as zC,hc as zS,hd as dA,i as Xm,ia as Gy,ib as GC,id as uA,j as ef,ja as Uy,jb as UC,jd as pA,k as tf,ka as Ky,kb as KC,kd as mA,l as rf,la as qy,lb as qC,ld as fA,m as nf,ma as Zy,mb as ZC,md as gA,n as of,na as jy,nb as jC,nd as hA,o as af,oa as Jy,ob as JC,od as wi,p as sf,pa as Yy,pb as YC,pc as Ai,pd as vi,q as cf,qa as Qy,qb as QC,qd as Oi,r as lf,ra as Xy,rb as XC,rd as Ni,s as df,sa as eC,sb as eS,t as uf,ta as tC,tb as tS,u as pf,ua as rC,ub as rS,v as mf,va as nC,vb as nS,w as ff,wa as iC,wb as iS,x as gf,xa as oC,xb as oS,y as Nf,ya as aC,yb as aS,z as kf,za as sC,zb as sS}from"./chunk-ywjkyg8p.js";import{Ad as Si,sd as ui,td as pi,ud as mi,vd as fi,wd as gi,xd as hi,yd as yi,zd as Ci}from"./chunk-zam6ecam.js";import{Id as bi}from"./chunk-dr4pj8hp.js";import{$d as wr,Be as Vr,Fe as _r,Jd as Bt,Ld as Wt,Le as Br,Md as Ht,Nd as zt,Od as Gt,Oe as Wr,Pd as Ut,Pe as Hr,Qd as Kt,Qe as zr,Re as Gr,Sd as Zt,Td as Sr,Ud as br,Vd as Rr,Wd as Tr,We as Ur,Xd as $r,Yd as Pr,Zd as Ir,_d as Dr,ae as vr,be as Or,ce as Nr,de as kr,ef as Kr,if as qr,ke as xr,nf as Zr,pe as Lr,te as Mr,xe as Fr}from"./chunk-q0rc1ax9.js";import{of as Rt,pf as $t,qf as Pt}from"./chunk-kasdm9tx.js";import{sf as Me}from"./chunk-by2bwzk6.js";import{tf as Cr}from"./chunk-73ztr55z.js";import{uf as Er}from"./chunk-xcj8zfmg.js";import{Af as er,Bf as tr,Cf as rr,Df as nr,Ef as ir,Ff as or,Gf as ar,Hf as sr,If as cr,Jf as lr,Kf as dr,Lf as ur,Mf as pr,Nf as J,Of as mr,Pf as fr,Qf as gr,Rf as hr,Sf as yr,vf as jt,wf as Jt,xf as Yt,yf as Qt,zf as Xt}from"./chunk-tz9myq9a.js";import{Tf as j}from"./chunk-y4xkj2f1.js";import{$f as tn,$g as Nn,Ah as _n,Bh as Bn,Fh as Wn,Gh as Hn,Hg as Cn,Hh as zn,Ig as Sn,Ih as Gn,Jh as Un,Kg as An,Kh as Kn,Lg as bn,Lh as qn,Mg as Rn,Ng as Tn,Nh as Zn,Og as $n,Oh as jn,Ph as Jn,Qh as Yn,Rg as Pn,Sg as In,Tg as Dn,Uf as jr,Vf as Jr,Wf as Yr,Xf as Qr,Xg as En,Yf as ue,Yg as wn,Zf as Xr,Zg as vn,_f as en,_g as On,ag as rn,ah as kn,bg as nn,ig as Ee,lg as on,mg as an,ng as sn,og as cn,oh as xn,ph as Ln,qg as ln,qh as Mn,rg as dn,rh as Fn,vg as un,wg as pe,zh as Vn}from"./chunk-aw0spg20.js";import{Vh as qt,Wh as Ar}from"./chunk-aj025v2s.js";import{Xh as Le}from"./chunk-wavjkdb8.js";import{Zh as Tt}from"./chunk-nk7sav4r.js";import{$h as bt}from"./chunk-mz0dk78z.js";import{$i as Sg,$j as Uh,Ai as Kf,Aj as Ch,Ak as my,Bi as qf,Bj as Sh,Bk as fy,Ci as Zf,Cj as Ah,Ck as gy,Di as jf,Dj as bh,Dk as hy,Ei as Jf,Ej as Rh,Ek as yy,Fi as Yf,Fj as Th,Fk as Cy,Gi as Qf,Gj as $h,Gk as Sy,Hi as Xf,Hj as Ph,Hk as Ay,Ii as eg,Ij as Ih,Ik as Ot,Ji as tg,Jj as Dh,Jk as by,Ki as rg,Kj as Eh,Kk as Ry,Li as ng,Lj as wh,Lk as Ty,Mi as ig,Mj as vh,Mk as $y,Ni as og,Nj as Oh,Nk as Py,Oi as ag,Oj as Nh,Ok as Iy,Pi as sg,Pj as kh,Pk as Dy,Qi as cg,Qj as xh,Qk as Ey,Ri as lg,Rj as Lh,Rk as wy,Si as dg,Sj as Mh,Sk as vy,Ti as ug,Tj as Fh,Tk as Oy,Ui as pg,Uj as Vh,Uk as Ny,Vi as mg,Vj as _h,Vk as ky,Wi as fg,Wj as Bh,Wk as xy,Xi as gg,Xj as Wh,Xk as Ly,Yi as hg,Yj as Hh,Yk as My,Zi as yg,Zj as zh,Zk as Fy,_i as Cg,_j as Gh,aj as Ag,ak as Kh,bj as qg,bk as qh,ci as hf,cj as Zg,ck as Zh,di as yf,dj as jg,dk as jh,ei as Cf,ej as Jg,ek as Jh,fi as Sf,fj as Yg,fk as Yh,gi as Af,gj as Qg,gk as Qh,hi as bf,hj as Xg,hk as Xh,ii as Rf,ij as eh,ik as ey,ji as Tf,jj as th,jk as ty,ki as $f,kj as rh,kk as ry,li as Pf,lj as nh,lk as ny,mi as If,mj as ih,mk as iy,ni as Df,nj as oh,nk as oy,oi as Ef,oj as ah,ok as ay,pi as wf,pj as sh,pk as sy,qi as vf,qj as ch,qk as It,ri as Of,rj as lh,rk as Dt,si as Vf,sj as dh,sk as Et,ti as _f,tj as uh,tk as wt,ui as Bf,uj as ph,uk as vt,vi as Wf,vj as mh,vk as cy,wi as Hf,wj as fh,wk as ly,xi as zf,xj as gh,xk as dy,yi as Gf,yj as hh,yk as uy,zi as Uf,zj as yh,zk as py}from"./chunk-aw0cgv5w.js";import{$k as Xn,_k as Qn,al as ei,bl as ti,cl as ri,dl as ni,el as ii,gl as oi,hl as ai,il as si,jl as ci,kl as li,ll as di}from"./chunk-1qdne0bf.js";import{nl as pn,ol as mn,pl as fn,ql as gn,rl as hn,sl as yn}from"./chunk-hn40z11p.js";import{Al as _t,tl as Nt,ul as kt,vl as xt,wl as Lt,xl as Mt,yl as Ft,zl as Vt}from"./chunk-x3hay61c.js";import{$l as Ua,$m as De,$n as Ic,$o as Il,$p as Id,$q as Iu,$r as Ip,$s as hm,Am as fs,An as Xs,Ao as Xc,Ap as Xl,Aq as Xd,Ar as Xu,As as Xp,At as zm,Bl as Sa,Bm as te,Bn as ec,Bo as el,Bp as ed,Bq as eu,Br as ep,Bs as em,Bt as Gm,Cl as Aa,Cm as w,Cn as tc,Co as tl,Cp as td,Cq as tu,Cr as tp,Cs as tm,Dl as ba,Dm as Re,Dn as rc,Do as rl,Dp as rd,Dq as ru,Dr as rp,Ds as rm,El as Ra,Em as K,En as nc,Eo as nl,Ep as nd,Eq as nu,Er as np,Es as nm,Fl as Ta,Fm as L,Fn as ic,Fo as il,Fp as id,Fq as iu,Fr as ip,Fs as im,Gl as $a,Gm as gs,Gn as oc,Go as ol,Gp as od,Gq as ou,Gr as op,Gs as om,Hl as Pa,Hm as hs,Hn as ac,Ho as al,Hp as ad,Hq as au,Hr as ap,Hs as am,Il as Ia,Im as re,In as sc,Io as sl,Ip as sd,Iq as su,Ir as sp,Is as sm,Jl as Da,Jm as ys,Jn as cc,Jo as cl,Jp as cd,Jq as cu,Jr as cp,Js as cm,Kl as Ea,Km as Cs,Kn as lc,Ko as ll,Kp as ld,Kq as lu,Kr as lp,Ks as lm,Ll as wa,Lm as Ss,Ln as dc,Lo as dl,Lp as dd,Lq as du,Lr as dp,Ls as dm,Ml as va,Mm as As,Mn as uc,Mo as ul,Mp as ud,Mq as uu,Mr as up,Ms as um,Nl as Oa,Nm as Te,Nn as pc,No as pl,Np as pd,Nq as pu,Nr as pp,Ns as ut,Ol as Na,Om as M,On as mc,Oo as ml,Op as md,Oq as mu,Or as mp,Os as pt,Pl as ka,Pm as q,Pn as fc,Po as fl,Pp as fd,Pq as fu,Pr as fp,Ps as mt,Ql as xa,Qm as ne,Qn as gc,Qo as gl,Qp as gd,Qq as gu,Qr as gp,Qs as ft,Rl as La,Rm as $e,Rn as hc,Ro as hl,Rp as hd,Rq as hu,Rr as hp,Rs as gt,Sl as Ma,Sm as Pe,Sn as yc,So as yl,Sp as yd,Sq as yu,Sr as yp,Ss as ht,Tl as Fa,Tm as bs,Tn as Cc,To as Cl,Tp as Cd,Tq as Cu,Tr as Cp,Ts as yt,Ul as Va,Um as Rs,Un as Sc,Uo as Sl,Up as Sd,Uq as Su,Ur as Sp,Us as Ct,Vl as _a,Vm as Ie,Vn as Ac,Vo as Al,Vp as Ad,Vq as Au,Vr as Ap,Vs as St,Wl as Ba,Wm as Ts,Wn as bc,Wo as bl,Wp as bd,Wq as bu,Wr as bp,Ws as At,Xl as Wa,Xm as $s,Xn as Rc,Xo as Rl,Xp as Rd,Xq as Ru,Xr as Rp,Xs as pm,Yl as Ha,Ym as Ps,Yn as Tc,Yo as Tl,Yp as Td,Yq as Tu,Yr as Tp,Ys as mm,Zl as za,Zm as Is,Zn as $c,Zo as $l,Zp as $d,Zq as $u,Zr as $p,Zs as fm,_l as Ga,_m as Ds,_n as Pc,_o as Pl,_p as Pd,_q as Pu,_r as Pp,_s as gm,am as Ka,an as Z,ao as Dc,ap as Dl,aq as Dd,ar as Du,as as Dp,at as ym,bm as qa,bn as Es,bo as Ec,bp as El,bq as Ed,br as Eu,bs as Ep,bt as Cm,cm as Za,cn as ws,co as wc,cp as wl,cq as wd,cr as wu,cs as wp,ct as Sm,dm as ja,dn as vs,do as vc,dp as vl,dq as vd,dr as vu,ds as vp,dt as Am,em as Ja,en as Os,eo as Oc,ep as Ol,eq as Od,er as Ou,es as Op,et as bm,fm as Se,fn as Ns,fo as Nc,fp as Nl,fq as Nd,fr as Nu,fs as Np,ft as Rm,gm as Ya,gn as ks,go as kc,gp as kl,gq as kd,gr as ku,gs as kp,gt as Tm,hm as Ae,hn as xs,ho as xc,hp as xl,hq as xd,hr as xu,hs as xp,ht as $m,im as be,in as Ls,io as Lc,ip as Ll,iq as Ld,ir as Lu,is as Lp,it as Pm,jm as Qa,jn as Ms,jo as Mc,jp as Ml,jq as Md,jr as Mu,js as Mp,jt as Im,km as Xa,kn as Fs,ko as Fc,kp as Fl,kq as Fd,kr as Fu,ks as Fp,kt as Dm,lm as es,ln as Vs,lo as Vc,lp as Vl,lq as Vd,lr as Vu,ls as Vp,lt as Em,mm as ts,mn as _s,mo as _c,mp as _l,mq as _d,mr as _u,ms as _p,mt as wm,nm as rs,nn as Bs,no as Bc,np as Bl,nq as Bd,nr as Bu,ns as Bp,nt as vm,om as ns,on as Ws,oo as Wc,op as Wl,oq as Wd,or as Wu,os as Wp,ot as Om,pm as is,pn as Hs,po as Hc,pp as Hl,pq as Hd,pr as Hu,ps as Hp,pt as Nm,qm as os,qn as zs,qo as zc,qp as zl,qq as zd,qr as zu,qs as zp,qt as km,rm as as,rn as Gs,ro as Gc,rp as Gl,rq as Gd,rr as Gu,rs as Gp,rt as xm,sm as ss,sn as Us,so as Uc,sp as Ul,sq as Ud,sr as Uu,ss as Up,st as Lm,tm as cs,tn as Ks,to as Kc,tp as Kl,tq as Kd,tr as Ku,ts as Kp,tt as Mm,um as ls,un as qs,uo as qc,up as ql,uq as qd,ur as qu,us as qp,ut as Fm,vm as ds,vn as Zs,vo as Zc,vp as Zl,vq as Zd,vr as Zu,vs as Zp,vt as Vm,wm as us,wn as js,wo as jc,wp as jl,wq as jd,wr as ju,ws as jp,wt as _m,xm as ee,xn as Js,xo as Jc,xp as Jl,xq as Jd,xr as Ju,xs as Jp,xt as Bm,ym as ps,yn as Ys,yo as Yc,yp as Yl,yq as Yd,yr as Yu,ys as Yp,yt as Wm,zm as ms,zn as Qs,zo as Qc,zp as Ql,zq as Qd,zr as Qu,zs as Qp,zt as Hm}from"./chunk-zz52xje8.js";import{Ct as Je}from"./chunk-z2qqwy7e.js";import{createHmac as fe,createSign as _e,timingSafeEqual as Be}from"node:crypto";function B(e){let t=e instanceof Date?e.getTime():e;if(!Number.isFinite(t))throw TypeError("Media access timestamp must be finite");return Math.floor(t/1000)}function ge(e){return Buffer.from(e).toString("base64").replaceAll("+","-").replaceAll("=","_").replaceAll("/","~")}function We(e){return Buffer.from(e).toString("base64url")}function he(e,t=!1){if(!e||/[\r\n]/.test(e))throw TypeError("Media resource is invalid");let r=t?e.replaceAll("*","wildcard"):e,n=new URL(r);if(!["http:","https:"].includes(n.protocol))throw TypeError("Media resource must use HTTP or HTTPS");if(!t&&e.includes("*"))throw TypeError("Canned policies cannot contain wildcards")}function ye(e,t){let r=_e("RSA-SHA1");return r.update(e),r.end(),ge(r.sign(t))}function Ce(e){he(e.resource,!0);let r={DateLessThan:{"AWS:EpochTime":B(e.expiresAt)}};if(e.activeAt!==void 0)r.DateGreaterThan={"AWS:EpochTime":B(e.activeAt)};if(e.ipAddress)r.IpAddress={"AWS:SourceIp":e.ipAddress};return JSON.stringify({Statement:[{Resource:e.resource,Condition:r}]})}function xi(e,t,r){he(e);let n=B(t),o=e.includes("?")?"&":"?",l=Ce({resource:e,expiresAt:t}),c=ye(l,r.privateKey);return`${e}${o}Expires=${n}&Signature=${encodeURIComponent(c)}&Key-Pair-Id=${encodeURIComponent(r.keyPairId)}`}function Li(e,t){let r=Ce(e);return{"CloudFront-Key-Pair-Id":t.keyPairId,"CloudFront-Policy":ge(Buffer.from(r)),"CloudFront-Signature":ye(r,t.privateKey)}}function Mi(e){if(!e.resource||/[\r\n]/.test(e.resource))throw TypeError("Media resource is invalid");let t=We(Buffer.from(JSON.stringify({resource:e.resource,expiresAt:B(e.expiresAt),...e.keyId?{keyId:e.keyId}:{},...e.audience?{audience:e.audience}:{}}))),r=fe("sha256",e.secret).update(t).digest("base64url");return`${t}.${r}`}function Fi(e,t){let[r,n,o]=e.split(".");if(!r||!n||o)return null;let l=fe("sha256",t.secret).update(r).digest(),c;try{c=Buffer.from(n,"base64url")}catch{return null}if(l.length!==c.length||!Be(l,c))return null;try{let s=JSON.parse(Buffer.from(r,"base64url").toString("utf8")),u=B(t.now??Date.now());if(!s.resource||!Number.isSafeInteger(s.expiresAt)||s.expiresAt<=u)return null;if(t.resource&&s.resource!==t.resource)return null;if(t.audience&&s.audience!==t.audience)return null;return s}catch{return null}}function Vi(e,t=!1){let r=new URL(e,"https://media.invalid").pathname.toLowerCase(),n=/\.(?:m3u8|mpd|vtt|json)$/.test(r),o=/\.(?:key|license)$/.test(r)||r.includes("/keys/")||r.includes("/licenses/");return{"Accept-Ranges":"bytes","Cache-Control":t&&(n||o)?"private, no-store":n?"public, max-age=5, s-maxage=30, stale-while-revalidate=30":"public, max-age=31536000, immutable","Cross-Origin-Resource-Policy":"cross-origin","X-Content-Type-Options":"nosniff"}}function _i(e){if(!/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(e.bucket))throw TypeError("Media bucket is invalid");if(!/^[a-z0-9-]+$/.test(e.region))throw TypeError("Media bucket region is invalid");let t=e.prefix?`/${e.prefix.replace(/^\/+|\/+$/g,"")}`:"",r=e.protected??!1,n="public, max-age=31536000, immutable",o=r?"private, no-store":"public, max-age=5, s-maxage=30, stale-while-revalidate=30";return{originDomain:`${e.bucket}.s3.${e.region}.amazonaws.com`,originPath:t,domain:e.domain,trustedKeyGroupIds:[...new Set(e.trustedKeyGroupIds??[])],behaviors:[{pathPattern:"*.m3u8",cacheControl:o,compress:!0,signed:r},{pathPattern:"*.mpd",cacheControl:o,compress:!0,signed:r},{pathPattern:"*.vtt",cacheControl:o,compress:!0,signed:r},{pathPattern:"*",cacheControl:n,compress:!1,signed:r}],responseHeaders:{"Access-Control-Allow-Headers":"Range, If-Range","Access-Control-Allow-Methods":"GET, HEAD, OPTIONS","Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":"Accept-Ranges, Content-Length, Content-Range, ETag","X-Content-Type-Options":"nosniff"}}}class He{builder;config;environment;mergedConfig;serverEipLogicalIds=new Map;constructor(e){this.config=e.config,this.environment=e.environment,this.builder=new Se(`${this.config.project.name} - ${this.environment}`),this.mergedConfig=this.mergeEnvironmentConfig()}mergeEnvironmentConfig(){let t=this.config.environments[this.environment]?.infrastructure;if(!t)return this.config;return{...this.config,infrastructure:{...this.config.infrastructure,...t,compute:{...this.config.infrastructure?.compute,...t.compute},storage:{...this.config.infrastructure?.storage,...t.storage},functions:{...this.config.infrastructure?.functions,...t.functions},servers:{...this.config.infrastructure?.servers,...t.servers},databases:{...this.config.infrastructure?.databases,...t.databases},cdn:{...this.config.infrastructure?.cdn,...t.cdn},sftp:t.sftp??this.config.infrastructure?.sftp,queues:{...this.config.infrastructure?.queues,...t.queues},redirects:{...this.config.infrastructure?.redirects,...t.redirects},realtime:{...this.config.infrastructure?.realtime,...t.realtime},cache:{...this.config.infrastructure?.cache,...t.cache},fileSystem:{...this.config.infrastructure?.fileSystem,...t.fileSystem},email:{...this.config.infrastructure?.email,...t.email},search:{...this.config.infrastructure?.search,...t.search},ai:{...this.config.infrastructure?.ai,...t.ai}}}}shouldDeploy(e){if(e.environments&&!e.environments.includes(this.environment))return!1;if(e.requiresFeatures){let t=this.config.features||{};if(!e.requiresFeatures.every((n)=>t[n]===!0))return!1}if(e.regions){let t=this.config.environments[this.environment]?.region||this.config.project.region;if(!e.regions.includes(t))return!1}if(e.condition&&typeof e.condition==="function")return e.condition(this.config,this.environment);return!0}resolveApiOriginPort(){let e=this.mergedConfig.infrastructure?.api?.port??this.mergedConfig.ports?.api,t=Number(e||3008);return Number.isFinite(t)&&t>0?t:3008}defaultComputeCachePathPatterns(){return["/api/*","/auth/*","/publisher/api/*","/publisher/*","/publish","/publish/*","/analytics/*","/packages/*","/npm/*","/zig/*","/php/*","/commits/*","/health","/dashboard/*","/search","/login","/logout","/signup","/account","/account/*"]}shouldRouteStorageBucketToCompute(e,t){return e==="public"||t.routeCompute===!0}storageBucketName(e,t,r){return this.mergedConfig.infrastructure?.storage?.[r]?.bucket??`${e}-${t}-${r}`}fileSystemLogicalId(e,t,r){return be(Ae({slug:`${e}-${r}`,environment:t,resourceType:"efs"}))}resolveSftpStorage(e,t,r){let n=e.storage;if(n?.type==="efs"&&n.fileSystem){if(!this.mergedConfig.infrastructure?.fileSystem?.[n.fileSystem])throw Error(`sftp: storage.fileSystem "${n.fileSystem}" is not defined in infrastructure.fileSystem`);return{type:"efs",fileSystemId:{Ref:this.fileSystemLogicalId(t,r,n.fileSystem)},posixProfile:n.posixProfile}}if(n?.type==="s3"&&n.storageBucket){if(!this.mergedConfig.infrastructure?.storage?.[n.storageBucket])throw Error(`sftp: storage.storageBucket "${n.storageBucket}" is not defined in infrastructure.storage`);return{type:"s3",bucket:this.storageBucketName(t,r,n.storageBucket)}}return}resolveComputeCachePathPatterns(e){if(e&&e.length>0)return e;return this.defaultComputeCachePathPatterns()}createComputeCacheBehavior(e,t){return{PathPattern:e,TargetOriginId:t,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",OriginRequestPolicyId:"b689b0a8-53d0-40ab-baf2-68738e2966ac"}}appendComputeAppOrigin(e,t,r,n,o,l){let c=this.serverEipLogicalIds.get("app"),s=this.serverEipLogicalIds.get("appInstance");if(!c)return;let u=`EC2-${n}-${o}-api`,h=this.mergedConfig.infrastructure?.servers?.app?.region||this.mergedConfig.project?.region||"us-east-1",d=h==="us-east-1"?".compute-1.amazonaws.com":`.${h}.compute.amazonaws.com`,b={"Fn::Join":["",["ec2-",{"Fn::Join":["-",{"Fn::Split":[".",{Ref:c}]}]},d]]},A=this.resolveApiOriginPort();if(e.push({Id:u,DomainName:b,CustomOriginConfig:{HTTPPort:A,HTTPSPort:443,OriginProtocolPolicy:"http-only",OriginSSLProtocols:["TLSv1.2"]}}),r.push(c),s)r.push(s);for(let T of l)t.push(this.createComputeCacheBehavior(T,u))}buildCaddyfile(e){let t=e.filter(([,o])=>typeof o.domain==="string"&&o.domain&&typeof o.port==="number");if(t.length===0)return;let r=new Map;for(let[,o]of t){let l=r.get(o.domain)??[];l.push({port:o.port,path:o.path}),r.set(o.domain,l)}let n=[];for(let[o,l]of r){let s=[...l].sort((u,h)=>{let d=!u.path||u.path==="/",b=!h.path||h.path==="/";if(d&&!b)return 1;if(!d&&b)return-1;return(h.path?.length??0)-(u.path?.length??0)}).map((u)=>{let h=!u.path||u.path==="/",d=`reverse_proxy localhost:${u.port}`;return h?` handle {
2
- ${d}
3
- }`:` handle ${u.path} {
4
- ${d}
5
- }`});n.push(`${o} {
6
- ${s.join(`
1
+ import{$ as nh,$a as qC,$b as qS,$c as gA,A as Kf,Aa as bC,Ab as bS,B as qf,Ba as RC,Bb as RS,Bc as Oi,C as Zf,Ca as TC,Cb as TS,Cc as Ni,D as Jf,Da as PC,Db as PS,Dc as ki,E as xg,Ea as $C,Eb as $S,Ec as xi,F as Lg,Fa as DC,Fb as DS,Fc as Li,G as Fg,Ga as IC,Gb as IS,Gc as Fi,H as Mg,Ha as wC,Hb as wS,Hc as Mi,I as _g,Ia as EC,Ib as ES,J as Bg,Ja as vC,Jb as vS,K as Vg,Ka as OC,Kb as OS,L as Wg,La as NC,Lb as NS,M as Hg,Ma as kC,Mb as kS,N as zg,Na as xC,Nb as xS,O as Gg,Oa as LC,Ob as LS,P as Ug,Pa as FC,Pb as FS,Pc as nA,Q as jg,Qa as MC,Qb as MS,Qc as iA,R as Kg,Ra as _C,Rb as _S,Rc as oA,S as qg,Sa as BC,Sb as BS,Sc as aA,T as Zg,Ta as VC,Tb as VS,Tc as sA,U as Jg,Ua as WC,Ub as WS,Uc as cA,V as Yg,Va as HC,Vb as HS,Vc as lA,W as Xg,Wa as zC,Wb as zS,Wc as dA,X as Qg,Xa as GC,Xb as GS,Xc as uA,Y as eh,Ya as UC,Yb as US,Yc as pA,Z as th,Za as jC,Zb as jS,Zc as mA,_ as rh,_a as KC,_b as KS,_c as fA,a as of,aa as ih,ab as ZC,ac as ZS,ad as hA,b as af,ba as oh,bb as JC,bc as JS,bd as yA,c as sf,ca as Yy,cb as YC,cc as YS,cd as CA,d as cf,da as Xy,db as XC,dc as XS,dd as SA,e as lf,ea as Qy,eb as QC,ec as QS,ed as AA,f as df,fa as eC,fb as eS,fc as eA,fd as bA,g as uf,ga as tC,gb as tS,gc as tA,gd as RA,h as pf,ha as rC,hb as rS,hc as rA,hd as TA,i as mf,ia as nC,ib as nS,id as PA,j as ff,ja as iC,jb as iS,jd as $A,k as gf,ka as oC,kb as oS,kd as DA,l as hf,la as aC,lb as aS,ld as IA,m as yf,ma as sC,mb as sS,md as wA,n as Cf,na as cC,nb as cS,nd as EA,o as Sf,oa as lC,ob as lS,od as _i,p as Af,pa as dC,pb as dS,pc as Ei,pd as Bi,q as bf,qa as uC,qb as uS,qd as Vi,r as Rf,ra as pC,rb as pS,rd as Wi,s as Tf,sa as mC,sb as mS,t as Pf,ta as fC,tb as fS,u as $f,ua as gC,ub as gS,v as Df,va as hC,vb as hS,w as If,wa as yC,wb as yS,x as wf,xa as CC,xb as CS,y as Uf,ya as SC,yb as SS,z as jf,za as AC,zb as AS}from"./chunk-b087qsyf.js";import{Ad as wi,sd as Ai,td as bi,ud as Ri,vd as Ti,wd as Pi,xd as $i,yd as Di,zd as Ii}from"./chunk-h42zck7h.js";import{Id as vi}from"./chunk-3mgj3hrh.js";import{$d as _r,Be as Kr,Fe as qr,Jd as Zt,Ld as Jt,Le as Zr,Md as Yt,Nd as Xt,Od as Qt,Oe as Jr,Pd as er,Pe as Yr,Qd as tr,Qe as Xr,Re as Qr,Sd as nr,Td as wr,Ud as vr,Vd as Or,Wd as Nr,We as en,Xd as kr,Yd as xr,Zd as Lr,_d as Fr,ae as Br,be as Vr,ce as Wr,de as Hr,ef as tn,if as rn,ke as zr,nf as nn,pe as Gr,te as Ur,xe as jr}from"./chunk-t0xgmhd6.js";import{of as Ot,pf as kt,qf as xt}from"./chunk-m8fs0233.js";import{sf as We}from"./chunk-by2bwzk6.js";import{tf as Ir}from"./chunk-73ztr55z.js";import{uf as Mr}from"./chunk-xcj8zfmg.js";import{Af as lr,Bf as dr,Cf as ur,Df as pr,Ef as mr,Ff as fr,Gf as gr,Hf as hr,If as yr,Jf as Cr,Kf as Sr,Lf as Ar,Mf as br,Nf as Y,Of as Rr,Pf as Tr,Qf as Pr,Rf as $r,Sf as Dr,vf as ir,wf as or,xf as ar,yf as sr,zf as cr}from"./chunk-tz9myq9a.js";import{Tf as J}from"./chunk-y4xkj2f1.js";import{$f as un,$g as Wn,Ah as qn,Bh as Zn,Fh as Jn,Gh as Yn,Hg as In,Hh as Xn,Ig as wn,Ih as Qn,Jh as ei,Kg as En,Kh as ti,Lg as vn,Lh as ri,Mg as On,Ng as Nn,Nh as ni,Og as kn,Oh as ii,Ph as oi,Qh as ai,Rg as xn,Sg as Ln,Tg as Fn,Uf as on,Vf as an,Wf as sn,Xf as cn,Xg as Mn,Yf as pe,Yg as _n,Zf as ln,Zg as Bn,_f as dn,_g as Vn,ag as pn,ah as Hn,bg as mn,ig as ve,lg as fn,mg as gn,ng as hn,og as yn,oh as zn,ph as Gn,qg as Cn,qh as Un,rg as Sn,rh as jn,vg as An,wg as me,zh as Kn}from"./chunk-nzqxdkch.js";import{Vh as rr,Wh as Er}from"./chunk-aj025v2s.js";import{Xh as Ve}from"./chunk-wavjkdb8.js";import{Zh as Nt}from"./chunk-152he7m3.js";import{$h as vt}from"./chunk-mz0dk78z.js";import{$i as Ng,$j as iy,Ai as og,Aj as Oh,Ak as Dy,Bi as ag,Bj as Nh,Bk as Iy,Ci as sg,Cj as kh,Ck as wy,Di as cg,Dj as xh,Dk as Ey,Ei as lg,Ej as Lh,Ek as vy,Fi as dg,Fj as Fh,Fk as Oy,Gi as ug,Gj as Mh,Gk as Ny,Hi as pg,Hj as _h,Hk as ky,Ii as mg,Ij as Bh,Ik as Vt,Ji as fg,Jj as Vh,Jk as xy,Ki as gg,Kj as Wh,Kk as Ly,Li as hg,Lj as Hh,Lk as Fy,Mi as yg,Mj as zh,Mk as My,Ni as Cg,Nj as Gh,Nk as _y,Oi as Sg,Oj as Uh,Ok as By,Pi as Ag,Pj as jh,Pk as Vy,Qi as bg,Qj as Kh,Qk as Wy,Ri as Rg,Rj as qh,Rk as Hy,Si as Tg,Sj as Zh,Sk as zy,Ti as Pg,Tj as Jh,Tk as Gy,Ui as $g,Uj as Yh,Uk as Uy,Vi as Dg,Vj as Xh,Vk as jy,Wi as Ig,Wj as Qh,Wk as Ky,Xi as wg,Xj as ey,Xk as qy,Yi as Eg,Yj as ty,Yk as Zy,Zi as vg,Zj as ry,Zk as Jy,_i as Og,_j as ny,aj as kg,ak as oy,bj as ah,bk as ay,ci as Ef,cj as sh,ck as sy,di as vf,dj as ch,dk as cy,ei as Of,ej as lh,ek as ly,fi as Nf,fj as dh,fk as dy,gi as kf,gj as uh,gk as uy,hi as xf,hj as ph,hk as py,ii as Lf,ij as mh,ik as my,ji as Ff,jj as fh,jk as fy,ki as Mf,kj as gh,kk as gy,li as _f,lj as hh,lk as hy,mi as Bf,mj as yh,mk as yy,ni as Vf,nj as Ch,nk as Cy,oi as Wf,oj as Sh,ok as Sy,pi as Hf,pj as Ah,pk as Ay,qi as zf,qj as bh,qk as Lt,ri as Gf,rj as Rh,rk as Ft,si as Yf,sj as Th,sk as Mt,ti as Xf,tj as Ph,tk as _t,ui as Qf,uj as $h,uk as Bt,vi as eg,vj as Dh,vk as by,wi as tg,wj as Ih,wk as Ry,xi as rg,xj as wh,xk as Ty,yi as ng,yj as Eh,yk as Py,zi as ig,zj as vh,zk as $y}from"./chunk-86ss83s2.js";import{$k as ci,_k as si,al as li,bl as di,cl as ui,dl as pi,el as mi,gl as fi,hl as gi,il as hi,jl as yi,kl as Ci,ll as Si}from"./chunk-1qdne0bf.js";import{nl as bn,ol as Rn,pl as Tn,ql as Pn,rl as $n,sl as Dn}from"./chunk-hn40z11p.js";import{Al as qt,tl as Wt,ul as Ht,vl as zt,wl as Gt,xl as Ut,yl as jt,zl as Kt}from"./chunk-x3hay61c.js";import{$l as is,$m as Ee,$n as Bc,$o as Bl,$p as Bd,$q as Bu,$r as Bp,$s as Em,Am as Is,An as pc,Ao as pl,Ap as pd,Aq as pu,Ar as pp,As as pm,At as rf,Bl as Na,Bm as re,Bn as mc,Bo as ml,Bp as md,Bq as mu,Br as mp,Bs as mm,Bt as nf,Cl as ka,Cm as E,Cn as fc,Co as fl,Cp as fd,Cq as fu,Cr as fp,Cs as fm,Dl as xa,Dm as Pe,Dn as gc,Do as gl,Dp as gd,Dq as gu,Dr as gp,Ds as gm,El as La,Em as j,En as hc,Eo as hl,Ep as hd,Eq as hu,Er as hp,Es as hm,Fl as Fa,Fm as L,Fn as yc,Fo as yl,Fp as yd,Fq as yu,Fr as yp,Fs as ym,Gl as Ma,Gm as ws,Gn as Cc,Go as Cl,Gp as Cd,Gq as Cu,Gr as Cp,Gs as Cm,Hl as _a,Hm as Es,Hn as Sc,Ho as Sl,Hp as Sd,Hq as Su,Hr as Sp,Hs as Sm,Il as Ba,Im as ne,In as Ac,Io as Al,Ip as Ad,Iq as Au,Ir as Ap,Is as Am,Jl as Va,Jm as vs,Jn as bc,Jo as bl,Jp as bd,Jq as bu,Jr as bp,Js as bm,Kl as Wa,Km as Os,Kn as Rc,Ko as Rl,Kp as Rd,Kq as Ru,Kr as Rp,Ks as Rm,Ll as Ha,Lm as Ns,Ln as Tc,Lo as Tl,Lp as Td,Lq as Tu,Lr as Tp,Ls as Tm,Ml as za,Mm as ks,Mn as Pc,Mo as Pl,Mp as Pd,Mq as Pu,Mr as Pp,Ms as Pm,Nl as Ga,Nm as $e,Nn as $c,No as $l,Np as $d,Nq as $u,Nr as $p,Ns as At,Ol as Ua,Om as F,On as Dc,Oo as Dl,Op as Dd,Oq as Du,Or as Dp,Os as bt,Pl as ja,Pm as K,Pn as Ic,Po as Il,Pp as Id,Pq as Iu,Pr as Ip,Ps as Rt,Ql as Ka,Qm as ie,Qn as wc,Qo as wl,Qp as wd,Qq as wu,Qr as wp,Qs as Tt,Rl as qa,Rm as De,Rn as Ec,Ro as El,Rp as Ed,Rq as Eu,Rr as Ep,Rs as Pt,Sl as Za,Sm as Ie,Sn as vc,So as vl,Sp as vd,Sq as vu,Sr as vp,Ss as $t,Tl as Ja,Tm as xs,Tn as Oc,To as Ol,Tp as Od,Tq as Ou,Tr as Op,Ts as Dt,Ul as Ya,Um as Ls,Un as Nc,Uo as Nl,Up as Nd,Uq as Nu,Ur as Np,Us as It,Vl as Xa,Vm as we,Vn as kc,Vo as kl,Vp as kd,Vq as ku,Vr as kp,Vs as wt,Wl as Qa,Wm as Fs,Wn as xc,Wo as xl,Wp as xd,Wq as xu,Wr as xp,Ws as Et,Xl as es,Xm as Ms,Xn as Lc,Xo as Ll,Xp as Ld,Xq as Lu,Xr as Lp,Xs as $m,Yl as ts,Ym as _s,Yn as Fc,Yo as Fl,Yp as Fd,Yq as Fu,Yr as Fp,Ys as Dm,Zl as rs,Zm as Bs,Zn as Mc,Zo as Ml,Zp as Md,Zq as Mu,Zr as Mp,Zs as Im,_l as ns,_m as Vs,_n as _c,_o as _l,_p as _d,_q as _u,_r as _p,_s as wm,am as os,an as q,ao as Vc,ap as Vl,aq as Vd,ar as Vu,as as Vp,at as vm,bm as as,bn as Ws,bo as Wc,bp as Wl,bq as Wd,br as Wu,bs as Wp,bt as Om,cm as ss,cn as Hs,co as Hc,cp as Hl,cq as Hd,cr as Hu,cs as Hp,ct as Nm,dm as cs,dn as zs,do as zc,dp as zl,dq as zd,dr as zu,ds as zp,dt as km,em as ls,en as Gs,eo as Gc,ep as Gl,eq as Gd,er as Gu,es as Gp,et as xm,fm as be,fn as Us,fo as Uc,fp as Ul,fq as Ud,fr as Uu,fs as Up,ft as Lm,gm as ds,gn as js,go as jc,gp as jl,gq as jd,gr as ju,gs as jp,gt as Fm,hm as Re,hn as Ks,ho as Kc,hp as Kl,hq as Kd,hr as Ku,hs as Kp,ht as Mm,im as Te,in as qs,io as qc,ip as ql,iq as qd,ir as qu,is as qp,it as _m,jm as us,jn as Zs,jo as Zc,jp as Zl,jq as Zd,jr as Zu,js as Zp,jt as Bm,km as ps,kn as Js,ko as Jc,kp as Jl,kq as Jd,kr as Ju,ks as Jp,kt as Vm,lm as ms,ln as Ys,lo as Yc,lp as Yl,lq as Yd,lr as Yu,ls as Yp,lt as Wm,mm as fs,mn as Xs,mo as Xc,mp as Xl,mq as Xd,mr as Xu,ms as Xp,mt as Hm,nm as gs,nn as Qs,no as Qc,np as Ql,nq as Qd,nr as Qu,ns as Qp,nt as zm,om as hs,on as ec,oo as el,op as ed,oq as eu,or as ep,os as em,ot as Gm,pm as ys,pn as tc,po as tl,pp as td,pq as tu,pr as tp,ps as tm,pt as Um,qm as Cs,qn as rc,qo as rl,qp as rd,qq as ru,qr as rp,qs as rm,qt as jm,rm as Ss,rn as nc,ro as nl,rp as nd,rq as nu,rr as np,rs as nm,rt as Km,sm as As,sn as ic,so as il,sp as id,sq as iu,sr as ip,ss as im,st as qm,tm as bs,tn as oc,to as ol,tp as od,tq as ou,tr as op,ts as om,tt as Zm,um as Rs,un as ac,uo as al,up as ad,uq as au,ur as ap,us as am,ut as Jm,vm as Ts,vn as sc,vo as sl,vp as sd,vq as su,vr as sp,vs as sm,vt as Ym,wm as Ps,wn as cc,wo as cl,wp as cd,wq as cu,wr as cp,ws as cm,wt as Xm,xm as te,xn as lc,xo as ll,xp as ld,xq as lu,xr as lp,xs as lm,xt as Qm,ym as $s,yn as dc,yo as dl,yp as dd,yq as du,yr as dp,ys as dm,yt as ef,zm as Ds,zn as uc,zo as ul,zp as ud,zq as uu,zr as up,zs as um,zt as tf}from"./chunk-jm5mg890.js";import{Ct as gt,Et as Z}from"./chunk-13qjvbqh.js";import{createHmac as he,createSign as Ge,timingSafeEqual as Ue}from"node:crypto";function V(e){let t=e instanceof Date?e.getTime():e;if(!Number.isFinite(t))throw TypeError("Media access timestamp must be finite");return Math.floor(t/1000)}function ye(e){return Buffer.from(e).toString("base64").replaceAll("+","-").replaceAll("=","_").replaceAll("/","~")}function je(e){return Buffer.from(e).toString("base64url")}function Ce(e,t=!1){if(!e||/[\r\n]/.test(e))throw TypeError("Media resource is invalid");let r=t?e.replaceAll("*","wildcard"):e,n=new URL(r);if(!["http:","https:"].includes(n.protocol))throw TypeError("Media resource must use HTTP or HTTPS");if(!t&&e.includes("*"))throw TypeError("Canned policies cannot contain wildcards")}function Se(e,t){let r=Ge("RSA-SHA1");return r.update(e),r.end(),ye(r.sign(t))}function Ae(e){Ce(e.resource,!0);let r={DateLessThan:{"AWS:EpochTime":V(e.expiresAt)}};if(e.activeAt!==void 0)r.DateGreaterThan={"AWS:EpochTime":V(e.activeAt)};if(e.ipAddress)r.IpAddress={"AWS:SourceIp":e.ipAddress};return JSON.stringify({Statement:[{Resource:e.resource,Condition:r}]})}function zi(e,t,r){Ce(e);let n=V(t),i=e.includes("?")?"&":"?",d=Ae({resource:e,expiresAt:t}),s=Se(d,r.privateKey);return`${e}${i}Expires=${n}&Signature=${encodeURIComponent(s)}&Key-Pair-Id=${encodeURIComponent(r.keyPairId)}`}function Gi(e,t){let r=Ae(e);return{"CloudFront-Key-Pair-Id":t.keyPairId,"CloudFront-Policy":ye(Buffer.from(r)),"CloudFront-Signature":Se(r,t.privateKey)}}function Ui(e){if(!e.resource||/[\r\n]/.test(e.resource))throw TypeError("Media resource is invalid");let t=je(Buffer.from(JSON.stringify({resource:e.resource,expiresAt:V(e.expiresAt),...e.keyId?{keyId:e.keyId}:{},...e.audience?{audience:e.audience}:{}}))),r=he("sha256",e.secret).update(t).digest("base64url");return`${t}.${r}`}function ji(e,t){let[r,n,i]=e.split(".");if(!r||!n||i)return null;let d=he("sha256",t.secret).update(r).digest(),s;try{s=Buffer.from(n,"base64url")}catch{return null}if(d.length!==s.length||!Ue(d,s))return null;try{let a=JSON.parse(Buffer.from(r,"base64url").toString("utf8")),l=V(t.now??Date.now());if(!a.resource||!Number.isSafeInteger(a.expiresAt)||a.expiresAt<=l)return null;if(t.resource&&a.resource!==t.resource)return null;if(t.audience&&a.audience!==t.audience)return null;return a}catch{return null}}function Ki(e,t=!1){let r=new URL(e,"https://media.invalid").pathname.toLowerCase(),n=/\.(?:m3u8|mpd|vtt|json)$/.test(r),i=/\.(?:key|license)$/.test(r)||r.includes("/keys/")||r.includes("/licenses/");return{"Accept-Ranges":"bytes","Cache-Control":t&&(n||i)?"private, no-store":n?"public, max-age=5, s-maxage=30, stale-while-revalidate=30":"public, max-age=31536000, immutable","Cross-Origin-Resource-Policy":"cross-origin","X-Content-Type-Options":"nosniff"}}function qi(e){if(!/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(e.bucket))throw TypeError("Media bucket is invalid");if(!/^[a-z0-9-]+$/.test(e.region))throw TypeError("Media bucket region is invalid");let t=e.prefix?`/${e.prefix.replace(/^\/+|\/+$/g,"")}`:"",r=e.protected??!1,n="public, max-age=31536000, immutable",i=r?"private, no-store":"public, max-age=5, s-maxage=30, stale-while-revalidate=30";return{originDomain:`${e.bucket}.s3.${e.region}.amazonaws.com`,originPath:t,domain:e.domain,trustedKeyGroupIds:[...new Set(e.trustedKeyGroupIds??[])],behaviors:[{pathPattern:"*.m3u8",cacheControl:i,compress:!0,signed:r},{pathPattern:"*.mpd",cacheControl:i,compress:!0,signed:r},{pathPattern:"*.vtt",cacheControl:i,compress:!0,signed:r},{pathPattern:"*",cacheControl:n,compress:!1,signed:r}],responseHeaders:{"Access-Control-Allow-Headers":"Range, If-Range","Access-Control-Allow-Methods":"GET, HEAD, OPTIONS","Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":"Accept-Ranges, Content-Length, Content-Range, ETag","X-Content-Type-Options":"nosniff"}}}class Ke{builder;config;environment;mergedConfig;serverEipLogicalIds=new Map;constructor(e){this.config=e.config,this.environment=e.environment,this.builder=new be(`${this.config.project.name} - ${this.environment}`),this.mergedConfig=this.mergeEnvironmentConfig()}mergeEnvironmentConfig(){let t=this.config.environments[this.environment]?.infrastructure;if(!t)return this.config;return{...this.config,infrastructure:{...this.config.infrastructure,...t,compute:{...this.config.infrastructure?.compute,...t.compute},storage:{...this.config.infrastructure?.storage,...t.storage},functions:{...this.config.infrastructure?.functions,...t.functions},servers:{...this.config.infrastructure?.servers,...t.servers},databases:{...this.config.infrastructure?.databases,...t.databases},cdn:{...this.config.infrastructure?.cdn,...t.cdn},sftp:t.sftp??this.config.infrastructure?.sftp,queues:{...this.config.infrastructure?.queues,...t.queues},redirects:{...this.config.infrastructure?.redirects,...t.redirects},realtime:{...this.config.infrastructure?.realtime,...t.realtime},cache:{...this.config.infrastructure?.cache,...t.cache},fileSystem:{...this.config.infrastructure?.fileSystem,...t.fileSystem},email:{...this.config.infrastructure?.email,...t.email},search:{...this.config.infrastructure?.search,...t.search},ai:{...this.config.infrastructure?.ai,...t.ai}}}}shouldDeploy(e){if(e.environments&&!e.environments.includes(this.environment))return!1;if(e.requiresFeatures){let t=this.config.features||{};if(!e.requiresFeatures.every((n)=>t[n]===!0))return!1}if(e.regions){let t=this.config.environments[this.environment]?.region||this.config.project.region;if(!e.regions.includes(t))return!1}if(e.condition&&typeof e.condition==="function")return e.condition(this.config,this.environment);return!0}resolveApiOriginPort(){let e=this.mergedConfig.infrastructure?.api?.port??this.mergedConfig.ports?.api,t=Number(e||3008);return Number.isFinite(t)&&t>0?t:3008}defaultComputeCachePathPatterns(){return["/api/*","/auth/*","/publisher/api/*","/publisher/*","/publish","/publish/*","/analytics/*","/packages/*","/npm/*","/zig/*","/php/*","/commits/*","/health","/dashboard/*","/search","/login","/logout","/signup","/account","/account/*"]}shouldRouteStorageBucketToCompute(e,t){return e==="public"||t.routeCompute===!0}storageBucketName(e,t,r){return this.mergedConfig.infrastructure?.storage?.[r]?.bucket??`${e}-${t}-${r}`}fileSystemLogicalId(e,t,r){return Te(Re({slug:`${e}-${r}`,environment:t,resourceType:"efs"}))}resolveSftpStorage(e,t,r){let n=e.storage;if(n?.type==="efs"&&n.fileSystem){if(!this.mergedConfig.infrastructure?.fileSystem?.[n.fileSystem])throw Error(`sftp: storage.fileSystem "${n.fileSystem}" is not defined in infrastructure.fileSystem`);return{type:"efs",fileSystemId:{Ref:this.fileSystemLogicalId(t,r,n.fileSystem)},posixProfile:n.posixProfile}}if(n?.type==="s3"&&n.storageBucket){if(!this.mergedConfig.infrastructure?.storage?.[n.storageBucket])throw Error(`sftp: storage.storageBucket "${n.storageBucket}" is not defined in infrastructure.storage`);return{type:"s3",bucket:this.storageBucketName(t,r,n.storageBucket)}}return}resolveComputeCachePathPatterns(e){if(e&&e.length>0)return e;return this.defaultComputeCachePathPatterns()}createComputeCacheBehavior(e,t){return{PathPattern:e,TargetOriginId:t,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",OriginRequestPolicyId:"b689b0a8-53d0-40ab-baf2-68738e2966ac"}}appendComputeAppOrigin(e,t,r,n,i,d){let s=this.serverEipLogicalIds.get("app"),a=this.serverEipLogicalIds.get("appInstance");if(!s)return;let l=`EC2-${n}-${i}-api`,p=this.mergedConfig.infrastructure?.servers?.app?.region||this.mergedConfig.project?.region||"us-east-1",u=p==="us-east-1"?".compute-1.amazonaws.com":`.${p}.compute.amazonaws.com`,b={"Fn::Join":["",["ec2-",{"Fn::Join":["-",{"Fn::Split":[".",{Ref:s}]}]},u]]},C=this.resolveApiOriginPort();if(e.push({Id:l,DomainName:b,CustomOriginConfig:{HTTPPort:C,HTTPSPort:443,OriginProtocolPolicy:"http-only",OriginSSLProtocols:["TLSv1.2"]}}),r.push(s),a)r.push(a);for(let T of d)t.push(this.createComputeCacheBehavior(T,l))}buildCaddyfile(e){let t=e.filter(([,i])=>typeof i.domain==="string"&&i.domain&&typeof i.port==="number");if(t.length===0)return;let r=new Map;for(let[,i]of t){let d=r.get(i.domain)??[];d.push({port:i.port,path:i.path}),r.set(i.domain,d)}let n=[];for(let[i,d]of r){let a=[...d].sort((l,p)=>{let u=!l.path||l.path==="/",b=!p.path||p.path==="/";if(u&&!b)return 1;if(!u&&b)return-1;return(p.path?.length??0)-(l.path?.length??0)}).map((l)=>{let p=!l.path||l.path==="/",u=`reverse_proxy localhost:${l.port}`;return p?` handle {
2
+ ${u}
3
+ }`:` handle ${l.path} {
4
+ ${u}
5
+ }`});n.push(`${i} {
6
+ ${a.join(`
7
7
  `)}
8
8
  }`)}return n.join(`
9
9
 
10
- `)}normalizeMountPath(e){let t=e?.mountPath||e?.path;if(!t||t==="/")return;let r=`/${t}`.replace(/\/+/g,"/").replace(/\/$/,"");return r==="/"?void 0:r}storageBucketLogicalId(e,t,r){return`${e}-${t}-s3-${r}`.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((n)=>n.charAt(0).toUpperCase()+n.slice(1)).join("")}pathMountRewriteFunctionCode(e,t="directory"){return`function handler(event) { var request = event.request; var prefix = ${JSON.stringify(e)}; var rewriteStyle = ${JSON.stringify(t)}; var uri = request.uri; if (uri === prefix) { uri = '/'; } else if (uri.indexOf(prefix + '/') === 0) { uri = uri.substring(prefix.length); } if (uri === '' || uri === '/') { request.uri = '/index.html'; return request; } if (uri.endsWith('/')) { request.uri = uri + 'index.html'; return request; } var lastSegment = uri.substring(uri.lastIndexOf('/') + 1); if (lastSegment.indexOf('.') === -1) { request.uri = rewriteStyle === 'flat' ? uri + '.html' : uri + '/index.html'; return request; } request.uri = uri; return request; }`}generate(){let e=this.mergedConfig.project.slug,t=this.environment,r=!!(this.mergedConfig.infrastructure?.functions&&Object.keys(this.mergedConfig.infrastructure.functions).length>0||this.mergedConfig.infrastructure?.api),n=!!(this.mergedConfig.infrastructure?.servers&&Object.keys(this.mergedConfig.infrastructure.servers).length>0),o=!!this.mergedConfig.infrastructure?.compute;if(!!((this.mergedConfig.mode||"server")==="serverless"&&this.mergedConfig.infrastructure?.containers&&Object.keys(this.mergedConfig.infrastructure.containers).length>0))this.generateNetworkInfrastructure(e,t),this.generateContainerInfrastructure(e,t);if(r)this.generateServerless(e,t);if(n)this.generateServer(e,t);if(o)this.generateComputeApp(e,t);if(this.mergedConfig.infrastructure?.jumpBox)this.generateJumpBox(e,t);if(this.generateSharedInfrastructure(e,t),this.config.tags)this.applyGlobalTags(this.config.tags);return this}applyGlobalTags(e){}generateNetworkInfrastructure(e,t){if(this.builder.hasResource("VPC"))return;let n=this.mergedConfig.infrastructure?.network?.cidr||"10.0.0.0/16",{vpc:o,logicalId:l}=Re.createVpc({slug:e,environment:t,cidr:n,enableDnsHostnames:!0,enableDnsSupport:!0});this.builder.addResource("VPC",o);let c=`${e}${t}IGW`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(c,{Type:"AWS::EC2::InternetGateway",Properties:{Tags:[{Key:"Name",Value:`${e}-${t}-igw`},{Key:"Environment",Value:t}]}});let s=`${e}${t}IGWAttach`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(s,{Type:"AWS::EC2::VPCGatewayAttachment",Properties:{VpcId:{Ref:"VPC"},InternetGatewayId:{Ref:c}}});let u=`${e}${t}PublicRT`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(u,{Type:"AWS::EC2::RouteTable",Properties:{VpcId:{Ref:"VPC"},Tags:[{Key:"Name",Value:`${e}-${t}-public-rt`},{Key:"Environment",Value:t}]}}),this.builder.addResource(`${e}${t}PublicRoute`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::EC2::Route",Properties:{RouteTableId:{Ref:u},DestinationCidrBlock:"0.0.0.0/0",GatewayId:{Ref:c}},DependsOn:s});let h=this.mergedConfig.environments[t]?.region||this.mergedConfig.project.region||"us-east-1",d=["a","b"];for(let b=0;b<2;b++){let A=`PublicSubnet${b+1}`;this.builder.addResource(A,{Type:"AWS::EC2::Subnet",Properties:{VpcId:{Ref:"VPC"},CidrBlock:`10.0.${b}.0/24`,AvailabilityZone:`${h}${d[b]}`,MapPublicIpOnLaunch:!0,Tags:[{Key:"Name",Value:`${e}-${t}-public-${d[b]}`},{Key:"Environment",Value:t}]}}),this.builder.addResource(`${A}RTAssoc`,{Type:"AWS::EC2::SubnetRouteTableAssociation",Properties:{SubnetId:{Ref:A},RouteTableId:{Ref:u}}})}}generateContainerInfrastructure(e,t){let r=this.mergedConfig.infrastructure?.containers;if(!r)return;let n=this.mergedConfig.infrastructure?.loadBalancer,o=this.mergedConfig.infrastructure?.ssl,l=this.mergedConfig.infrastructure?.dns,c;if(o?.enabled&&o.domains?.length)if(o.certificateArn);else{let d=o.domains[0],b=o.domains.slice(1).map((g)=>{if(g.includes(".")&&g.endsWith(d))return g.replace(`.${d}`,"");return g}),{certificate:A,logicalId:T}=te.createCertificate({domain:d,subdomains:b,slug:e,environment:t,validationMethod:"DNS",hostedZoneId:l?.hostedZoneId});c=T,this.builder.addResource(T,A)}let s="ECSCluster";this.builder.addResource(s,{Type:"AWS::ECS::Cluster",Properties:{ClusterName:`${e}-${t}`,ClusterSettings:[{Name:"containerInsights",Value:"enabled"}],Tags:[{Key:"Name",Value:`${e}-${t}`},{Key:"Environment",Value:t}]}});let u=`${e}${t}ALBSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(u,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ALB security group for ${e}-${t}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:80,ToPort:80,CidrIp:"0.0.0.0/0",Description:"HTTP"},{IpProtocol:"tcp",FromPort:443,ToPort:443,CidrIp:"0.0.0.0/0",Description:"HTTPS"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${e}-${t}-alb-sg`},{Key:"Environment",Value:t}]}});let h=`${e}${t}ECSSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");for(let[d,b]of Object.entries(r)){let A=b.port||3000;this.builder.addResource(h,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ECS tasks security group for ${e}-${t}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:A,ToPort:A,SourceSecurityGroupId:{Ref:u},Description:"Allow traffic from ALB"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${e}-${t}-ecs-sg`},{Key:"Environment",Value:t}]}});let T=`${e}${t}TaskExecRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(T,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-ecs-exec-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"],Policies:[{PolicyName:"ECRPullPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"}]}}]}});let g=`${e}${t}TaskRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(g,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-ecs-task-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"TaskPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:ListBucket"],Resource:"*"}]}}]}});let m=`${e}${t}${d}LogGroup`.replace(/[^a-zA-Z0-9]/g,""),a=`/ecs/${e}-${t}-${d}`;this.builder.addResource(m,{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:a,RetentionInDays:30}});let y=`${e}${t}${d}TaskDef`.replace(/[^a-zA-Z0-9]/g,""),i=String(b.cpu||512),p=String(b.memory||1024);this.builder.addResource(y,{Type:"AWS::ECS::TaskDefinition",Properties:{Family:`${e}-${t}-${d}`,NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:i,Memory:p,ExecutionRoleArn:{"Fn::GetAtt":[T,"Arn"]},TaskRoleArn:{"Fn::GetAtt":[g,"Arn"]},ContainerDefinitions:[{Name:d,Image:{"Fn::Sub":`\${AWS::AccountId}.dkr.ecr.\${AWS::Region}.amazonaws.com/${e}:latest`},Essential:!0,PortMappings:[{ContainerPort:A,Protocol:"tcp"}],LogConfiguration:{LogDriver:"awslogs",Options:{"awslogs-group":a,"awslogs-region":{Ref:"AWS::Region"},"awslogs-stream-prefix":d}},HealthCheck:{Command:["CMD-SHELL",`curl -f http://localhost:${A}${b.healthCheck||"/health"} || exit 1`],Interval:30,Timeout:5,Retries:3,StartPeriod:60}}],Tags:[{Key:"Name",Value:`${e}-${t}-${d}`},{Key:"Environment",Value:t}]},DependsOn:[T,g,m]});let f=`${e}${t}ALB`.replace(/[^a-zA-Z0-9]/g,"");if(n?.enabled!==!1){this.builder.addResource(f,{Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:`${e}-${t}-alb`,Scheme:"internet-facing",Type:"application",Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],SecurityGroups:[{Ref:u}],Tags:[{Key:"Name",Value:`${e}-${t}-alb`},{Key:"Environment",Value:t}]}});let C=`${e}${t}TargetGroup`.replace(/[^a-zA-Z0-9]/g,""),S=n?.healthCheck?.path||b.healthCheck||"/health";this.builder.addResource(C,{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:`${e}-${t}-tg`,Port:A,Protocol:"HTTP",VpcId:{Ref:"VPC"},TargetType:"ip",HealthCheckPath:S,HealthCheckIntervalSeconds:n?.healthCheck?.interval||30,HealthyThresholdCount:n?.healthCheck?.healthyThreshold||2,UnhealthyThresholdCount:n?.healthCheck?.unhealthyThreshold||5,HealthCheckTimeoutSeconds:10,Tags:[{Key:"Name",Value:`${e}-${t}-tg`},{Key:"Environment",Value:t}]}});let R=`${e}${t}HTTPListener`.replace(/[^a-zA-Z0-9]/g,"");if(o?.enabled&&o?.redirectHttp)this.builder.addResource(R,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:f},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"redirect",RedirectConfig:{Protocol:"HTTPS",Port:"443",StatusCode:"HTTP_301"}}]}});else this.builder.addResource(R,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:f},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:C}}]}});if(o?.enabled){let v=o.certificateArn||(c?{Ref:c}:void 0);if(v){let O=`${e}${t}HTTPSListener`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(O,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:f},Port:443,Protocol:"HTTPS",Certificates:[{CertificateArn:v}],DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:C}}],SslPolicy:"ELBSecurityPolicy-TLS13-1-2-2021-06"}})}}let I=`${e}${t}${d}Service`.replace(/[^a-zA-Z0-9]/g,""),D=b.desiredCount||1;this.builder.addResource(I,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${e}-${t}-${d}`,Cluster:{Ref:s},TaskDefinition:{Ref:y},DesiredCount:D,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:h}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},LoadBalancers:[{ContainerName:d,ContainerPort:A,TargetGroupArn:{Ref:C}}],HealthCheckGracePeriodSeconds:120,Tags:[{Key:"Name",Value:`${e}-${t}-${d}`},{Key:"Environment",Value:t}]},DependsOn:[y,R,C]});let P=b.autoScaling;if(P){let v=`${e}${t}${d}ScalableTarget`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(v,{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{MaxCapacity:P.max||10,MinCapacity:P.min||1,ResourceId:{"Fn::Sub":`service/\${${s}}/${e}-${t}-${d}`},ScalableDimension:"ecs:service:DesiredCount",ServiceNamespace:"ecs",RoleARN:{"Fn::Sub":"arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"}},DependsOn:I}),P.targetCpuUtilization)this.builder.addResource(`${e}${t}${d}CPUScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${e}-${t}-${d}-cpu-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:v},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageCPUUtilization"},TargetValue:P.targetCpuUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}});if(P.targetMemoryUtilization)this.builder.addResource(`${e}${t}${d}MemoryScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${e}-${t}-${d}-memory-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:v},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageMemoryUtilization"},TargetValue:P.targetMemoryUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}})}if(l?.domain&&l?.hostedZoneId)this.builder.addResource(`${e}${t}ApiDnsRecord`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:l.hostedZoneId,Name:`api.${l.domain}`,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[f,"DNSName"]},HostedZoneId:{"Fn::GetAtt":[f,"CanonicalHostedZoneID"]}}}});this.builder.addOutput("ECSClusterArn",{Description:"ECS Cluster ARN",Value:{"Fn::GetAtt":[s,"Arn"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-cluster-arn"}}}),this.builder.addOutput("ECSServiceName",{Description:"ECS Service Name",Value:`${e}-${t}-${d}`,Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-service-name"}}}),this.builder.addOutput("LoadBalancerDNS",{Description:"Application Load Balancer DNS Name",Value:{"Fn::GetAtt":[f,"DNSName"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-alb-dns"}}})}else{let C=`${e}${t}${d}Service`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(C,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${e}-${t}-${d}`,Cluster:{Ref:s},TaskDefinition:{Ref:y},DesiredCount:b.desiredCount||1,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:h}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},Tags:[{Key:"Name",Value:`${e}-${t}-${d}`},{Key:"Environment",Value:t}]},DependsOn:[y]})}break}}generateServerless(e,t){if(this.mergedConfig.infrastructure?.functions)for(let[r,n]of Object.entries(this.mergedConfig.infrastructure.functions)){if(!this.shouldDeploy(n))continue;let{role:o,logicalId:l}=$e.createRole({slug:e,environment:t,roleName:`${e}-${t}-${r}-role`,servicePrincipal:"lambda.amazonaws.com",managedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]});this.builder.addResource(l,o);let{lambdaFunction:c,logicalId:s}=w.createLambdaFunction({slug:e,environment:t,functionName:`${e}-${t}-${r}`,handler:n.handler||"index.handler",runtime:n.runtime||"nodejs20.x",code:{zipFile:n.code||"export const handler = async () => ({ statusCode: 200 });"},role:l,timeout:n.timeout,memorySize:n.memorySize});this.builder.addResource(s,c)}if(this.mergedConfig.infrastructure?.api){let{restApi:r,logicalId:n}=Pe.createRestApi({slug:e,environment:t,apiName:`${e}-${t}-api`});this.builder.addResource(n,r)}}generateServer(e,t){if(!this.mergedConfig.infrastructure?.servers)return;let r=this.mergedConfig.infrastructure.servers,n=this.mergedConfig.infrastructure?.compute,o=this.mergedConfig.infrastructure?.ssl;if(Object.values(r).some((c)=>!c.privateNetwork||c.privateNetwork==="create"))this.generateNetworkInfrastructure(e,t);for(let[c,s]of Object.entries(r)){let u=s.instanceType||s.size||n?.size,d=(u?w.InstanceSize.specs[u]:void 0)?.instanceType||u||"t3.micro",b=s.type||"app",A=s.userData||s.startupScript;if(!A)A=w.UserData.generateAppServerScript({runtime:"bun",runtimeVersion:s.bunVersion||"latest",webServer:"none",domain:s.domain,enableSsl:!!o?.enabled,sslEmail:o?.letsEncrypt?.email,installRedis:b==="cache",installDatabaseClients:!!s.database});let T=s.privateNetwork&&s.privateNetwork!=="create"?s.privateNetwork:{Ref:"VPC"},g=s.subnet||{Ref:"PublicSubnet1"},a=!!this.mergedConfig.infrastructure?.email?.server?.enabled,y=[22,80,443,this.resolveApiOriginPort()];if(a)y.push(25,465,587,143,993);let i=w.createServerModeStack({slug:`${e}-${c}`,environment:t,vpcId:T,subnetId:g,instanceType:d,keyName:s.keyName||`${e}-${t}`,domain:s.domain,userData:A,volumeSize:s.diskSize||20,imageId:s.image,allowedPorts:y});for(let[p,f]of Object.entries(i.resources))this.builder.addResource(p,f);this.serverEipLogicalIds.set(c,i.outputs.eipLogicalId),this.serverEipLogicalIds.set(`${c}Instance`,i.outputs.instanceLogicalId),this.builder.addOutput(`${c}InstanceId`,{Value:{Ref:i.outputs.instanceLogicalId},Description:`Instance ID for ${c} server`}),this.builder.addOutput(`${c}PublicIp`,{Value:{Ref:i.outputs.eipLogicalId},Description:`Public IP for ${c} server`})}}generateComputeApp(e,t){let r=this.mergedConfig.infrastructure?.compute;if(!r)return;let n=this.mergedConfig.sites||{},o=Object.entries(n),c=this.mergedConfig.infrastructure?.dns?.domain,s=this.mergedConfig.infrastructure?.database,u=r.size,d=(u?w.InstanceSize.specs[u]:void 0)?.instanceType||u||"t3.micro";if(!this.builder.hasResource("VPC"))this.generateNetworkInfrastructure(e,t);let b=this.buildCaddyfile(o),A=w.UserData.generateBunAppScript({runtime:r.runtime||"bun",runtimeVersion:r.runtimeVersion||"latest",systemPackages:r.systemPackages,database:s,caddyfile:b}),T=Ee(r.appUpdates),g=T.length>0?`${A}
10
+ `)}normalizeMountPath(e){let t=e?.mountPath||e?.path;if(!t||t==="/")return;let r=`/${t}`.replace(/\/+/g,"/").replace(/\/$/,"");return r==="/"?void 0:r}storageBucketLogicalId(e,t,r){return`${e}-${t}-s3-${r}`.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((n)=>n.charAt(0).toUpperCase()+n.slice(1)).join("")}pathMountRewriteFunctionCode(e,t="directory"){return`function handler(event) { var request = event.request; var prefix = ${JSON.stringify(e)}; var rewriteStyle = ${JSON.stringify(t)}; var uri = request.uri; if (uri === prefix) { uri = '/'; } else if (uri.indexOf(prefix + '/') === 0) { uri = uri.substring(prefix.length); } if (uri === '' || uri === '/') { request.uri = '/index.html'; return request; } if (uri.endsWith('/')) { request.uri = uri + 'index.html'; return request; } var lastSegment = uri.substring(uri.lastIndexOf('/') + 1); if (lastSegment.indexOf('.') === -1) { request.uri = rewriteStyle === 'flat' ? uri + '.html' : uri + '/index.html'; return request; } request.uri = uri; return request; }`}generate(){let e=this.mergedConfig.project.slug,t=this.environment,r=!!(this.mergedConfig.infrastructure?.functions&&Object.keys(this.mergedConfig.infrastructure.functions).length>0||this.mergedConfig.infrastructure?.api),n=!!(this.mergedConfig.infrastructure?.servers&&Object.keys(this.mergedConfig.infrastructure.servers).length>0),i=!!this.mergedConfig.infrastructure?.compute;if(!!((this.mergedConfig.mode||"server")==="serverless"&&this.mergedConfig.infrastructure?.containers&&Object.keys(this.mergedConfig.infrastructure.containers).length>0))this.generateNetworkInfrastructure(e,t),this.generateContainerInfrastructure(e,t);if(r)this.generateServerless(e,t);if(n)this.generateServer(e,t);if(i)this.generateComputeApp(e,t);if(this.mergedConfig.infrastructure?.jumpBox)this.generateJumpBox(e,t);if(this.generateSharedInfrastructure(e,t),this.config.tags)this.applyGlobalTags(this.config.tags);return this}applyGlobalTags(e){}generateNetworkInfrastructure(e,t){if(this.builder.hasResource("VPC"))return;let n=this.mergedConfig.infrastructure?.network?.cidr||"10.0.0.0/16",{vpc:i,logicalId:d}=Pe.createVpc({slug:e,environment:t,cidr:n,enableDnsHostnames:!0,enableDnsSupport:!0});this.builder.addResource("VPC",i);let s=`${e}${t}IGW`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(s,{Type:"AWS::EC2::InternetGateway",Properties:{Tags:[{Key:"Name",Value:`${e}-${t}-igw`},{Key:"Environment",Value:t}]}});let a=`${e}${t}IGWAttach`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(a,{Type:"AWS::EC2::VPCGatewayAttachment",Properties:{VpcId:{Ref:"VPC"},InternetGatewayId:{Ref:s}}});let l=`${e}${t}PublicRT`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(l,{Type:"AWS::EC2::RouteTable",Properties:{VpcId:{Ref:"VPC"},Tags:[{Key:"Name",Value:`${e}-${t}-public-rt`},{Key:"Environment",Value:t}]}}),this.builder.addResource(`${e}${t}PublicRoute`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::EC2::Route",Properties:{RouteTableId:{Ref:l},DestinationCidrBlock:"0.0.0.0/0",GatewayId:{Ref:s}},DependsOn:a});let p=this.mergedConfig.environments[t]?.region||this.mergedConfig.project.region||"us-east-1",u=["a","b"];for(let b=0;b<2;b++){let C=`PublicSubnet${b+1}`;this.builder.addResource(C,{Type:"AWS::EC2::Subnet",Properties:{VpcId:{Ref:"VPC"},CidrBlock:`10.0.${b}.0/24`,AvailabilityZone:`${p}${u[b]}`,MapPublicIpOnLaunch:!0,Tags:[{Key:"Name",Value:`${e}-${t}-public-${u[b]}`},{Key:"Environment",Value:t}]}}),this.builder.addResource(`${C}RTAssoc`,{Type:"AWS::EC2::SubnetRouteTableAssociation",Properties:{SubnetId:{Ref:C},RouteTableId:{Ref:l}}})}}generateContainerInfrastructure(e,t){let r=this.mergedConfig.infrastructure?.containers;if(!r)return;let n=this.mergedConfig.infrastructure?.loadBalancer,i=this.mergedConfig.infrastructure?.ssl,d=this.mergedConfig.infrastructure?.dns,s;if(i?.enabled&&i.domains?.length)if(i.certificateArn);else{let u=i.domains[0],b=i.domains.slice(1).map((g)=>{if(g.includes(".")&&g.endsWith(u))return g.replace(`.${u}`,"");return g}),{certificate:C,logicalId:T}=re.createCertificate({domain:u,subdomains:b,slug:e,environment:t,validationMethod:"DNS",hostedZoneId:d?.hostedZoneId});s=T,this.builder.addResource(T,C)}let a="ECSCluster";this.builder.addResource(a,{Type:"AWS::ECS::Cluster",Properties:{ClusterName:`${e}-${t}`,ClusterSettings:[{Name:"containerInsights",Value:"enabled"}],Tags:[{Key:"Name",Value:`${e}-${t}`},{Key:"Environment",Value:t}]}});let l=`${e}${t}ALBSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(l,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ALB security group for ${e}-${t}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:80,ToPort:80,CidrIp:"0.0.0.0/0",Description:"HTTP"},{IpProtocol:"tcp",FromPort:443,ToPort:443,CidrIp:"0.0.0.0/0",Description:"HTTPS"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${e}-${t}-alb-sg`},{Key:"Environment",Value:t}]}});let p=`${e}${t}ECSSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");for(let[u,b]of Object.entries(r)){let C=b.port||3000;this.builder.addResource(p,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ECS tasks security group for ${e}-${t}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:C,ToPort:C,SourceSecurityGroupId:{Ref:l},Description:"Allow traffic from ALB"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${e}-${t}-ecs-sg`},{Key:"Environment",Value:t}]}});let T=`${e}${t}TaskExecRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(T,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-ecs-exec-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"],Policies:[{PolicyName:"ECRPullPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"}]}}]}});let g=`${e}${t}TaskRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(g,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-ecs-task-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"TaskPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:ListBucket"],Resource:"*"}]}}]}});let m=`${e}${t}${u}LogGroup`.replace(/[^a-zA-Z0-9]/g,""),c=`/ecs/${e}-${t}-${u}`;this.builder.addResource(m,{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:c,RetentionInDays:30}});let y=`${e}${t}${u}TaskDef`.replace(/[^a-zA-Z0-9]/g,""),o=String(b.cpu||512),f=String(b.memory||1024);this.builder.addResource(y,{Type:"AWS::ECS::TaskDefinition",Properties:{Family:`${e}-${t}-${u}`,NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:o,Memory:f,ExecutionRoleArn:{"Fn::GetAtt":[T,"Arn"]},TaskRoleArn:{"Fn::GetAtt":[g,"Arn"]},ContainerDefinitions:[{Name:u,Image:{"Fn::Sub":`\${AWS::AccountId}.dkr.ecr.\${AWS::Region}.amazonaws.com/${e}:latest`},Essential:!0,PortMappings:[{ContainerPort:C,Protocol:"tcp"}],LogConfiguration:{LogDriver:"awslogs",Options:{"awslogs-group":c,"awslogs-region":{Ref:"AWS::Region"},"awslogs-stream-prefix":u}},HealthCheck:{Command:["CMD-SHELL",`curl -f http://localhost:${C}${b.healthCheck||"/health"} || exit 1`],Interval:30,Timeout:5,Retries:3,StartPeriod:60}}],Tags:[{Key:"Name",Value:`${e}-${t}-${u}`},{Key:"Environment",Value:t}]},DependsOn:[T,g,m]});let h=`${e}${t}ALB`.replace(/[^a-zA-Z0-9]/g,"");if(n?.enabled!==!1){this.builder.addResource(h,{Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:`${e}-${t}-alb`,Scheme:"internet-facing",Type:"application",Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],SecurityGroups:[{Ref:l}],Tags:[{Key:"Name",Value:`${e}-${t}-alb`},{Key:"Environment",Value:t}]}});let S=`${e}${t}TargetGroup`.replace(/[^a-zA-Z0-9]/g,""),A=n?.healthCheck?.path||b.healthCheck||"/health";this.builder.addResource(S,{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:`${e}-${t}-tg`,Port:C,Protocol:"HTTP",VpcId:{Ref:"VPC"},TargetType:"ip",HealthCheckPath:A,HealthCheckIntervalSeconds:n?.healthCheck?.interval||30,HealthyThresholdCount:n?.healthCheck?.healthyThreshold||2,UnhealthyThresholdCount:n?.healthCheck?.unhealthyThreshold||5,HealthCheckTimeoutSeconds:10,Tags:[{Key:"Name",Value:`${e}-${t}-tg`},{Key:"Environment",Value:t}]}});let R=`${e}${t}HTTPListener`.replace(/[^a-zA-Z0-9]/g,"");if(i?.enabled&&i?.redirectHttp)this.builder.addResource(R,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:h},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"redirect",RedirectConfig:{Protocol:"HTTPS",Port:"443",StatusCode:"HTTP_301"}}]}});else this.builder.addResource(R,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:h},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:S}}]}});if(i?.enabled){let v=i.certificateArn||(s?{Ref:s}:void 0);if(v){let O=`${e}${t}HTTPSListener`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(O,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:h},Port:443,Protocol:"HTTPS",Certificates:[{CertificateArn:v}],DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:S}}],SslPolicy:"ELBSecurityPolicy-TLS13-1-2-2021-06"}})}}let D=`${e}${t}${u}Service`.replace(/[^a-zA-Z0-9]/g,""),I=b.desiredCount||1;this.builder.addResource(D,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${e}-${t}-${u}`,Cluster:{Ref:a},TaskDefinition:{Ref:y},DesiredCount:I,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:p}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},LoadBalancers:[{ContainerName:u,ContainerPort:C,TargetGroupArn:{Ref:S}}],HealthCheckGracePeriodSeconds:120,Tags:[{Key:"Name",Value:`${e}-${t}-${u}`},{Key:"Environment",Value:t}]},DependsOn:[y,R,S]});let P=b.autoScaling;if(P){let v=`${e}${t}${u}ScalableTarget`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(v,{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{MaxCapacity:P.max||10,MinCapacity:P.min||1,ResourceId:{"Fn::Sub":`service/\${${a}}/${e}-${t}-${u}`},ScalableDimension:"ecs:service:DesiredCount",ServiceNamespace:"ecs",RoleARN:{"Fn::Sub":"arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"}},DependsOn:D}),P.targetCpuUtilization)this.builder.addResource(`${e}${t}${u}CPUScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${e}-${t}-${u}-cpu-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:v},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageCPUUtilization"},TargetValue:P.targetCpuUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}});if(P.targetMemoryUtilization)this.builder.addResource(`${e}${t}${u}MemoryScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${e}-${t}-${u}-memory-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:v},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageMemoryUtilization"},TargetValue:P.targetMemoryUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}})}if(d?.domain&&d?.hostedZoneId)this.builder.addResource(`${e}${t}ApiDnsRecord`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:d.hostedZoneId,Name:`api.${d.domain}`,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[h,"DNSName"]},HostedZoneId:{"Fn::GetAtt":[h,"CanonicalHostedZoneID"]}}}});this.builder.addOutput("ECSClusterArn",{Description:"ECS Cluster ARN",Value:{"Fn::GetAtt":[a,"Arn"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-cluster-arn"}}}),this.builder.addOutput("ECSServiceName",{Description:"ECS Service Name",Value:`${e}-${t}-${u}`,Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-service-name"}}}),this.builder.addOutput("LoadBalancerDNS",{Description:"Application Load Balancer DNS Name",Value:{"Fn::GetAtt":[h,"DNSName"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-alb-dns"}}})}else{let S=`${e}${t}${u}Service`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(S,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${e}-${t}-${u}`,Cluster:{Ref:a},TaskDefinition:{Ref:y},DesiredCount:b.desiredCount||1,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:p}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},Tags:[{Key:"Name",Value:`${e}-${t}-${u}`},{Key:"Environment",Value:t}]},DependsOn:[y]})}break}}generateServerless(e,t){if(this.mergedConfig.infrastructure?.functions)for(let[r,n]of Object.entries(this.mergedConfig.infrastructure.functions)){if(!this.shouldDeploy(n))continue;let{role:i,logicalId:d}=De.createRole({slug:e,environment:t,roleName:`${e}-${t}-${r}-role`,servicePrincipal:"lambda.amazonaws.com",managedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]});this.builder.addResource(d,i);let{lambdaFunction:s,logicalId:a}=E.createLambdaFunction({slug:e,environment:t,functionName:`${e}-${t}-${r}`,handler:n.handler||"index.handler",runtime:n.runtime||"nodejs20.x",code:{zipFile:n.code||"export const handler = async () => ({ statusCode: 200 });"},role:d,timeout:n.timeout,memorySize:n.memorySize});this.builder.addResource(a,s)}if(this.mergedConfig.infrastructure?.api){let{restApi:r,logicalId:n}=Ie.createRestApi({slug:e,environment:t,apiName:`${e}-${t}-api`});this.builder.addResource(n,r)}}generateServer(e,t){if(!this.mergedConfig.infrastructure?.servers)return;let r=this.mergedConfig.infrastructure.servers,n=this.mergedConfig.infrastructure?.compute,i=this.mergedConfig.infrastructure?.ssl;if(Object.values(r).some((s)=>!s.privateNetwork||s.privateNetwork==="create"))this.generateNetworkInfrastructure(e,t);for(let[s,a]of Object.entries(r)){let l=a.instanceType||a.size||n?.size,u=(l?E.InstanceSize.specs[l]:void 0)?.instanceType||l||"t3.micro",b=a.type||"app",C=a.userData||a.startupScript;if(!C)C=E.UserData.generateAppServerScript({runtime:"bun",runtimeVersion:a.bunVersion||"latest",webServer:"none",domain:a.domain,enableSsl:!!i?.enabled,sslEmail:i?.letsEncrypt?.email,installRedis:b==="cache",installDatabaseClients:!!a.database});let T=a.privateNetwork&&a.privateNetwork!=="create"?a.privateNetwork:{Ref:"VPC"},g=a.subnet||{Ref:"PublicSubnet1"},c=!!this.mergedConfig.infrastructure?.email?.server?.enabled,y=[22,80,443,this.resolveApiOriginPort()];if(c)y.push(25,465,587,143,993);let o=E.createServerModeStack({slug:`${e}-${s}`,environment:t,vpcId:T,subnetId:g,instanceType:u,keyName:a.keyName||`${e}-${t}`,domain:a.domain,userData:C,volumeSize:a.diskSize||20,imageId:a.image,allowedPorts:y});for(let[f,h]of Object.entries(o.resources))this.builder.addResource(f,h);this.serverEipLogicalIds.set(s,o.outputs.eipLogicalId),this.serverEipLogicalIds.set(`${s}Instance`,o.outputs.instanceLogicalId),this.builder.addOutput(`${s}InstanceId`,{Value:{Ref:o.outputs.instanceLogicalId},Description:`Instance ID for ${s} server`}),this.builder.addOutput(`${s}PublicIp`,{Value:{Ref:o.outputs.eipLogicalId},Description:`Public IP for ${s} server`})}}generateComputeApp(e,t){let r=this.mergedConfig.infrastructure?.compute;if(!r)return;let n=this.mergedConfig.sites||{},i=Object.entries(n),s=this.mergedConfig.infrastructure?.dns?.domain,a=this.mergedConfig.infrastructure?.database,l=r.size,u=(l?E.InstanceSize.specs[l]:void 0)?.instanceType||l||"t3.micro";if(!this.builder.hasResource("VPC"))this.generateNetworkInfrastructure(e,t);let b=this.buildCaddyfile(i),C=E.UserData.generateBunAppScript({runtime:r.runtime||"bun",runtimeVersion:r.runtimeVersion||"latest",systemPackages:r.systemPackages,database:a,caddyfile:b}),T=ve(r.appUpdates),g=T.length>0?`${C}
11
11
  ${T.join(`
12
12
  `)}
13
- `:A,m=o.map(([,S])=>S.port).filter((S)=>typeof S==="number"&&![80,443].includes(S)),a=this.resolveApiOriginPort(),y=`${e}${t}DeployBucket`.replace(/[^a-zA-Z0-9]/g,""),i=`${e}-${t}-deploy`;this.builder.addResource(y,{Type:"AWS::S3::Bucket",Properties:{BucketName:i,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"expire-old-releases",Status:"Enabled",ExpirationInDays:7,Prefix:"releases/"}]},Tags:[{Key:"Project",Value:e},{Key:"Environment",Value:t},{Key:"ManagedBy",Value:"ts-cloud"}]}});let p=w.createServerModeStack({slug:`${e}-app`,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},instanceType:d,keyName:r.allowSsh?`${e}-${t}`:void 0,domain:c,userData:g,volumeSize:r.disk?.size||20,imageId:r.image,allowedPorts:[...r.allowSsh?[22]:[],80,443,a,...m]}),f=p.resources[p.outputs.instanceLogicalId];if(f?.Properties){let S=f.Properties.Tags||[];f.Properties.Tags=[...S,{Key:"Project",Value:e},{Key:"Environment",Value:t},{Key:"Role",Value:"app"},{Key:"ManagedBy",Value:"ts-cloud"}]}let C=p.resources[p.outputs.roleLogicalId];if(C?.Properties)C.Properties.Policies=C.Properties.Policies||[],C.Properties.Policies.push({PolicyName:"DeployBucketRead",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:GetObject","s3:ListBucket"],Resource:[`arn:aws:s3:::${i}`,`arn:aws:s3:::${i}/*`]}]}});for(let[S,R]of Object.entries(p.resources))this.builder.addResource(S,R);this.builder.addOutput("deployBucketName",{Value:{Ref:y},Description:"S3 bucket where release tarballs are uploaded"}),this.builder.addOutput("appInstanceId",{Value:{Ref:p.outputs.instanceLogicalId},Description:"EC2 instance ID for the app server"}),this.builder.addOutput("appPublicIp",{Value:{Ref:p.outputs.eipLogicalId},Description:"Public IP for the app server"}),this.serverEipLogicalIds.set("app",p.outputs.eipLogicalId),this.serverEipLogicalIds.set("appInstance",p.outputs.instanceLogicalId)}generateJumpBox(e,t){let r=this.mergedConfig.infrastructure?.jumpBox;if(!r)return;let n=r===!0?{}:r;if(n.enabled===!1)return;this.generateNetworkInfrastructure(e,t);let o=n.size||"micro",c=w.InstanceSize.specs[o]?.instanceType||o||"t3.micro",s;if(n.mountEfs)s={fileSystemId:typeof n.mountEfs==="string"?n.mountEfs:{Ref:"FileSystem"},mountPath:n.mountPath||"/mnt/efs"};let u;if(n.databaseTools)u=w.JumpBox.withDatabaseTools({slug:e,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:n.keyName||`${e}-${t}`,allowedCidrs:n.allowedCidrs});else if(s)u=w.JumpBox.withEfsMount({slug:e,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:n.keyName||`${e}-${t}`,fileSystemId:s.fileSystemId,mountPath:s.mountPath,allowedCidrs:n.allowedCidrs});else u=w.createJumpBox({slug:e,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:n.keyName||`${e}-${t}`,instanceType:c,allowedCidrs:n.allowedCidrs,mountEfs:s});for(let[h,d]of Object.entries(u.resources))this.builder.addResource(h,d);this.builder.addOutput("JumpBoxInstanceId",{Value:{Ref:u.instanceLogicalId},Description:"The ID of the JumpBox EC2 instance (use with SSM Session Manager or SSH)"})}generateSharedInfrastructure(e,t){let r=this.mergedConfig.infrastructure?.ssl,n=this.mergedConfig.infrastructure?.dns,o=n?.domain,l=n?.hostedZoneId,c=[],s,u;if(r?.certificateArn)u=r.certificateArn;else if(r?.enabled&&o&&l){let m=r.domains||[o],a=m[0],y=m.slice(1).map((f)=>{if(f.includes(".")&&f.endsWith(a))return f.replace(`.${a}`,"");return f}),{certificate:i,logicalId:p}=te.createCertificate({domain:a,subdomains:y,slug:e,environment:t,validationMethod:"DNS",hostedZoneId:l});s=p,this.builder.addResource(p,i)}if(this.mergedConfig.infrastructure?.storage){let m=Object.entries(this.mergedConfig.infrastructure.storage).some(([,i])=>i.website),a;if(m&&(s||u))a=`${e}${t}CloudFrontOAC`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(a,{Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${e}-${t}-s3-oac`,Description:`OAC for ${e} ${t} S3 website buckets`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}});let y=Object.entries(this.mergedConfig.infrastructure.storage).map(([i,p])=>({name:i,config:p,mountPath:this.normalizeMountPath(p),rewriteStyle:p.pathRewriteStyle||"directory",logicalId:this.storageBucketLogicalId(e,t,i)})).filter((i)=>i.name!=="public"&&i.config.website&&i.mountPath);for(let[i,p]of Object.entries(this.mergedConfig.infrastructure.storage)){let f=!!(p.website&&a),C=this.storageBucketName(e,t,i),{bucket:S,logicalId:R}=ee.createBucket({slug:e,name:i,environment:t,bucketName:C,versioning:p.versioning,encryption:p.encryption,public:f?!1:p.public});if(f&&S.Properties)S.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1};if(this.builder.addResource(R,S),p.website){let D=typeof p.website==="object"?p.website:{},P=ee.enableWebsiteHosting(S,D.indexDocument||"index.html",D.errorDocument);this.builder.addResource(R,P)}let I=this.normalizeMountPath(p);if(f&&a&&o&&!(I&&i!=="public")){let D=`${e}${t}${i}CDN`.replace(/[^a-zA-Z0-9]/g,""),P=[];if(p.aliases&&p.aliases.length>0)P.push(...p.aliases);else if(i==="public"){if(P.push(o),r?.domains?.includes(`www.${o}`))P.push(`www.${o}`)}else if(i==="docs")P.push(`docs.${o}`);else if(i==="blog")P.push(`blog.${o}`);let v=typeof p.website==="object"?p.website:{},O=p.spa===!0,F=v.errorDocument||(O?"index.html":"404.html"),V=[];if(O)V.push({ErrorCode:403,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300});else V.push({ErrorCode:403,ResponseCode:404,ResponsePagePath:`/${F}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${F}`,ErrorCachingMinTTL:300});let z=u&&P.length>0?{AcmCertificateArn:u,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:s&&P.length>0?{AcmCertificateArn:{Ref:s},SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},_=`S3-${e}-${t}-${i}`,k=this.mergedConfig.project.region||"us-east-1",x;if(!O)x=`${e}${t}${i}UrlRewrite`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(x,{Type:"AWS::CloudFront::Function",Properties:{Name:`${e}-${t}-${i}-url-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`URL rewrite for ${e} ${t} ${i} - appends .html to extensionless paths`,Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) { var request = event.request; var uri = request.uri; if (uri.endsWith('/')) { request.uri += 'index.html'; }
14
- else if (!uri.includes('.')) { request.uri += '.html'; } return request; }`}});let Y=[{Id:_,DomainName:{"Fn::Sub":`\${${R}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:a}}],G=[],Q=[];if(this.shouldRouteStorageBucketToCompute(i,p)){this.appendComputeAppOrigin(Y,G,Q,e,t,this.resolveComputeCachePathPatterns(p.computeRoutes));for(let E of y){let U=`S3-${e}-${t}-${E.name}`,X=`${e}${t}${E.name}PathMountRewrite`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(X,{Type:"AWS::CloudFront::Function",Properties:{Name:`${e}-${t}-${E.name}-path-mount-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`Path mount rewrite for ${e} ${t} ${E.name} at ${E.mountPath}`,Runtime:"cloudfront-js-2.0"},FunctionCode:this.pathMountRewriteFunctionCode(E.mountPath,E.rewriteStyle)}}),Y.push({Id:U,DomainName:{"Fn::Sub":`\${${E.logicalId}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:a}}),Q.push(E.logicalId,X);for(let Ve of[E.mountPath,`${E.mountPath}/*`])G.push({PathPattern:Ve,TargetOriginId:U,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[X,"FunctionARN"]}}]})}}let me={Type:"AWS::CloudFront::Distribution",DependsOn:[R,a,...x?[x]:[],...Q],Properties:{DistributionConfig:{Enabled:!0,Comment:`${e} ${t} ${i} site`,DefaultRootObject:"index.html",Origins:Y,DefaultCacheBehavior:{TargetOriginId:_,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",...x?{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[x,"FunctionARN"]}}]}:{}},...G.length>0?{CacheBehaviors:G}:{},...P.length>0?{Aliases:P}:{},ViewerCertificate:z,PriceClass:"PriceClass_100",HttpVersion:"http2and3",IPV6Enabled:!0,CustomErrorResponses:V}}};if(s)me.DependsOn.push(s);this.builder.addResource(D,me);let Fe=`${R}CloudFrontPolicy`;if(this.builder.addResource(Fe,{Type:"AWS::S3::BucketPolicy",DependsOn:[R,D],Properties:{Bucket:{Ref:R},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${R}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${D}}`}}}}]}}}),this.shouldRouteStorageBucketToCompute(i,p))for(let E of y){let U=`${E.logicalId}CloudFrontPolicy`;this.builder.addResource(U,{Type:"AWS::S3::BucketPolicy",DependsOn:[E.logicalId,D],Properties:{Bucket:{Ref:E.logicalId},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${E.logicalId}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${D}}`}}}}]}}})}if(P.length>0)c.push({name:i,bucketLogicalId:R,distLogicalId:D,oacLogicalId:a,aliases:P});this.builder.addOutput(`${i}CloudFrontDomain`,{Value:{"Fn::GetAtt":[D,"DomainName"]},Description:`CloudFront domain for ${i}`}),this.builder.addOutput(`${i}CloudFrontDistributionId`,{Value:{Ref:D},Description:`CloudFront distribution ID for ${i}`})}if(this.builder.addOutput(`${i}BucketName`,{Value:{Ref:R},Description:`S3 bucket name for ${i}`}),i==="public")this.builder.addOutput("FrontendBucketName",{Value:{Ref:R},Description:"Frontend S3 bucket name"});if(i==="docs")this.builder.addOutput("DocsBucketName",{Value:{Ref:R},Description:"Documentation S3 bucket name"});if(i==="blog")this.builder.addOutput("BlogBucketName",{Value:{Ref:R},Description:"Blog S3 bucket name"})}}if(this.mergedConfig.infrastructure?.sftp){let m=this.mergedConfig.infrastructure.sftp,a=Te.create({...m,storage:this.resolveSftpStorage(m,e,t)??m.storage,slug:e,environment:t});for(let[y,i]of Object.entries(a.resources))this.builder.addResource(y,i);this.builder.addOutput("SftpServerId",{Value:{Ref:a.serverLogicalId},Description:"AWS Transfer Family SFTP server ID"}),this.builder.addOutput("SftpEndpoint",{Value:{"Fn::Sub":`\${${a.serverLogicalId}}.server.transfer.\${AWS::Region}.amazonaws.com`},Description:"AWS Transfer Family SFTP endpoint"}),this.builder.addOutput("SftpStorageDomain",{Value:a.domain,Description:"Storage backing the SFTP server (EFS or S3)"})}if(l&&c.length>0)for(let{name:m,distLogicalId:a,aliases:y}of c)for(let i of y){let p=i.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${p}ARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[a],Properties:{HostedZoneId:l,Name:i,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[a,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}}),this.builder.addResource(`${p}AAAARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[a],Properties:{HostedZoneId:l,Name:i,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":[a,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}})}if(this.mergedConfig.infrastructure?.databases){for(let[m,a]of Object.entries(this.mergedConfig.infrastructure.databases))if(a.engine==="dynamodb"){let{table:y,logicalId:i}=q.createTable({slug:e,environment:t,tableName:`${e}-${t}-${m}`,partitionKey:a.partitionKey||{name:"id",type:"S"},sortKey:a.sortKey});this.builder.addResource(i,y)}else if(a.engine==="postgres"){let{dbInstance:y,logicalId:i}=q.createPostgres({slug:e,environment:t,dbInstanceIdentifier:`${e}-${t}-${m}`,masterUsername:a.username||"admin",masterUserPassword:a.password||"changeme123",allocatedStorage:a.storage||20,dbInstanceClass:a.instanceClass||"db.t3.micro"});this.builder.addResource(i,y)}else if(a.engine==="mysql"){let{dbInstance:y,logicalId:i}=q.createMysql({slug:e,environment:t,dbInstanceIdentifier:`${e}-${t}-${m}`,masterUsername:a.username||"admin",masterUserPassword:a.password||"changeme123",allocatedStorage:a.storage||20,dbInstanceClass:a.instanceClass||"db.t3.micro"});this.builder.addResource(i,y)}}if(this.mergedConfig.infrastructure?.cdn)for(let[m,a]of Object.entries(this.mergedConfig.infrastructure.cdn)){if(!a.origin)continue;let y=typeof a.customDomain==="string"?a.customDomain:a.customDomain?.domain||a.domain,i=typeof a.customDomain==="object"?a.customDomain?.certificateArn:a.certificateArn,p=i||u,f=`${e}${t}${m}CDN`.replace(/[^a-zA-Z0-9]/g,""),C=`S3-${e}-${t}-${m}-cdn`,S=[{Id:C,DomainName:a.origin,OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginShield:a.originShield?{Enabled:!0,OriginShieldRegion:a.originShieldRegion||this.mergedConfig.environments[t]?.region||this.mergedConfig.project.region||"us-east-1"}:{Enabled:!1}}],R=[],I=[];if(a.routeCompute)this.appendComputeAppOrigin(S,R,I,e,t,this.resolveComputeCachePathPatterns(a.computeRoutes));let D=p&&y?{AcmCertificateArn:s&&!i?{Ref:s}:p,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},P=[...I];if(s&&!i&&y)P.push(s);let v={Type:"AWS::CloudFront::Distribution",...P.length>0?{DependsOn:P}:{},Properties:{DistributionConfig:{Enabled:!0,Comment:`${e} ${t} ${m} CDN`,DefaultRootObject:"index.html",Origins:S,DefaultCacheBehavior:{TargetOriginId:C,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:a.compress!==!1,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"},...R.length>0?{CacheBehaviors:R}:{},...y&&p?{Aliases:[y]}:{},ViewerCertificate:D,PriceClass:"PriceClass_100",HttpVersion:a.http3?"http2and3":"http2"}}};if(this.builder.addResource(f,v),l&&y&&p){let O=y.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${O}CdnARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[f,...s&&!i?[s]:[]],Properties:{HostedZoneId:l,Name:y,Type:"A",AliasTarget:{HostedZoneId:"Z2FDTNDATAQYW2",DNSName:{"Fn::GetAtt":[f,"DomainName"]}}}})}}if(this.mergedConfig.infrastructure?.queues)for(let[m,a]of Object.entries(this.mergedConfig.infrastructure.queues)){if(!this.shouldDeploy(a))continue;let{queue:y,logicalId:i}=re.createQueue({slug:e,environment:t,name:`${e}-${t}-${m}`,fifo:a.fifo,visibilityTimeout:a.visibilityTimeout,messageRetentionPeriod:a.messageRetentionPeriod,delaySeconds:a.delaySeconds,maxMessageSize:a.maxMessageSize,receiveMessageWaitTime:a.receiveMessageWaitTime,contentBasedDeduplication:a.contentBasedDeduplication,encrypted:a.encrypted,kmsKeyId:a.kmsKeyId});this.builder.addResource(i,y);let p;if(a.deadLetterQueue){let{deadLetterQueue:f,updatedSourceQueue:C,deadLetterLogicalId:S}=re.createDeadLetterQueue(i,{slug:e,environment:t,maxReceiveCount:a.maxReceiveCount});p=S,this.builder.addResource(S,f);let I=this.builder.getResources()[i];if(I?.Properties)I.Properties.RedrivePolicy=C.Properties?.RedrivePolicy}if(a.trigger){let f=a.trigger,C=`${e}${t}${f.functionName}`.replace(/[^a-zA-Z0-9]/g,""),S={Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:{"Fn::GetAtt":[i,"Arn"]},FunctionName:{Ref:C},BatchSize:f.batchSize||10,MaximumBatchingWindowInSeconds:f.batchWindow||0,Enabled:!0,...f.reportBatchItemFailures!==!1&&{FunctionResponseTypes:["ReportBatchItemFailures"]},...f.maxConcurrency&&{ScalingConfig:{MaximumConcurrency:f.maxConcurrency}},...f.filterPattern&&{FilterCriteria:{Filters:[{Pattern:JSON.stringify(f.filterPattern)}]}}},DependsOn:[i,C]};this.builder.addResource(`${i}Trigger`,S)}if(a.alarms?.enabled){let f=a.alarms,C=f.notificationTopicArn;if(!C&&f.notificationEmails?.length){let I=`${i}AlarmTopic`;this.builder.addResource(I,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-${m}-alarms`,DisplayName:`${m} Queue Alarms`}}),f.notificationEmails.forEach((D,P)=>{this.builder.addResource(`${I}Sub${P}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:I},Protocol:"email",Endpoint:D}})}),C={Ref:I}}let S=f.queueDepthThreshold||1000;this.builder.addResource(`${i}DepthAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-${m}-queue-depth`,AlarmDescription:`Queue ${m} depth exceeds ${S} messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:S,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[i,"QueueName"]}}],...C&&{AlarmActions:[C],OKActions:[C]}}});let R=f.messageAgeThreshold||3600;if(this.builder.addResource(`${i}AgeAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-${m}-message-age`,AlarmDescription:`Queue ${m} oldest message exceeds ${R} seconds`,MetricName:"ApproximateAgeOfOldestMessage",Namespace:"AWS/SQS",Statistic:"Maximum",Period:300,EvaluationPeriods:2,Threshold:R,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[i,"QueueName"]}}],...C&&{AlarmActions:[C],OKActions:[C]}}}),p&&f.dlqAlarm!==!1)this.builder.addResource(`${p}Alarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-${m}-dlq-messages`,AlarmDescription:`Dead letter queue for ${m} has messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Sum",Period:300,EvaluationPeriods:1,Threshold:0,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[p,"QueueName"]}}],...C&&{AlarmActions:[C]}}})}if(a.subscribe){let f=a.subscribe,C=f.topicArn;if(!C&&f.topicName)C={Ref:f.topicName};if(C){this.builder.addResource(`${i}SnsPolicy`,{Type:"AWS::SQS::QueuePolicy",Properties:{Queues:[{Ref:i}],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"sns.amazonaws.com"},Action:"sqs:SendMessage",Resource:{"Fn::GetAtt":[i,"Arn"]},Condition:{ArnEquals:{"aws:SourceArn":C}}}]}}});let S={TopicArn:C,Protocol:"sqs",Endpoint:{"Fn::GetAtt":[i,"Arn"]},RawMessageDelivery:f.rawMessageDelivery||!1};if(f.filterPolicy)S.FilterPolicy=f.filterPolicy,S.FilterPolicyScope=f.filterPolicyScope||"MessageAttributes";this.builder.addResource(`${i}SnsSub`,{Type:"AWS::SNS::Subscription",Properties:S,DependsOn:`${i}SnsPolicy`})}}}if(this.mergedConfig.infrastructure?.realtime?.enabled)if((this.mergedConfig.infrastructure.realtime.mode||"serverless")==="server")this.generateRealtimeServerResources(e,t);else this.generateRealtimeResources(e,t);let h=this.mergedConfig.infrastructure?.redirects;if(h){let m=h.target||this.mergedConfig.infrastructure?.dns?.domain||"",a=h.protocol||"https";if(h.domains?.length&&m)for(let y of h.domains){let{bucket:i,bucketPolicy:p,logicalId:f,policyLogicalId:C}=Z.createDomainRedirectBucket({slug:e,environment:t,sourceDomain:y,targetDomain:m,protocol:a});this.builder.addResource(f,i),this.builder.addResource(C,p)}if(h.paths&&Object.keys(h.paths).length>0){let y=Z.fromMapping(h.paths,{statusCode:h.statusCode||301}),{function:i,logicalId:p}=Z.createPathRedirectFunction({slug:e,environment:t,rules:y});this.builder.addResource(p,i)}}if(this.mergedConfig.infrastructure?.monitoring?.alarms)for(let[m,a]of Object.entries(this.mergedConfig.infrastructure.monitoring.alarms)){let{alarm:y,logicalId:i}=Ie.createAlarm({slug:e,environment:t,alarmName:`${e}-${t}-${m}`,metricName:a.metricName||"Errors",namespace:a.namespace||"AWS/Lambda",threshold:a.threshold||1,comparisonOperator:a.comparisonOperator||"GreaterThanThreshold"});this.builder.addResource(i,y)}let d=this.mergedConfig.infrastructure?.cache;if(d){let m=d.type||"redis";if(m==="redis"){this.generateNetworkInfrastructure(e,t);let a=d.redis||{},{replicationGroup:y,subnetGroup:i,logicalId:p,subnetGroupId:f}=ne.createRedis({slug:e,environment:t,nodeType:a.nodeType||d.nodeType||"cache.t3.micro",engineVersion:a.engineVersion||"7.1",port:a.port||6379,numCacheClusters:a.numCacheNodes||2,automaticFailover:a.automaticFailoverEnabled!==!1,atRestEncryption:!0,transitEncryption:!0,snapshotRetentionDays:a.snapshotRetentionLimit||7,snapshotWindow:a.snapshotWindow,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(p,y),i&&f)this.builder.addResource(f,i);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[p,"PrimaryEndPoint.Address"]},Description:"Redis primary endpoint address"}),this.builder.addOutput("CachePort",{Value:{"Fn::GetAtt":[p,"PrimaryEndPoint.Port"]},Description:"Redis primary endpoint port"})}else if(m==="memcached"){this.generateNetworkInfrastructure(e,t);let a=d.elasticache||{},{cluster:y,subnetGroup:i,logicalId:p,subnetGroupId:f}=ne.createMemcached({slug:e,environment:t,nodeType:a.nodeType||d.nodeType||"cache.t3.micro",engineVersion:a.engineVersion||"1.6.22",numCacheNodes:a.numCacheNodes||2,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(p,y),i&&f)this.builder.addResource(f,i);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[p,"ConfigurationEndpoint.Address"]},Description:"Memcached configuration endpoint address"})}}let b=this.mergedConfig.infrastructure?.email;if(b){let m=b.domain||this.mergedConfig.infrastructure?.dns?.domain;if(m){let{emailIdentity:a,logicalId:y}=L.verifyDomain({domain:m,slug:e,environment:t,enableDkim:b.enableDkim!==!1,dkimKeyLength:b.dkimKeyLength||"RSA_2048_BIT"});if(this.builder.addResource(y,a),b.configurationSet!==!1){let{configurationSet:f,logicalId:C}=L.createConfigurationSet({slug:e,environment:t});this.builder.addResource(C,f)}let i=b.hostedZoneId||this.mergedConfig.infrastructure?.dns?.hostedZoneId;if(i){if(b.enableDkim!==!1)for(let I=1;I<=3;I++){let D=`DkimRecord${I}${m.replace(/\./g,"")}`;this.builder.addResource(D,{Type:"AWS::Route53::RecordSet",DependsOn:[y],Properties:{HostedZoneId:i,Name:{"Fn::GetAtt":[y,`DkimDNSTokenName${I}`]},Type:"CNAME",TTL:1800,ResourceRecords:[{"Fn::GetAtt":[y,`DkimDNSTokenValue${I}`]}]}})}let{record:f,logicalId:C}=L.createSpfRecord(m,i);this.builder.addResource(C,f);let{record:S,logicalId:R}=L.createDmarcRecord(m,i,{policy:"none",reportingEmail:b.dmarcReportingEmail||`dmarc-reports@${m}`});this.builder.addResource(R,S)}this.builder.addOutput("EmailDomain",{Value:m,Description:"SES verified email domain"});let p=b.server;if(p?.enabled&&i){let f=this.mergedConfig.environments[t]?.region||this.mergedConfig.project.region||"us-east-1",C=`${e}-${t}-email`,{role:S,policy:R,roleLogicalId:I,policyLogicalId:D}=L.createEmailLambdaRole({slug:e,environment:t,s3BucketArn:`arn:aws:s3:::${C}`,sesIdentityArn:`arn:aws:ses:${f}:*:identity/${m}`});this.builder.addResource(I,S),this.builder.addResource(D,R);let{function:P,permission:v,logicalId:O,permissionLogicalId:F}=L.createInboundEmailLambda({slug:e,environment:t,roleArn:{"Fn::GetAtt":[I,"Arn"]},s3BucketName:C,organizedPrefix:"mailboxes/"});this.builder.addResource(O,P),this.builder.addResource(F,v);let V=L.createInboundEmailSetup({slug:e,environment:t,domain:m,s3BucketName:C,s3KeyPrefix:"inbox/",region:f,hostedZoneId:i,lambdaFunctionArn:{"Fn::GetAtt":[O,"Arn"]}});for(let[_,k]of Object.entries(V.resources)){if(k.Type==="AWS::SES::ReceiptRule")k.DependsOn=[F,O];this.builder.addResource(_,k)}this.builder.addOutput("InboundEmailLambda",{Value:{Ref:O},Description:"Inbound email processing Lambda function"}),this.builder.addOutput("EmailBucket",{Value:C,Description:"S3 bucket for email storage"});let z=this.serverEipLogicalIds.get("app");if(z&&i){let k=`${p?.subdomain||"mail"}.${m}`,x=k.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${x}ARecord`,{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:i,Name:k,Type:"A",TTL:"300",ResourceRecords:[{Ref:z}]}})}this.builder.addOutput("MailHost",{Value:`mail.${m}`,Description:"Mail server hostname for SMTP/IMAP clients"})}}}let A=this.mergedConfig.infrastructure?.search;if(A){let m=A.vpc?{subnetIds:[{Ref:"PublicSubnet1"}],securityGroupIds:[]}:void 0;if(m)this.generateNetworkInfrastructure(e,t);let{domain:a,logicalId:y}=De.createDomain({slug:e,environment:t,engineVersion:A.engineVersion||"OpenSearch_2.11",instanceType:A.instanceType||"t3.small.search",instanceCount:A.instanceCount||1,volumeSize:A.volumeSize||10,volumeType:A.volumeType||"gp3",dedicatedMaster:A.dedicatedMaster||!1,dedicatedMasterType:A.dedicatedMasterType,dedicatedMasterCount:A.dedicatedMasterCount||3,multiAz:A.multiAz||!1,encryption:A.encryption||{atRest:!0,nodeToNode:!0},advancedSecurity:A.advancedSecurity,autoTune:A.autoTune!==!1,vpc:m});this.builder.addResource(y,a),this.builder.addOutput("SearchDomainEndpoint",{Value:{"Fn::GetAtt":[y,"DomainEndpoint"]},Description:"OpenSearch domain endpoint"}),this.builder.addOutput("SearchDomainArn",{Value:{"Fn::GetAtt":[y,"Arn"]},Description:"OpenSearch domain ARN"})}let T=this.mergedConfig.infrastructure?.fileSystem;if(T&&Object.keys(T).length>0){this.generateNetworkInfrastructure(e,t);for(let[m,a]of Object.entries(T)){let{fileSystem:y,logicalId:i}=K.createFileSystem({slug:`${e}-${m}`,environment:t,encrypted:a.encrypted!==!1,performanceMode:a.performanceMode||"generalPurpose",throughputMode:a.throughputMode||"bursting",enableBackup:!0});this.builder.addResource(i,y);let{securityGroup:p,logicalId:f}=K.createEfsSecurityGroup({slug:`${e}-${m}`,environment:t,vpcId:{Ref:"VPC"},sourceCidrBlocks:["10.0.0.0/16"]});this.builder.addResource(f,p);let{mountTargets:C,logicalIds:S}=K.createMultiAzMountTargets(i,{slug:`${e}-${m}`,environment:t,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],securityGroupId:{Ref:f}});for(let R=0;R<C.length;R++)this.builder.addResource(S[R],C[R]);this.builder.addOutput(`${m}FileSystemId`,{Value:{Ref:i},Description:`EFS file system ID for ${m}`})}}let g=this.mergedConfig.infrastructure?.ai;if(g){let m=g.service||"ecs",a=g.models||["*"],y=g.allowStreaming!==!1,i;if(m==="ecs")i=M.enableBedrockForEcs({slug:e,environment:t,models:a,allowStreaming:y});else if(m==="ec2")i=M.enableBedrockForEc2({slug:e,environment:t,models:a,allowStreaming:y});else if(m==="lambda")i=M.enableBedrockForLambda({slug:e,environment:t,models:a,allowStreaming:y});else i=M.createBedrockRole(m,{slug:e,environment:t,models:a,allowStreaming:y});if(this.builder.addResource(i.logicalId,i.role),g.allowAsync){let{policy:p,logicalId:f}=M.createBedrockPolicy({slug:e,environment:t,models:a,allowStreaming:y,allowAsync:!0});this.builder.addResource(f,p)}this.builder.addOutput("BedrockRoleArn",{Value:{"Fn::GetAtt":[i.logicalId,"Arn"]},Description:"IAM role ARN with Bedrock permissions"})}}generateRealtimeResources(e,t){let r=this.mergedConfig.infrastructure?.realtime;if(!r)return;let n=r.name||`${e}-${t}-realtime`,o=r.scaling||{},l=r.storage||{type:"dynamodb"},c=o.handlerMemory||256,s=o.handlerTimeout||30,u=`${e}${t}RealtimeConnections`.replace(/[^a-zA-Z0-9]/g,""),h=`${e}${t}RealtimeChannels`.replace(/[^a-zA-Z0-9]/g,"");if(l.type==="dynamodb"){let S=l.dynamodb||{},R=S.billingMode||"PAY_PER_REQUEST";this.builder.addResource(u,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${e}-${t}-realtime-connections`,BillingMode:R,AttributeDefinitions:[{AttributeName:"connectionId",AttributeType:"S"},{AttributeName:"userId",AttributeType:"S"}],KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],GlobalSecondaryIndexes:[{IndexName:"userId-index",KeySchema:[{AttributeName:"userId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:S.readCapacity||5,WriteCapacityUnits:S.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:S.readCapacity||5,WriteCapacityUnits:S.writeCapacity||5}},...S.pointInTimeRecovery&&{PointInTimeRecoverySpecification:{PointInTimeRecoveryEnabled:!0}},Tags:[{Key:"Name",Value:`${e}-${t}-realtime-connections`},{Key:"Environment",Value:t}]}}),this.builder.addResource(h,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${e}-${t}-realtime-channels`,BillingMode:R,AttributeDefinitions:[{AttributeName:"channel",AttributeType:"S"},{AttributeName:"connectionId",AttributeType:"S"}],KeySchema:[{AttributeName:"channel",KeyType:"HASH"},{AttributeName:"connectionId",KeyType:"RANGE"}],GlobalSecondaryIndexes:[{IndexName:"connectionId-index",KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:S.readCapacity||5,WriteCapacityUnits:S.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:S.readCapacity||5,WriteCapacityUnits:S.writeCapacity||5}},Tags:[{Key:"Name",Value:`${e}-${t}-realtime-channels`},{Key:"Environment",Value:t}]}})}let d=`${e}${t}RealtimeRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(d,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-realtime-handler-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:"RealtimeHandlerPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:GetItem","dynamodb:PutItem","dynamodb:DeleteItem","dynamodb:Query","dynamodb:Scan","dynamodb:UpdateItem"],Resource:[{"Fn::GetAtt":[u,"Arn"]},{"Fn::Sub":`\${${u}.Arn}/index/*`},{"Fn::GetAtt":[h,"Arn"]},{"Fn::Sub":`\${${h}.Arn}/index/*`}]},{Effect:"Allow",Action:"execute-api:ManageConnections",Resource:{"Fn::Sub":"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*"}}]}}]}});let b=`${e}${t}RealtimeConnect`.replace(/[^a-zA-Z0-9]/g,""),A=`${e}${t}RealtimeDisconnect`.replace(/[^a-zA-Z0-9]/g,""),T=`${e}${t}RealtimeMessage`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(b,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${e}-${t}-realtime-connect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[d,"Arn"]},MemorySize:c,Timeout:s,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:u},CHANNELS_TABLE:{Ref:h},ENVIRONMENT:t}},Code:{ZipFile:this.generateConnectHandlerCode()}},DependsOn:[d,u]}),this.builder.addResource(A,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${e}-${t}-realtime-disconnect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[d,"Arn"]},MemorySize:c,Timeout:s,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:u},CHANNELS_TABLE:{Ref:h},ENVIRONMENT:t}},Code:{ZipFile:this.generateDisconnectHandlerCode()}},DependsOn:[d,u,h]}),this.builder.addResource(T,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${e}-${t}-realtime-message`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[d,"Arn"]},MemorySize:c,Timeout:s,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:u},CHANNELS_TABLE:{Ref:h},ENVIRONMENT:t}},Code:{ZipFile:this.generateMessageHandlerCode()}},DependsOn:[d,u,h]});let g=`${e}${t}RealtimeApi`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(g,{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:n,ProtocolType:"WEBSOCKET",RouteSelectionExpression:"$request.body.action",Tags:{Name:n,Environment:t}}});let m=`${b}Permission`,a=`${A}Permission`,y=`${T}Permission`;this.builder.addResource(m,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:b},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${g}}/*/$connect`}}}),this.builder.addResource(a,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:A},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${g}}/*/$disconnect`}}}),this.builder.addResource(y,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:T},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${g}}/*/$default`}}});let i=`${g}ConnectInteg`,p=`${g}DisconnectInteg`,f=`${g}MessageInteg`;this.builder.addResource(i,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:g},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${b}.Arn}/invocations`}}}),this.builder.addResource(p,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:g},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${A}.Arn}/invocations`}}}),this.builder.addResource(f,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:g},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${T}.Arn}/invocations`}}}),this.builder.addResource(`${g}ConnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:g},RouteKey:"$connect",AuthorizationType:"NONE",Target:{"Fn::Sub":`integrations/\${${i}}`}}}),this.builder.addResource(`${g}DisconnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:g},RouteKey:"$disconnect",Target:{"Fn::Sub":`integrations/\${${p}}`}}}),this.builder.addResource(`${g}DefaultRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:g},RouteKey:"$default",Target:{"Fn::Sub":`integrations/\${${f}}`}}});let C=`${g}Stage`;if(this.builder.addResource(C,{Type:"AWS::ApiGatewayV2::Stage",Properties:{ApiId:{Ref:g},StageName:t,AutoDeploy:!0,DefaultRouteSettings:{ThrottlingBurstLimit:o.messagesPerSecond||1000,ThrottlingRateLimit:o.messagesPerSecond||1000}}}),r.monitoring?.enabled){let S=r.monitoring,R=S.notificationTopicArn;if(!R&&S.notificationEmails?.length){let I=`${g}AlarmTopic`;this.builder.addResource(I,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-realtime-alarms`,DisplayName:"Realtime WebSocket Alarms"}}),S.notificationEmails.forEach((D,P)=>{this.builder.addResource(`${I}Sub${P}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:I},Protocol:"email",Endpoint:D}})}),R={Ref:I}}if(S.connectionThreshold)this.builder.addResource(`${g}ConnectionAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-connections`,AlarmDescription:`WebSocket connections exceed ${S.connectionThreshold}`,MetricName:"ConnectCount",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:300,EvaluationPeriods:2,Threshold:S.connectionThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:g}}],...R&&{AlarmActions:[R]}}});if(S.errorThreshold)this.builder.addResource(`${g}ErrorAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-errors`,AlarmDescription:`WebSocket errors exceed ${S.errorThreshold}/min`,MetricName:"ExecutionError",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:60,EvaluationPeriods:3,Threshold:S.errorThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:g}}],...R&&{AlarmActions:[R]}}})}this.builder.addOutput(`${g}Endpoint`,{Description:"WebSocket API endpoint URL",Value:{"Fn::Sub":`wss://\${${g}}.execute-api.\${AWS::Region}.amazonaws.com/${t}`},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-endpoint"}}}),this.builder.addOutput(`${g}Id`,{Description:"WebSocket API ID",Value:{Ref:g},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-api-id"}}})}generateConnectHandlerCode(){return`
13
+ `:C,m=i.map(([,A])=>A.port).filter((A)=>typeof A==="number"&&![80,443].includes(A)),c=this.resolveApiOriginPort(),y=`${e}${t}DeployBucket`.replace(/[^a-zA-Z0-9]/g,""),o=`${e}-${t}-deploy`;this.builder.addResource(y,{Type:"AWS::S3::Bucket",Properties:{BucketName:o,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"expire-old-releases",Status:"Enabled",ExpirationInDays:7,Prefix:"releases/"}]},Tags:[{Key:"Project",Value:e},{Key:"Environment",Value:t},{Key:"ManagedBy",Value:"ts-cloud"}]}});let f=E.createServerModeStack({slug:`${e}-app`,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},instanceType:u,keyName:r.allowSsh?`${e}-${t}`:void 0,domain:s,userData:g,volumeSize:r.disk?.size||20,imageId:r.image,allowedPorts:[...r.allowSsh?[22]:[],80,443,c,...m]}),h=f.resources[f.outputs.instanceLogicalId];if(h?.Properties){let A=h.Properties.Tags||[];h.Properties.Tags=[...A,{Key:"Project",Value:e},{Key:"Environment",Value:t},{Key:"Role",Value:"app"},{Key:"ManagedBy",Value:"ts-cloud"}]}let S=f.resources[f.outputs.roleLogicalId];if(S?.Properties)S.Properties.Policies=S.Properties.Policies||[],S.Properties.Policies.push({PolicyName:"DeployBucketRead",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:GetObject","s3:ListBucket"],Resource:[`arn:aws:s3:::${o}`,`arn:aws:s3:::${o}/*`]}]}});for(let[A,R]of Object.entries(f.resources))this.builder.addResource(A,R);this.builder.addOutput("deployBucketName",{Value:{Ref:y},Description:"S3 bucket where release tarballs are uploaded"}),this.builder.addOutput("appInstanceId",{Value:{Ref:f.outputs.instanceLogicalId},Description:"EC2 instance ID for the app server"}),this.builder.addOutput("appPublicIp",{Value:{Ref:f.outputs.eipLogicalId},Description:"Public IP for the app server"}),this.serverEipLogicalIds.set("app",f.outputs.eipLogicalId),this.serverEipLogicalIds.set("appInstance",f.outputs.instanceLogicalId)}generateJumpBox(e,t){let r=this.mergedConfig.infrastructure?.jumpBox;if(!r)return;let n=r===!0?{}:r;if(n.enabled===!1)return;this.generateNetworkInfrastructure(e,t);let i=n.size||"micro",s=E.InstanceSize.specs[i]?.instanceType||i||"t3.micro",a;if(n.mountEfs)a={fileSystemId:typeof n.mountEfs==="string"?n.mountEfs:{Ref:"FileSystem"},mountPath:n.mountPath||"/mnt/efs"};let l;if(n.databaseTools)l=E.JumpBox.withDatabaseTools({slug:e,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:n.keyName||`${e}-${t}`,allowedCidrs:n.allowedCidrs});else if(a)l=E.JumpBox.withEfsMount({slug:e,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:n.keyName||`${e}-${t}`,fileSystemId:a.fileSystemId,mountPath:a.mountPath,allowedCidrs:n.allowedCidrs});else l=E.createJumpBox({slug:e,environment:t,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:n.keyName||`${e}-${t}`,instanceType:s,allowedCidrs:n.allowedCidrs,mountEfs:a});for(let[p,u]of Object.entries(l.resources))this.builder.addResource(p,u);this.builder.addOutput("JumpBoxInstanceId",{Value:{Ref:l.instanceLogicalId},Description:"The ID of the JumpBox EC2 instance (use with SSM Session Manager or SSH)"})}generateSharedInfrastructure(e,t){let r=this.mergedConfig.infrastructure?.ssl,n=this.mergedConfig.infrastructure?.dns,i=n?.domain,d=n?.hostedZoneId,s=[],a,l;if(r?.certificateArn)l=r.certificateArn;else if(r?.enabled&&i&&d){let m=r.domains||[i],c=m[0],y=m.slice(1).map((h)=>{if(h.includes(".")&&h.endsWith(c))return h.replace(`.${c}`,"");return h}),{certificate:o,logicalId:f}=re.createCertificate({domain:c,subdomains:y,slug:e,environment:t,validationMethod:"DNS",hostedZoneId:d});a=f,this.builder.addResource(f,o)}if(this.mergedConfig.infrastructure?.storage){let m=Object.entries(this.mergedConfig.infrastructure.storage).some(([,o])=>o.website),c;if(m&&(a||l))c=`${e}${t}CloudFrontOAC`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(c,{Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${e}-${t}-s3-oac`,Description:`OAC for ${e} ${t} S3 website buckets`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}});let y=Object.entries(this.mergedConfig.infrastructure.storage).map(([o,f])=>({name:o,config:f,mountPath:this.normalizeMountPath(f),rewriteStyle:f.pathRewriteStyle||"directory",logicalId:this.storageBucketLogicalId(e,t,o)})).filter((o)=>o.name!=="public"&&o.config.website&&o.mountPath);for(let[o,f]of Object.entries(this.mergedConfig.infrastructure.storage)){let h=!!(f.website&&c),S=this.storageBucketName(e,t,o),{bucket:A,logicalId:R}=te.createBucket({slug:e,name:o,environment:t,bucketName:S,versioning:f.versioning,encryption:f.encryption,public:h?!1:f.public});if(h&&A.Properties)A.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1};if(this.builder.addResource(R,A),f.website){let I=typeof f.website==="object"?f.website:{},P=te.enableWebsiteHosting(A,I.indexDocument||"index.html",I.errorDocument);this.builder.addResource(R,P)}let D=this.normalizeMountPath(f);if(h&&c&&i&&!(D&&o!=="public")){let I=`${e}${t}${o}CDN`.replace(/[^a-zA-Z0-9]/g,""),P=[];if(f.aliases&&f.aliases.length>0)P.push(...f.aliases);else if(o==="public"){if(P.push(i),r?.domains?.includes(`www.${i}`))P.push(`www.${i}`)}else if(o==="docs")P.push(`docs.${i}`);else if(o==="blog")P.push(`blog.${i}`);let v=typeof f.website==="object"?f.website:{},O=f.spa===!0,M=v.errorDocument||(O?"index.html":"404.html"),_=[];if(O)_.push({ErrorCode:403,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300});else _.push({ErrorCode:403,ResponseCode:404,ResponsePagePath:`/${M}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${M}`,ErrorCachingMinTTL:300});let z=l&&P.length>0?{AcmCertificateArn:l,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:a&&P.length>0?{AcmCertificateArn:{Ref:a},SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},B=`S3-${e}-${t}-${o}`,k=this.mergedConfig.project.region||"us-east-1",x;if(!O)x=`${e}${t}${o}UrlRewrite`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(x,{Type:"AWS::CloudFront::Function",Properties:{Name:`${e}-${t}-${o}-url-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`URL rewrite for ${e} ${t} ${o} - appends .html to extensionless paths`,Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) { var request = event.request; var uri = request.uri; if (uri.endsWith('/')) { request.uri += 'index.html'; }
14
+ else if (!uri.includes('.')) { request.uri += '.html'; } return request; }`}});let X=[{Id:B,DomainName:{"Fn::Sub":`\${${R}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:c}}],G=[],Q=[];if(this.shouldRouteStorageBucketToCompute(o,f)){this.appendComputeAppOrigin(X,G,Q,e,t,this.resolveComputeCachePathPatterns(f.computeRoutes));for(let w of y){let U=`S3-${e}-${t}-${w.name}`,ee=`${e}${t}${w.name}PathMountRewrite`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(ee,{Type:"AWS::CloudFront::Function",Properties:{Name:`${e}-${t}-${w.name}-path-mount-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`Path mount rewrite for ${e} ${t} ${w.name} at ${w.mountPath}`,Runtime:"cloudfront-js-2.0"},FunctionCode:this.pathMountRewriteFunctionCode(w.mountPath,w.rewriteStyle)}}),X.push({Id:U,DomainName:{"Fn::Sub":`\${${w.logicalId}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:c}}),Q.push(w.logicalId,ee);for(let ze of[w.mountPath,`${w.mountPath}/*`])G.push({PathPattern:ze,TargetOriginId:U,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[ee,"FunctionARN"]}}]})}}let ge={Type:"AWS::CloudFront::Distribution",DependsOn:[R,c,...x?[x]:[],...Q],Properties:{DistributionConfig:{Enabled:!0,Comment:`${e} ${t} ${o} site`,DefaultRootObject:"index.html",Origins:X,DefaultCacheBehavior:{TargetOriginId:B,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",...x?{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[x,"FunctionARN"]}}]}:{}},...G.length>0?{CacheBehaviors:G}:{},...P.length>0?{Aliases:P}:{},ViewerCertificate:z,PriceClass:"PriceClass_100",HttpVersion:"http2and3",IPV6Enabled:!0,CustomErrorResponses:_}}};if(a)ge.DependsOn.push(a);this.builder.addResource(I,ge);let He=`${R}CloudFrontPolicy`;if(this.builder.addResource(He,{Type:"AWS::S3::BucketPolicy",DependsOn:[R,I],Properties:{Bucket:{Ref:R},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${R}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${I}}`}}}}]}}}),this.shouldRouteStorageBucketToCompute(o,f))for(let w of y){let U=`${w.logicalId}CloudFrontPolicy`;this.builder.addResource(U,{Type:"AWS::S3::BucketPolicy",DependsOn:[w.logicalId,I],Properties:{Bucket:{Ref:w.logicalId},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${w.logicalId}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${I}}`}}}}]}}})}if(P.length>0)s.push({name:o,bucketLogicalId:R,distLogicalId:I,oacLogicalId:c,aliases:P});this.builder.addOutput(`${o}CloudFrontDomain`,{Value:{"Fn::GetAtt":[I,"DomainName"]},Description:`CloudFront domain for ${o}`}),this.builder.addOutput(`${o}CloudFrontDistributionId`,{Value:{Ref:I},Description:`CloudFront distribution ID for ${o}`})}if(this.builder.addOutput(`${o}BucketName`,{Value:{Ref:R},Description:`S3 bucket name for ${o}`}),o==="public")this.builder.addOutput("FrontendBucketName",{Value:{Ref:R},Description:"Frontend S3 bucket name"});if(o==="docs")this.builder.addOutput("DocsBucketName",{Value:{Ref:R},Description:"Documentation S3 bucket name"});if(o==="blog")this.builder.addOutput("BlogBucketName",{Value:{Ref:R},Description:"Blog S3 bucket name"})}}if(this.mergedConfig.infrastructure?.sftp){let m=this.mergedConfig.infrastructure.sftp,c=$e.create({...m,storage:this.resolveSftpStorage(m,e,t)??m.storage,slug:e,environment:t});for(let[y,o]of Object.entries(c.resources))this.builder.addResource(y,o);this.builder.addOutput("SftpServerId",{Value:{Ref:c.serverLogicalId},Description:"AWS Transfer Family SFTP server ID"}),this.builder.addOutput("SftpEndpoint",{Value:{"Fn::Sub":`\${${c.serverLogicalId}}.server.transfer.\${AWS::Region}.amazonaws.com`},Description:"AWS Transfer Family SFTP endpoint"}),this.builder.addOutput("SftpStorageDomain",{Value:c.domain,Description:"Storage backing the SFTP server (EFS or S3)"})}if(d&&s.length>0)for(let{name:m,distLogicalId:c,aliases:y}of s)for(let o of y){let f=o.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${f}ARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[c],Properties:{HostedZoneId:d,Name:o,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[c,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}}),this.builder.addResource(`${f}AAAARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[c],Properties:{HostedZoneId:d,Name:o,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":[c,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}})}if(this.mergedConfig.infrastructure?.databases){for(let[m,c]of Object.entries(this.mergedConfig.infrastructure.databases))if(c.engine==="dynamodb"){let{table:y,logicalId:o}=K.createTable({slug:e,environment:t,tableName:`${e}-${t}-${m}`,partitionKey:c.partitionKey||{name:"id",type:"S"},sortKey:c.sortKey});this.builder.addResource(o,y)}else if(c.engine==="postgres"){let{dbInstance:y,logicalId:o}=K.createPostgres({slug:e,environment:t,dbInstanceIdentifier:`${e}-${t}-${m}`,masterUsername:c.username||"admin",masterUserPassword:c.password||"changeme123",allocatedStorage:c.storage||20,dbInstanceClass:c.instanceClass||"db.t3.micro"});this.builder.addResource(o,y)}else if(c.engine==="mysql"){let{dbInstance:y,logicalId:o}=K.createMysql({slug:e,environment:t,dbInstanceIdentifier:`${e}-${t}-${m}`,masterUsername:c.username||"admin",masterUserPassword:c.password||"changeme123",allocatedStorage:c.storage||20,dbInstanceClass:c.instanceClass||"db.t3.micro"});this.builder.addResource(o,y)}}if(this.mergedConfig.infrastructure?.cdn)for(let[m,c]of Object.entries(this.mergedConfig.infrastructure.cdn)){if(!c.origin)continue;let y=typeof c.customDomain==="string"?c.customDomain:c.customDomain?.domain||c.domain,o=typeof c.customDomain==="object"?c.customDomain?.certificateArn:c.certificateArn,f=o||l,h=`${e}${t}${m}CDN`.replace(/[^a-zA-Z0-9]/g,""),S=`S3-${e}-${t}-${m}-cdn`,A=[{Id:S,DomainName:c.origin,OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginShield:c.originShield?{Enabled:!0,OriginShieldRegion:c.originShieldRegion||this.mergedConfig.environments[t]?.region||this.mergedConfig.project.region||"us-east-1"}:{Enabled:!1}}],R=[],D=[];if(c.routeCompute)this.appendComputeAppOrigin(A,R,D,e,t,this.resolveComputeCachePathPatterns(c.computeRoutes));let I=f&&y?{AcmCertificateArn:a&&!o?{Ref:a}:f,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},P=[...D];if(a&&!o&&y)P.push(a);let v={Type:"AWS::CloudFront::Distribution",...P.length>0?{DependsOn:P}:{},Properties:{DistributionConfig:{Enabled:!0,Comment:`${e} ${t} ${m} CDN`,DefaultRootObject:"index.html",Origins:A,DefaultCacheBehavior:{TargetOriginId:S,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:c.compress!==!1,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"},...R.length>0?{CacheBehaviors:R}:{},...y&&f?{Aliases:[y]}:{},ViewerCertificate:I,PriceClass:"PriceClass_100",HttpVersion:c.http3?"http2and3":"http2"}}};if(this.builder.addResource(h,v),d&&y&&f){let O=y.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${O}CdnARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[h,...a&&!o?[a]:[]],Properties:{HostedZoneId:d,Name:y,Type:"A",AliasTarget:{HostedZoneId:"Z2FDTNDATAQYW2",DNSName:{"Fn::GetAtt":[h,"DomainName"]}}}})}}if(this.mergedConfig.infrastructure?.queues)for(let[m,c]of Object.entries(this.mergedConfig.infrastructure.queues)){if(!this.shouldDeploy(c))continue;let{queue:y,logicalId:o}=ne.createQueue({slug:e,environment:t,name:`${e}-${t}-${m}`,fifo:c.fifo,visibilityTimeout:c.visibilityTimeout,messageRetentionPeriod:c.messageRetentionPeriod,delaySeconds:c.delaySeconds,maxMessageSize:c.maxMessageSize,receiveMessageWaitTime:c.receiveMessageWaitTime,contentBasedDeduplication:c.contentBasedDeduplication,encrypted:c.encrypted,kmsKeyId:c.kmsKeyId});this.builder.addResource(o,y);let f;if(c.deadLetterQueue){let{deadLetterQueue:h,updatedSourceQueue:S,deadLetterLogicalId:A}=ne.createDeadLetterQueue(o,{slug:e,environment:t,maxReceiveCount:c.maxReceiveCount});f=A,this.builder.addResource(A,h);let D=this.builder.getResources()[o];if(D?.Properties)D.Properties.RedrivePolicy=S.Properties?.RedrivePolicy}if(c.trigger){let h=c.trigger,S=`${e}${t}${h.functionName}`.replace(/[^a-zA-Z0-9]/g,""),A={Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:{"Fn::GetAtt":[o,"Arn"]},FunctionName:{Ref:S},BatchSize:h.batchSize||10,MaximumBatchingWindowInSeconds:h.batchWindow||0,Enabled:!0,...h.reportBatchItemFailures!==!1&&{FunctionResponseTypes:["ReportBatchItemFailures"]},...h.maxConcurrency&&{ScalingConfig:{MaximumConcurrency:h.maxConcurrency}},...h.filterPattern&&{FilterCriteria:{Filters:[{Pattern:JSON.stringify(h.filterPattern)}]}}},DependsOn:[o,S]};this.builder.addResource(`${o}Trigger`,A)}if(c.alarms?.enabled){let h=c.alarms,S=h.notificationTopicArn;if(!S&&h.notificationEmails?.length){let D=`${o}AlarmTopic`;this.builder.addResource(D,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-${m}-alarms`,DisplayName:`${m} Queue Alarms`}}),h.notificationEmails.forEach((I,P)=>{this.builder.addResource(`${D}Sub${P}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:D},Protocol:"email",Endpoint:I}})}),S={Ref:D}}let A=h.queueDepthThreshold||1000;this.builder.addResource(`${o}DepthAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-${m}-queue-depth`,AlarmDescription:`Queue ${m} depth exceeds ${A} messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:A,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[o,"QueueName"]}}],...S&&{AlarmActions:[S],OKActions:[S]}}});let R=h.messageAgeThreshold||3600;if(this.builder.addResource(`${o}AgeAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-${m}-message-age`,AlarmDescription:`Queue ${m} oldest message exceeds ${R} seconds`,MetricName:"ApproximateAgeOfOldestMessage",Namespace:"AWS/SQS",Statistic:"Maximum",Period:300,EvaluationPeriods:2,Threshold:R,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[o,"QueueName"]}}],...S&&{AlarmActions:[S],OKActions:[S]}}}),f&&h.dlqAlarm!==!1)this.builder.addResource(`${f}Alarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-${m}-dlq-messages`,AlarmDescription:`Dead letter queue for ${m} has messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Sum",Period:300,EvaluationPeriods:1,Threshold:0,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[f,"QueueName"]}}],...S&&{AlarmActions:[S]}}})}if(c.subscribe){let h=c.subscribe,S=h.topicArn;if(!S&&h.topicName)S={Ref:h.topicName};if(S){this.builder.addResource(`${o}SnsPolicy`,{Type:"AWS::SQS::QueuePolicy",Properties:{Queues:[{Ref:o}],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"sns.amazonaws.com"},Action:"sqs:SendMessage",Resource:{"Fn::GetAtt":[o,"Arn"]},Condition:{ArnEquals:{"aws:SourceArn":S}}}]}}});let A={TopicArn:S,Protocol:"sqs",Endpoint:{"Fn::GetAtt":[o,"Arn"]},RawMessageDelivery:h.rawMessageDelivery||!1};if(h.filterPolicy)A.FilterPolicy=h.filterPolicy,A.FilterPolicyScope=h.filterPolicyScope||"MessageAttributes";this.builder.addResource(`${o}SnsSub`,{Type:"AWS::SNS::Subscription",Properties:A,DependsOn:`${o}SnsPolicy`})}}}if(this.mergedConfig.infrastructure?.realtime?.enabled)if((this.mergedConfig.infrastructure.realtime.mode||"serverless")==="server")this.generateRealtimeServerResources(e,t);else this.generateRealtimeResources(e,t);let p=this.mergedConfig.infrastructure?.redirects;if(p){let m=p.target||this.mergedConfig.infrastructure?.dns?.domain||"",c=p.protocol||"https";if(p.domains?.length&&m)for(let y of p.domains){let{bucket:o,bucketPolicy:f,logicalId:h,policyLogicalId:S}=q.createDomainRedirectBucket({slug:e,environment:t,sourceDomain:y,targetDomain:m,protocol:c});this.builder.addResource(h,o),this.builder.addResource(S,f)}if(p.paths&&Object.keys(p.paths).length>0){let y=q.fromMapping(p.paths,{statusCode:p.statusCode||301}),{function:o,logicalId:f}=q.createPathRedirectFunction({slug:e,environment:t,rules:y});this.builder.addResource(f,o)}}if(this.mergedConfig.infrastructure?.monitoring?.alarms)for(let[m,c]of Object.entries(this.mergedConfig.infrastructure.monitoring.alarms)){let{alarm:y,logicalId:o}=we.createAlarm({slug:e,environment:t,alarmName:`${e}-${t}-${m}`,metricName:c.metricName||"Errors",namespace:c.namespace||"AWS/Lambda",threshold:c.threshold||1,comparisonOperator:c.comparisonOperator||"GreaterThanThreshold"});this.builder.addResource(o,y)}let u=this.mergedConfig.infrastructure?.cache;if(u){let m=u.type||"redis";if(m==="redis"){this.generateNetworkInfrastructure(e,t);let c=u.redis||{},{replicationGroup:y,subnetGroup:o,logicalId:f,subnetGroupId:h}=ie.createRedis({slug:e,environment:t,nodeType:c.nodeType||u.nodeType||"cache.t3.micro",engineVersion:c.engineVersion||"7.1",port:c.port||6379,numCacheClusters:c.numCacheNodes||2,automaticFailover:c.automaticFailoverEnabled!==!1,atRestEncryption:!0,transitEncryption:!0,snapshotRetentionDays:c.snapshotRetentionLimit||7,snapshotWindow:c.snapshotWindow,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(f,y),o&&h)this.builder.addResource(h,o);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[f,"PrimaryEndPoint.Address"]},Description:"Redis primary endpoint address"}),this.builder.addOutput("CachePort",{Value:{"Fn::GetAtt":[f,"PrimaryEndPoint.Port"]},Description:"Redis primary endpoint port"})}else if(m==="memcached"){this.generateNetworkInfrastructure(e,t);let c=u.elasticache||{},{cluster:y,subnetGroup:o,logicalId:f,subnetGroupId:h}=ie.createMemcached({slug:e,environment:t,nodeType:c.nodeType||u.nodeType||"cache.t3.micro",engineVersion:c.engineVersion||"1.6.22",numCacheNodes:c.numCacheNodes||2,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(f,y),o&&h)this.builder.addResource(h,o);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[f,"ConfigurationEndpoint.Address"]},Description:"Memcached configuration endpoint address"})}}let b=this.mergedConfig.infrastructure?.email;if(b){let m=b.domain||this.mergedConfig.infrastructure?.dns?.domain;if(m){let{emailIdentity:c,logicalId:y}=L.verifyDomain({domain:m,slug:e,environment:t,enableDkim:b.enableDkim!==!1,dkimKeyLength:b.dkimKeyLength||"RSA_2048_BIT"});if(this.builder.addResource(y,c),b.configurationSet!==!1){let{configurationSet:h,logicalId:S}=L.createConfigurationSet({slug:e,environment:t});this.builder.addResource(S,h)}let o=b.hostedZoneId||this.mergedConfig.infrastructure?.dns?.hostedZoneId;if(o){if(b.enableDkim!==!1)for(let D=1;D<=3;D++){let I=`DkimRecord${D}${m.replace(/\./g,"")}`;this.builder.addResource(I,{Type:"AWS::Route53::RecordSet",DependsOn:[y],Properties:{HostedZoneId:o,Name:{"Fn::GetAtt":[y,`DkimDNSTokenName${D}`]},Type:"CNAME",TTL:1800,ResourceRecords:[{"Fn::GetAtt":[y,`DkimDNSTokenValue${D}`]}]}})}let{record:h,logicalId:S}=L.createSpfRecord(m,o);this.builder.addResource(S,h);let{record:A,logicalId:R}=L.createDmarcRecord(m,o,{policy:"none",reportingEmail:b.dmarcReportingEmail||`dmarc-reports@${m}`});this.builder.addResource(R,A)}this.builder.addOutput("EmailDomain",{Value:m,Description:"SES verified email domain"});let f=b.server;if(f?.enabled&&o){let h=this.mergedConfig.environments[t]?.region||this.mergedConfig.project.region||"us-east-1",S=`${e}-${t}-email`,{role:A,policy:R,roleLogicalId:D,policyLogicalId:I}=L.createEmailLambdaRole({slug:e,environment:t,s3BucketArn:`arn:aws:s3:::${S}`,sesIdentityArn:`arn:aws:ses:${h}:*:identity/${m}`});this.builder.addResource(D,A),this.builder.addResource(I,R);let{function:P,permission:v,logicalId:O,permissionLogicalId:M}=L.createInboundEmailLambda({slug:e,environment:t,roleArn:{"Fn::GetAtt":[D,"Arn"]},s3BucketName:S,organizedPrefix:"mailboxes/"});this.builder.addResource(O,P),this.builder.addResource(M,v);let _=L.createInboundEmailSetup({slug:e,environment:t,domain:m,s3BucketName:S,s3KeyPrefix:"inbox/",region:h,hostedZoneId:o,lambdaFunctionArn:{"Fn::GetAtt":[O,"Arn"]}});for(let[B,k]of Object.entries(_.resources)){if(k.Type==="AWS::SES::ReceiptRule")k.DependsOn=[M,O];this.builder.addResource(B,k)}this.builder.addOutput("InboundEmailLambda",{Value:{Ref:O},Description:"Inbound email processing Lambda function"}),this.builder.addOutput("EmailBucket",{Value:S,Description:"S3 bucket for email storage"});let z=this.serverEipLogicalIds.get("app");if(z&&o){let k=`${f?.subdomain||"mail"}.${m}`,x=k.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${x}ARecord`,{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:o,Name:k,Type:"A",TTL:"300",ResourceRecords:[{Ref:z}]}})}this.builder.addOutput("MailHost",{Value:`mail.${m}`,Description:"Mail server hostname for SMTP/IMAP clients"})}}}let C=this.mergedConfig.infrastructure?.search;if(C){let m=C.vpc?{subnetIds:[{Ref:"PublicSubnet1"}],securityGroupIds:[]}:void 0;if(m)this.generateNetworkInfrastructure(e,t);let{domain:c,logicalId:y}=Ee.createDomain({slug:e,environment:t,engineVersion:C.engineVersion||"OpenSearch_2.11",instanceType:C.instanceType||"t3.small.search",instanceCount:C.instanceCount||1,volumeSize:C.volumeSize||10,volumeType:C.volumeType||"gp3",dedicatedMaster:C.dedicatedMaster||!1,dedicatedMasterType:C.dedicatedMasterType,dedicatedMasterCount:C.dedicatedMasterCount||3,multiAz:C.multiAz||!1,encryption:C.encryption||{atRest:!0,nodeToNode:!0},advancedSecurity:C.advancedSecurity,autoTune:C.autoTune!==!1,vpc:m});this.builder.addResource(y,c),this.builder.addOutput("SearchDomainEndpoint",{Value:{"Fn::GetAtt":[y,"DomainEndpoint"]},Description:"OpenSearch domain endpoint"}),this.builder.addOutput("SearchDomainArn",{Value:{"Fn::GetAtt":[y,"Arn"]},Description:"OpenSearch domain ARN"})}let T=this.mergedConfig.infrastructure?.fileSystem;if(T&&Object.keys(T).length>0){this.generateNetworkInfrastructure(e,t);for(let[m,c]of Object.entries(T)){let{fileSystem:y,logicalId:o}=j.createFileSystem({slug:`${e}-${m}`,environment:t,encrypted:c.encrypted!==!1,performanceMode:c.performanceMode||"generalPurpose",throughputMode:c.throughputMode||"bursting",enableBackup:!0});this.builder.addResource(o,y);let{securityGroup:f,logicalId:h}=j.createEfsSecurityGroup({slug:`${e}-${m}`,environment:t,vpcId:{Ref:"VPC"},sourceCidrBlocks:["10.0.0.0/16"]});this.builder.addResource(h,f);let{mountTargets:S,logicalIds:A}=j.createMultiAzMountTargets(o,{slug:`${e}-${m}`,environment:t,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],securityGroupId:{Ref:h}});for(let R=0;R<S.length;R++)this.builder.addResource(A[R],S[R]);this.builder.addOutput(`${m}FileSystemId`,{Value:{Ref:o},Description:`EFS file system ID for ${m}`})}}let g=this.mergedConfig.infrastructure?.ai;if(g){let m=g.service||"ecs",c=g.models||["*"],y=g.allowStreaming!==!1,o;if(m==="ecs")o=F.enableBedrockForEcs({slug:e,environment:t,models:c,allowStreaming:y});else if(m==="ec2")o=F.enableBedrockForEc2({slug:e,environment:t,models:c,allowStreaming:y});else if(m==="lambda")o=F.enableBedrockForLambda({slug:e,environment:t,models:c,allowStreaming:y});else o=F.createBedrockRole(m,{slug:e,environment:t,models:c,allowStreaming:y});if(this.builder.addResource(o.logicalId,o.role),g.allowAsync){let{policy:f,logicalId:h}=F.createBedrockPolicy({slug:e,environment:t,models:c,allowStreaming:y,allowAsync:!0});this.builder.addResource(h,f)}this.builder.addOutput("BedrockRoleArn",{Value:{"Fn::GetAtt":[o.logicalId,"Arn"]},Description:"IAM role ARN with Bedrock permissions"})}}generateRealtimeResources(e,t){let r=this.mergedConfig.infrastructure?.realtime;if(!r)return;let n=r.name||`${e}-${t}-realtime`,i=r.scaling||{},d=r.storage||{type:"dynamodb"},s=i.handlerMemory||256,a=i.handlerTimeout||30,l=`${e}${t}RealtimeConnections`.replace(/[^a-zA-Z0-9]/g,""),p=`${e}${t}RealtimeChannels`.replace(/[^a-zA-Z0-9]/g,"");if(d.type==="dynamodb"){let A=d.dynamodb||{},R=A.billingMode||"PAY_PER_REQUEST";this.builder.addResource(l,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${e}-${t}-realtime-connections`,BillingMode:R,AttributeDefinitions:[{AttributeName:"connectionId",AttributeType:"S"},{AttributeName:"userId",AttributeType:"S"}],KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],GlobalSecondaryIndexes:[{IndexName:"userId-index",KeySchema:[{AttributeName:"userId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:A.readCapacity||5,WriteCapacityUnits:A.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:A.readCapacity||5,WriteCapacityUnits:A.writeCapacity||5}},...A.pointInTimeRecovery&&{PointInTimeRecoverySpecification:{PointInTimeRecoveryEnabled:!0}},Tags:[{Key:"Name",Value:`${e}-${t}-realtime-connections`},{Key:"Environment",Value:t}]}}),this.builder.addResource(p,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${e}-${t}-realtime-channels`,BillingMode:R,AttributeDefinitions:[{AttributeName:"channel",AttributeType:"S"},{AttributeName:"connectionId",AttributeType:"S"}],KeySchema:[{AttributeName:"channel",KeyType:"HASH"},{AttributeName:"connectionId",KeyType:"RANGE"}],GlobalSecondaryIndexes:[{IndexName:"connectionId-index",KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:A.readCapacity||5,WriteCapacityUnits:A.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...R==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:A.readCapacity||5,WriteCapacityUnits:A.writeCapacity||5}},Tags:[{Key:"Name",Value:`${e}-${t}-realtime-channels`},{Key:"Environment",Value:t}]}})}let u=`${e}${t}RealtimeRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(u,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-realtime-handler-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:"RealtimeHandlerPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:GetItem","dynamodb:PutItem","dynamodb:DeleteItem","dynamodb:Query","dynamodb:Scan","dynamodb:UpdateItem"],Resource:[{"Fn::GetAtt":[l,"Arn"]},{"Fn::Sub":`\${${l}.Arn}/index/*`},{"Fn::GetAtt":[p,"Arn"]},{"Fn::Sub":`\${${p}.Arn}/index/*`}]},{Effect:"Allow",Action:"execute-api:ManageConnections",Resource:{"Fn::Sub":"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*"}}]}}]}});let b=`${e}${t}RealtimeConnect`.replace(/[^a-zA-Z0-9]/g,""),C=`${e}${t}RealtimeDisconnect`.replace(/[^a-zA-Z0-9]/g,""),T=`${e}${t}RealtimeMessage`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(b,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${e}-${t}-realtime-connect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[u,"Arn"]},MemorySize:s,Timeout:a,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:l},CHANNELS_TABLE:{Ref:p},ENVIRONMENT:t}},Code:{ZipFile:this.generateConnectHandlerCode()}},DependsOn:[u,l]}),this.builder.addResource(C,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${e}-${t}-realtime-disconnect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[u,"Arn"]},MemorySize:s,Timeout:a,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:l},CHANNELS_TABLE:{Ref:p},ENVIRONMENT:t}},Code:{ZipFile:this.generateDisconnectHandlerCode()}},DependsOn:[u,l,p]}),this.builder.addResource(T,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${e}-${t}-realtime-message`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[u,"Arn"]},MemorySize:s,Timeout:a,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:l},CHANNELS_TABLE:{Ref:p},ENVIRONMENT:t}},Code:{ZipFile:this.generateMessageHandlerCode()}},DependsOn:[u,l,p]});let g=`${e}${t}RealtimeApi`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(g,{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:n,ProtocolType:"WEBSOCKET",RouteSelectionExpression:"$request.body.action",Tags:{Name:n,Environment:t}}});let m=`${b}Permission`,c=`${C}Permission`,y=`${T}Permission`;this.builder.addResource(m,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:b},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${g}}/*/$connect`}}}),this.builder.addResource(c,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:C},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${g}}/*/$disconnect`}}}),this.builder.addResource(y,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:T},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${g}}/*/$default`}}});let o=`${g}ConnectInteg`,f=`${g}DisconnectInteg`,h=`${g}MessageInteg`;this.builder.addResource(o,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:g},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${b}.Arn}/invocations`}}}),this.builder.addResource(f,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:g},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${C}.Arn}/invocations`}}}),this.builder.addResource(h,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:g},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${T}.Arn}/invocations`}}}),this.builder.addResource(`${g}ConnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:g},RouteKey:"$connect",AuthorizationType:"NONE",Target:{"Fn::Sub":`integrations/\${${o}}`}}}),this.builder.addResource(`${g}DisconnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:g},RouteKey:"$disconnect",Target:{"Fn::Sub":`integrations/\${${f}}`}}}),this.builder.addResource(`${g}DefaultRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:g},RouteKey:"$default",Target:{"Fn::Sub":`integrations/\${${h}}`}}});let S=`${g}Stage`;if(this.builder.addResource(S,{Type:"AWS::ApiGatewayV2::Stage",Properties:{ApiId:{Ref:g},StageName:t,AutoDeploy:!0,DefaultRouteSettings:{ThrottlingBurstLimit:i.messagesPerSecond||1000,ThrottlingRateLimit:i.messagesPerSecond||1000}}}),r.monitoring?.enabled){let A=r.monitoring,R=A.notificationTopicArn;if(!R&&A.notificationEmails?.length){let D=`${g}AlarmTopic`;this.builder.addResource(D,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-realtime-alarms`,DisplayName:"Realtime WebSocket Alarms"}}),A.notificationEmails.forEach((I,P)=>{this.builder.addResource(`${D}Sub${P}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:D},Protocol:"email",Endpoint:I}})}),R={Ref:D}}if(A.connectionThreshold)this.builder.addResource(`${g}ConnectionAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-connections`,AlarmDescription:`WebSocket connections exceed ${A.connectionThreshold}`,MetricName:"ConnectCount",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:300,EvaluationPeriods:2,Threshold:A.connectionThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:g}}],...R&&{AlarmActions:[R]}}});if(A.errorThreshold)this.builder.addResource(`${g}ErrorAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-errors`,AlarmDescription:`WebSocket errors exceed ${A.errorThreshold}/min`,MetricName:"ExecutionError",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:60,EvaluationPeriods:3,Threshold:A.errorThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:g}}],...R&&{AlarmActions:[R]}}})}this.builder.addOutput(`${g}Endpoint`,{Description:"WebSocket API endpoint URL",Value:{"Fn::Sub":`wss://\${${g}}.execute-api.\${AWS::Region}.amazonaws.com/${t}`},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-endpoint"}}}),this.builder.addOutput(`${g}Id`,{Description:"WebSocket API ID",Value:{Ref:g},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-api-id"}}})}generateConnectHandlerCode(){return`
15
15
  const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
16
16
  const { DynamoDBDocumentClient, PutCommand } = require('@aws-sdk/lib-dynamodb');
17
17
 
@@ -170,7 +170,7 @@ catch (error) {
170
170
  return { statusCode: 500, body: JSON.stringify({ error: 'Internal error' }) };
171
171
  }
172
172
  };
173
- `.trim()}generateRealtimeServerResources(e,t){let r=this.mergedConfig.infrastructure?.realtime;if(!r)return;let n=r.server||{},o=n.port||6001,l=n.instances||1,c=`${e}${t}RealtimeSG`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(c,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`Security group for ${e} realtime WebSocket server`,GroupName:`${e}-${t}-realtime-sg`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:o,ToPort:o,CidrIp:"0.0.0.0/0",Description:"WebSocket connections"},{IpProtocol:"tcp",FromPort:443,ToPort:443,CidrIp:"0.0.0.0/0",Description:"HTTPS/WSS connections"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${e}-${t}-realtime-sg`},{Key:"Environment",Value:t}]}});let s=`${e}${t}RealtimeTaskDef`.replace(/[^a-zA-Z0-9]/g,""),u=`${e}${t}RealtimeTaskRole`.replace(/[^a-zA-Z0-9]/g,""),h=`${e}${t}RealtimeExecRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(h,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-realtime-exec-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]}}),this.builder.addResource(u,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-realtime-task-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"RealtimeTaskPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"},...n.redis?.enabled?[{Effect:"Allow",Action:["elasticache:DescribeCacheClusters","elasticache:DescribeReplicationGroups"],Resource:"*"}]:[]]}}]}});let d=[{Name:"BROADCAST_HOST",Value:n.host||"0.0.0.0"},{Name:"BROADCAST_PORT",Value:String(o)},{Name:"NODE_ENV",Value:t==="production"?"production":"development"}];if(n.redis?.enabled){if(n.redis.useElastiCache)d.push({Name:"REDIS_HOST",Value:{"Fn::GetAtt":["CacheCluster","RedisEndpoint.Address"]}}),d.push({Name:"REDIS_PORT",Value:{"Fn::GetAtt":["CacheCluster","RedisEndpoint.Port"]}});else d.push({Name:"REDIS_HOST",Value:n.redis.host||"localhost"}),d.push({Name:"REDIS_PORT",Value:String(n.redis.port||6379)});if(n.redis.keyPrefix)d.push({Name:"REDIS_KEY_PREFIX",Value:n.redis.keyPrefix})}this.builder.addResource(s,{Type:"AWS::ECS::TaskDefinition",Properties:{Family:`${e}-${t}-realtime`,NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:"512",Memory:"1024",ExecutionRoleArn:{"Fn::GetAtt":[h,"Arn"]},TaskRoleArn:{"Fn::GetAtt":[u,"Arn"]},ContainerDefinitions:[{Name:"realtime",Image:{"Fn::Sub":`\${AWS::AccountId}.dkr.ecr.\${AWS::Region}.amazonaws.com/${e}-realtime:latest`},Essential:!0,PortMappings:[{ContainerPort:o,Protocol:"tcp"}],Environment:d,LogConfiguration:{LogDriver:"awslogs",Options:{"awslogs-group":`/ecs/${e}-${t}-realtime`,"awslogs-region":{Ref:"AWS::Region"},"awslogs-stream-prefix":"realtime"}},HealthCheck:{Command:["CMD-SHELL",`curl -f http://localhost:${o}${n.healthCheckPath||"/health"} || exit 1`],Interval:30,Timeout:5,Retries:3,StartPeriod:60}}],Tags:[{Key:"Name",Value:`${e}-${t}-realtime`},{Key:"Environment",Value:t}]},DependsOn:[h,u]});let b=`${e}${t}RealtimeLogs`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(b,{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:`/ecs/${e}-${t}-realtime`,RetentionInDays:30}});let A=`${e}${t}RealtimeService`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(A,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${e}-${t}-realtime`,Cluster:{Ref:"ECSCluster"},TaskDefinition:{Ref:s},DesiredCount:l,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:c}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},HealthCheckGracePeriodSeconds:60,Tags:[{Key:"Name",Value:`${e}-${t}-realtime`},{Key:"Environment",Value:t}]},DependsOn:[s,c,b]}),n.autoScaling){let T=n.autoScaling,g=`${e}${t}RealtimeScalableTarget`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(g,{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{MaxCapacity:T.max||10,MinCapacity:T.min||1,ResourceId:{"Fn::Sub":`service/\${ECSCluster}/${e}-${t}-realtime`},RoleARN:{"Fn::Sub":"arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"},ScalableDimension:"ecs:service:DesiredCount",ServiceNamespace:"ecs"},DependsOn:A}),T.targetCPU)this.builder.addResource(`${e}${t}RealtimeCPUPolicy`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${e}-${t}-realtime-cpu-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:g},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageCPUUtilization"},TargetValue:T.targetCPU,ScaleInCooldown:300,ScaleOutCooldown:60}}})}if(r.monitoring?.enabled){let T=r.monitoring,g=T.notificationTopicArn;if(!g&&T.notificationEmails?.length){let m=`${e}${t}RealtimeAlarmTopic`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(m,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-realtime-alarms`,DisplayName:"Realtime Server Alarms"}}),T.notificationEmails.forEach((a,y)=>{this.builder.addResource(`${m}Sub${y}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:m},Protocol:"email",Endpoint:a}})}),g={Ref:m}}this.builder.addResource(`${e}${t}RealtimeCPUAlarm`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-high-cpu`,AlarmDescription:"Realtime server CPU utilization is high",MetricName:"CPUUtilization",Namespace:"AWS/ECS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:80,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ClusterName",Value:{Ref:"ECSCluster"}},{Name:"ServiceName",Value:`${e}-${t}-realtime`}],...g&&{AlarmActions:[g]}},DependsOn:A}),this.builder.addResource(`${e}${t}RealtimeMemoryAlarm`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-high-memory`,AlarmDescription:"Realtime server memory utilization is high",MetricName:"MemoryUtilization",Namespace:"AWS/ECS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:80,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ClusterName",Value:{Ref:"ECSCluster"}},{Name:"ServiceName",Value:`${e}-${t}-realtime`}],...g&&{AlarmActions:[g]}},DependsOn:A})}this.builder.addOutput(`${e}${t}RealtimeEndpoint`.replace(/[^a-zA-Z0-9]/g,""),{Description:"Realtime WebSocket server endpoint",Value:{"Fn::Sub":`wss://${e}-${t}-realtime.\${AWS::Region}.elb.amazonaws.com:${o}`},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-endpoint"}}})}generateBroadcastConfig(){let e=this.mergedConfig.infrastructure?.realtime;if(!e||e.mode!=="server")return"";let t=e.server||{};return`import type { BroadcastConfig } from 'ts-broadcasting'
173
+ `.trim()}generateRealtimeServerResources(e,t){let r=this.mergedConfig.infrastructure?.realtime;if(!r)return;let n=r.server||{},i=n.port||6001,d=n.instances||1,s=`${e}${t}RealtimeSG`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(s,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`Security group for ${e} realtime WebSocket server`,GroupName:`${e}-${t}-realtime-sg`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:i,ToPort:i,CidrIp:"0.0.0.0/0",Description:"WebSocket connections"},{IpProtocol:"tcp",FromPort:443,ToPort:443,CidrIp:"0.0.0.0/0",Description:"HTTPS/WSS connections"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${e}-${t}-realtime-sg`},{Key:"Environment",Value:t}]}});let a=`${e}${t}RealtimeTaskDef`.replace(/[^a-zA-Z0-9]/g,""),l=`${e}${t}RealtimeTaskRole`.replace(/[^a-zA-Z0-9]/g,""),p=`${e}${t}RealtimeExecRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(p,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-realtime-exec-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]}}),this.builder.addResource(l,{Type:"AWS::IAM::Role",Properties:{RoleName:`${e}-${t}-realtime-task-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"RealtimeTaskPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"},...n.redis?.enabled?[{Effect:"Allow",Action:["elasticache:DescribeCacheClusters","elasticache:DescribeReplicationGroups"],Resource:"*"}]:[]]}}]}});let u=[{Name:"BROADCAST_HOST",Value:n.host||"0.0.0.0"},{Name:"BROADCAST_PORT",Value:String(i)},{Name:"NODE_ENV",Value:t==="production"?"production":"development"}];if(n.redis?.enabled){if(n.redis.useElastiCache)u.push({Name:"REDIS_HOST",Value:{"Fn::GetAtt":["CacheCluster","RedisEndpoint.Address"]}}),u.push({Name:"REDIS_PORT",Value:{"Fn::GetAtt":["CacheCluster","RedisEndpoint.Port"]}});else u.push({Name:"REDIS_HOST",Value:n.redis.host||"localhost"}),u.push({Name:"REDIS_PORT",Value:String(n.redis.port||6379)});if(n.redis.keyPrefix)u.push({Name:"REDIS_KEY_PREFIX",Value:n.redis.keyPrefix})}this.builder.addResource(a,{Type:"AWS::ECS::TaskDefinition",Properties:{Family:`${e}-${t}-realtime`,NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:"512",Memory:"1024",ExecutionRoleArn:{"Fn::GetAtt":[p,"Arn"]},TaskRoleArn:{"Fn::GetAtt":[l,"Arn"]},ContainerDefinitions:[{Name:"realtime",Image:{"Fn::Sub":`\${AWS::AccountId}.dkr.ecr.\${AWS::Region}.amazonaws.com/${e}-realtime:latest`},Essential:!0,PortMappings:[{ContainerPort:i,Protocol:"tcp"}],Environment:u,LogConfiguration:{LogDriver:"awslogs",Options:{"awslogs-group":`/ecs/${e}-${t}-realtime`,"awslogs-region":{Ref:"AWS::Region"},"awslogs-stream-prefix":"realtime"}},HealthCheck:{Command:["CMD-SHELL",`curl -f http://localhost:${i}${n.healthCheckPath||"/health"} || exit 1`],Interval:30,Timeout:5,Retries:3,StartPeriod:60}}],Tags:[{Key:"Name",Value:`${e}-${t}-realtime`},{Key:"Environment",Value:t}]},DependsOn:[p,l]});let b=`${e}${t}RealtimeLogs`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(b,{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:`/ecs/${e}-${t}-realtime`,RetentionInDays:30}});let C=`${e}${t}RealtimeService`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(C,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${e}-${t}-realtime`,Cluster:{Ref:"ECSCluster"},TaskDefinition:{Ref:a},DesiredCount:d,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:s}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},HealthCheckGracePeriodSeconds:60,Tags:[{Key:"Name",Value:`${e}-${t}-realtime`},{Key:"Environment",Value:t}]},DependsOn:[a,s,b]}),n.autoScaling){let T=n.autoScaling,g=`${e}${t}RealtimeScalableTarget`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(g,{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{MaxCapacity:T.max||10,MinCapacity:T.min||1,ResourceId:{"Fn::Sub":`service/\${ECSCluster}/${e}-${t}-realtime`},RoleARN:{"Fn::Sub":"arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"},ScalableDimension:"ecs:service:DesiredCount",ServiceNamespace:"ecs"},DependsOn:C}),T.targetCPU)this.builder.addResource(`${e}${t}RealtimeCPUPolicy`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${e}-${t}-realtime-cpu-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:g},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageCPUUtilization"},TargetValue:T.targetCPU,ScaleInCooldown:300,ScaleOutCooldown:60}}})}if(r.monitoring?.enabled){let T=r.monitoring,g=T.notificationTopicArn;if(!g&&T.notificationEmails?.length){let m=`${e}${t}RealtimeAlarmTopic`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(m,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-realtime-alarms`,DisplayName:"Realtime Server Alarms"}}),T.notificationEmails.forEach((c,y)=>{this.builder.addResource(`${m}Sub${y}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:m},Protocol:"email",Endpoint:c}})}),g={Ref:m}}this.builder.addResource(`${e}${t}RealtimeCPUAlarm`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-high-cpu`,AlarmDescription:"Realtime server CPU utilization is high",MetricName:"CPUUtilization",Namespace:"AWS/ECS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:80,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ClusterName",Value:{Ref:"ECSCluster"}},{Name:"ServiceName",Value:`${e}-${t}-realtime`}],...g&&{AlarmActions:[g]}},DependsOn:C}),this.builder.addResource(`${e}${t}RealtimeMemoryAlarm`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${e}-${t}-realtime-high-memory`,AlarmDescription:"Realtime server memory utilization is high",MetricName:"MemoryUtilization",Namespace:"AWS/ECS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:80,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ClusterName",Value:{Ref:"ECSCluster"}},{Name:"ServiceName",Value:`${e}-${t}-realtime`}],...g&&{AlarmActions:[g]}},DependsOn:C})}this.builder.addOutput(`${e}${t}RealtimeEndpoint`.replace(/[^a-zA-Z0-9]/g,""),{Description:"Realtime WebSocket server endpoint",Value:{"Fn::Sub":`wss://${e}-${t}-realtime.\${AWS::Region}.elb.amazonaws.com:${i}`},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-endpoint"}}})}generateBroadcastConfig(){let e=this.mergedConfig.infrastructure?.realtime;if(!e||e.mode!=="server")return"";let t=e.server||{};return`import type { BroadcastConfig } from 'ts-broadcasting'
174
174
 
175
175
  export default {
176
176
  verbose: ${this.environment!=="production"},
@@ -219,7 +219,7 @@ ${t.loadManagement?.enabled?`
219
219
  },
220
220
  `:""}
221
221
  } satisfies BroadcastConfig
222
- `}toYAML(){return this.builder.toYAML()}toJSON(){return this.builder.toJSON()}getBuilder(){return this.builder}}function ze(e){let t=[],r=[];if(!e.AWSTemplateFormatVersion)t.push({path:"AWSTemplateFormatVersion",message:"AWSTemplateFormatVersion is required",severity:"error"});else if(e.AWSTemplateFormatVersion!=="2010-09-09")r.push({path:"AWSTemplateFormatVersion",message:'AWSTemplateFormatVersion should be "2010-09-09"',severity:"warning"});if(!e.Resources||Object.keys(e.Resources).length===0)t.push({path:"Resources",message:"At least one resource is required",severity:"error"});else for(let[n,o]of Object.entries(e.Resources))Ge(n,o,t,r);if(e.Resources){let n=qe(e.Resources);if(n.length>0)t.push({path:"Resources",message:`Circular dependencies detected: ${n.join(" -> ")}`,severity:"error"})}if(e.Parameters)for(let[n,o]of Object.entries(e.Parameters))Ue(n,o,t,r);if(e.Outputs)for(let[n,o]of Object.entries(e.Outputs))Ke(n,o,t,r);return{valid:t.length===0,errors:t,warnings:r}}function Ge(e,t,r,n){if(!t.Type)r.push({path:`Resources.${e}.Type`,message:"Resource Type is required",severity:"error"});if(!/^[a-zA-Z0-9]+$/.test(e))n.push({path:`Resources.${e}`,message:"Logical ID should only contain alphanumeric characters",severity:"warning"});if(t.Type&&!t.Type.startsWith("AWS::")&&!t.Type.startsWith("Custom::"))r.push({path:`Resources.${e}.Type`,message:'Resource Type must start with "AWS::" or "Custom::"',severity:"error"});if(t.Properties){for(let[o,l]of Object.entries(t.Properties))if(l===void 0||l===null)n.push({path:`Resources.${e}.Properties.${o}`,message:"Property has undefined or null value",severity:"warning"})}if(t.DependsOn){if(typeof t.DependsOn==="string"){if(t.DependsOn===e)r.push({path:`Resources.${e}.DependsOn`,message:"Resource cannot depend on itself",severity:"error"})}else if(Array.isArray(t.DependsOn)){if(t.DependsOn.includes(e))r.push({path:`Resources.${e}.DependsOn`,message:"Resource cannot depend on itself",severity:"error"})}}}function Ue(e,t,r,n){if(!t.Type)r.push({path:`Parameters.${e}.Type`,message:"Parameter Type is required",severity:"error"});let o=["String","Number","List<Number>","CommaDelimitedList","AWS::SSM::Parameter::Value<String>"];if(t.Type&&!o.includes(t.Type)&&!t.Type.startsWith("AWS::"))n.push({path:`Parameters.${e}.Type`,message:`Uncommon parameter type: ${t.Type}`,severity:"warning"});if(t.NoEcho&&t.Default)n.push({path:`Parameters.${e}`,message:"NoEcho parameters should not have default values",severity:"warning"})}function Ke(e,t,r,n){if(!t.Value)r.push({path:`Outputs.${e}.Value`,message:"Output Value is required",severity:"error"})}function qe(e){let t={};for(let[c,s]of Object.entries(e)){if(t[c]=[],s.DependsOn){if(typeof s.DependsOn==="string")t[c].push(s.DependsOn);else if(Array.isArray(s.DependsOn))t[c].push(...s.DependsOn)}let u=ie(s);t[c].push(...u)}let r=new Set,n=new Set,o=[];function l(c,s){r.add(c),n.add(c),s.push(c);let u=t[c]||[];for(let h of u)if(!r.has(h)){if(l(h,s))return!0}else if(n.has(h)){let d=s.indexOf(h);return o.push(...s.slice(d),h),!0}return s.pop(),n.delete(c),!1}for(let c of Object.keys(t))if(!r.has(c)){if(l(c,[]))return o}return[]}function ie(e,t=[]){if(typeof e!=="object"||e===null)return t;if(Array.isArray(e)){for(let r of e)ie(r,t);return t}if(e.Ref&&typeof e.Ref==="string"&&!e.Ref.startsWith("AWS::"))t.push(e.Ref);if(e["Fn::GetAtt"]){let r=e["Fn::GetAtt"];if(Array.isArray(r)&&r.length>0)t.push(r[0])}for(let r of Object.values(e))ie(r,t);return t}function Ze(e){let t=[],r=[],n=new TextEncoder().encode(e).length,o=51200,l=460800;if(n>51200)if(n>460800)t.push({path:"template",message:`Template size (${n} bytes) exceeds maximum allowed size of 460800 bytes`,severity:"error"});else r.push({path:"template",message:`Template size (${n} bytes) exceeds direct upload limit (51200 bytes). You must upload to S3 first.`,severity:"warning"});return{valid:t.length===0,errors:t,warnings:r}}function je(e){let t=[],r=[],n=e.Resources?Object.keys(e.Resources).length:0,o=e.Parameters?Object.keys(e.Parameters).length:0,l=e.Outputs?Object.keys(e.Outputs).length:0;if(n>500)t.push({path:"Resources",message:`Template has ${n} resources, exceeding the limit of 500`,severity:"error"});else if(n>200)r.push({path:"Resources",message:`Template has ${n} resources. Consider using nested stacks for better organization.`,severity:"warning"});if(o>200)t.push({path:"Parameters",message:`Template has ${o} parameters, exceeding the limit of 200`,severity:"error"});if(l>200)t.push({path:"Outputs",message:`Template has ${l} outputs, exceeding the limit of 200`,severity:"error"});return{valid:t.length===0,errors:t,warnings:r}}function Xi(e){let{domains:t,email:r,staging:n=!1,challengeType:o="http-01",certPath:l="/etc/letsencrypt/live",autoRenew:c=!0}=e,s=t[0],u=t.map((d)=>`-d ${d}`).join(" "),h=n?"--staging":"";if(o==="http-01")return Ye({domains:t,email:r,staging:n,certPath:l,autoRenew:c,domainFlags:u,stagingFlag:h,primaryDomain:s});else{let d=e.dnsProvider?.provider||(e.hostedZoneId?"route53":void 0);return Qe({domains:t,email:r,staging:n,certPath:l,autoRenew:c,domainFlags:u,stagingFlag:h,primaryDomain:s,hostedZoneId:e.hostedZoneId,dnsProvider:e.dnsProvider,dnsProviderType:d})}}function Ye(e){let{email:t,certPath:r,autoRenew:n,domainFlags:o,stagingFlag:l,primaryDomain:c}=e;return`
222
+ `}toYAML(){return this.builder.toYAML()}toJSON(){return this.builder.toJSON()}getBuilder(){return this.builder}}function qe(e){let t=[],r=[];if(!e.AWSTemplateFormatVersion)t.push({path:"AWSTemplateFormatVersion",message:"AWSTemplateFormatVersion is required",severity:"error"});else if(e.AWSTemplateFormatVersion!=="2010-09-09")r.push({path:"AWSTemplateFormatVersion",message:'AWSTemplateFormatVersion should be "2010-09-09"',severity:"warning"});if(!e.Resources||Object.keys(e.Resources).length===0)t.push({path:"Resources",message:"At least one resource is required",severity:"error"});else for(let[n,i]of Object.entries(e.Resources))Ze(n,i,t,r);if(e.Resources){let n=Xe(e.Resources);if(n.length>0)t.push({path:"Resources",message:`Circular dependencies detected: ${n.join(" -> ")}`,severity:"error"})}if(e.Parameters)for(let[n,i]of Object.entries(e.Parameters))Je(n,i,t,r);if(e.Outputs)for(let[n,i]of Object.entries(e.Outputs))Ye(n,i,t,r);return{valid:t.length===0,errors:t,warnings:r}}function Ze(e,t,r,n){if(!t.Type)r.push({path:`Resources.${e}.Type`,message:"Resource Type is required",severity:"error"});if(!/^[a-zA-Z0-9]+$/.test(e))n.push({path:`Resources.${e}`,message:"Logical ID should only contain alphanumeric characters",severity:"warning"});if(t.Type&&!t.Type.startsWith("AWS::")&&!t.Type.startsWith("Custom::"))r.push({path:`Resources.${e}.Type`,message:'Resource Type must start with "AWS::" or "Custom::"',severity:"error"});if(t.Properties){for(let[i,d]of Object.entries(t.Properties))if(d===void 0||d===null)n.push({path:`Resources.${e}.Properties.${i}`,message:"Property has undefined or null value",severity:"warning"})}if(t.DependsOn){if(typeof t.DependsOn==="string"){if(t.DependsOn===e)r.push({path:`Resources.${e}.DependsOn`,message:"Resource cannot depend on itself",severity:"error"})}else if(Array.isArray(t.DependsOn)){if(t.DependsOn.includes(e))r.push({path:`Resources.${e}.DependsOn`,message:"Resource cannot depend on itself",severity:"error"})}}}function Je(e,t,r,n){if(!t.Type)r.push({path:`Parameters.${e}.Type`,message:"Parameter Type is required",severity:"error"});let i=["String","Number","List<Number>","CommaDelimitedList","AWS::SSM::Parameter::Value<String>"];if(t.Type&&!i.includes(t.Type)&&!t.Type.startsWith("AWS::"))n.push({path:`Parameters.${e}.Type`,message:`Uncommon parameter type: ${t.Type}`,severity:"warning"});if(t.NoEcho&&t.Default)n.push({path:`Parameters.${e}`,message:"NoEcho parameters should not have default values",severity:"warning"})}function Ye(e,t,r,n){if(!t.Value)r.push({path:`Outputs.${e}.Value`,message:"Output Value is required",severity:"error"})}function Xe(e){let t={};for(let[s,a]of Object.entries(e)){if(t[s]=[],a.DependsOn){if(typeof a.DependsOn==="string")t[s].push(a.DependsOn);else if(Array.isArray(a.DependsOn))t[s].push(...a.DependsOn)}let l=oe(a);t[s].push(...l)}let r=new Set,n=new Set,i=[];function d(s,a){r.add(s),n.add(s),a.push(s);let l=t[s]||[];for(let p of l)if(!r.has(p)){if(d(p,a))return!0}else if(n.has(p)){let u=a.indexOf(p);return i.push(...a.slice(u),p),!0}return a.pop(),n.delete(s),!1}for(let s of Object.keys(t))if(!r.has(s)){if(d(s,[]))return i}return[]}function oe(e,t=[]){if(typeof e!=="object"||e===null)return t;if(Array.isArray(e)){for(let r of e)oe(r,t);return t}if(e.Ref&&typeof e.Ref==="string"&&!e.Ref.startsWith("AWS::"))t.push(e.Ref);if(e["Fn::GetAtt"]){let r=e["Fn::GetAtt"];if(Array.isArray(r)&&r.length>0)t.push(r[0])}for(let r of Object.values(e))oe(r,t);return t}function Qe(e){let t=[],r=[],n=new TextEncoder().encode(e).length,i=51200,d=460800;if(n>51200)if(n>460800)t.push({path:"template",message:`Template size (${n} bytes) exceeds maximum allowed size of 460800 bytes`,severity:"error"});else r.push({path:"template",message:`Template size (${n} bytes) exceeds direct upload limit (51200 bytes). You must upload to S3 first.`,severity:"warning"});return{valid:t.length===0,errors:t,warnings:r}}function et(e){let t=[],r=[],n=e.Resources?Object.keys(e.Resources).length:0,i=e.Parameters?Object.keys(e.Parameters).length:0,d=e.Outputs?Object.keys(e.Outputs).length:0;if(n>500)t.push({path:"Resources",message:`Template has ${n} resources, exceeding the limit of 500`,severity:"error"});else if(n>200)r.push({path:"Resources",message:`Template has ${n} resources. Consider using nested stacks for better organization.`,severity:"warning"});if(i>200)t.push({path:"Parameters",message:`Template has ${i} parameters, exceeding the limit of 200`,severity:"error"});if(d>200)t.push({path:"Outputs",message:`Template has ${d} outputs, exceeding the limit of 200`,severity:"error"});return{valid:t.length===0,errors:t,warnings:r}}function co(e){let{domains:t,email:r,staging:n=!1,challengeType:i="http-01",certPath:d="/etc/letsencrypt/live",autoRenew:s=!0}=e,a=t[0],l=t.map((u)=>`-d ${u}`).join(" "),p=n?"--staging":"";if(i==="http-01")return tt({domains:t,email:r,staging:n,certPath:d,autoRenew:s,domainFlags:l,stagingFlag:p,primaryDomain:a});else{let u=e.dnsProvider?.provider||(e.hostedZoneId?"route53":void 0);return rt({domains:t,email:r,staging:n,certPath:d,autoRenew:s,domainFlags:l,stagingFlag:p,primaryDomain:a,hostedZoneId:e.hostedZoneId,dnsProvider:e.dnsProvider,dnsProviderType:u})}}function tt(e){let{email:t,certPath:r,autoRenew:n,domainFlags:i,stagingFlag:d,primaryDomain:s}=e;return`
223
223
  # ==========================================
224
224
  # Let's Encrypt Certificate Setup (HTTP-01)
225
225
  # ==========================================
@@ -236,28 +236,28 @@ certbot certonly \\
236
236
  --non-interactive \\
237
237
  --agree-tos \\
238
238
  --email ${t} \\
239
- ${l} \\
240
- ${o}
239
+ ${d} \\
240
+ ${i}
241
241
 
242
242
  # Check if certificate was obtained
243
- if [ -f "${r}/${c}/fullchain.pem" ]; then
243
+ if [ -f "${r}/${s}/fullchain.pem" ]; then
244
244
  echo "Certificate obtained successfully!"
245
245
 
246
246
  # Create symlinks for easier access
247
247
  mkdir -p /etc/ssl/stacks
248
- ln -sf ${r}/${c}/fullchain.pem /etc/ssl/stacks/fullchain.pem
249
- ln -sf ${r}/${c}/privkey.pem /etc/ssl/stacks/privkey.pem
250
- ln -sf ${r}/${c}/cert.pem /etc/ssl/stacks/cert.pem
251
- ln -sf ${r}/${c}/chain.pem /etc/ssl/stacks/chain.pem
248
+ ln -sf ${r}/${s}/fullchain.pem /etc/ssl/stacks/fullchain.pem
249
+ ln -sf ${r}/${s}/privkey.pem /etc/ssl/stacks/privkey.pem
250
+ ln -sf ${r}/${s}/cert.pem /etc/ssl/stacks/cert.pem
251
+ ln -sf ${r}/${s}/chain.pem /etc/ssl/stacks/chain.pem
252
252
  else
253
253
  echo "Failed to obtain certificate!"
254
254
  fi
255
255
 
256
- ${n?oe(c):"# Auto-renewal disabled"}
256
+ ${n?ae(s):"# Auto-renewal disabled"}
257
257
 
258
258
  # Restart the application
259
259
  systemctl start stacks
260
- `}function Qe(e){let{email:t,certPath:r,autoRenew:n,domainFlags:o,stagingFlag:l,primaryDomain:c,hostedZoneId:s,dnsProvider:u,dnsProviderType:h}=e;if(h==="route53"||s){if(!s)throw Error("hostedZoneId is required for DNS-01 challenge with Route53");return`
260
+ `}function rt(e){let{email:t,certPath:r,autoRenew:n,domainFlags:i,stagingFlag:d,primaryDomain:s,hostedZoneId:a,dnsProvider:l,dnsProviderType:p}=e;if(p==="route53"||a){if(!a)throw Error("hostedZoneId is required for DNS-01 challenge with Route53");return`
261
261
  # ==========================================
262
262
  # Let's Encrypt Certificate Setup (DNS-01 via Route53)
263
263
  # ==========================================
@@ -271,27 +271,27 @@ certbot certonly \\
271
271
  --non-interactive \\
272
272
  --agree-tos \\
273
273
  --email ${t} \\
274
- ${l} \\
275
- ${o}
274
+ ${d} \\
275
+ ${i}
276
276
 
277
277
  # Check if certificate was obtained
278
- if [ -f "${r}/${c}/fullchain.pem" ]; then
278
+ if [ -f "${r}/${s}/fullchain.pem" ]; then
279
279
  echo "Certificate obtained successfully!"
280
280
 
281
281
  # Create symlinks for easier access
282
282
  mkdir -p /etc/ssl/stacks
283
- ln -sf ${r}/${c}/fullchain.pem /etc/ssl/stacks/fullchain.pem
284
- ln -sf ${r}/${c}/privkey.pem /etc/ssl/stacks/privkey.pem
285
- ln -sf ${r}/${c}/cert.pem /etc/ssl/stacks/cert.pem
286
- ln -sf ${r}/${c}/chain.pem /etc/ssl/stacks/chain.pem
283
+ ln -sf ${r}/${s}/fullchain.pem /etc/ssl/stacks/fullchain.pem
284
+ ln -sf ${r}/${s}/privkey.pem /etc/ssl/stacks/privkey.pem
285
+ ln -sf ${r}/${s}/cert.pem /etc/ssl/stacks/cert.pem
286
+ ln -sf ${r}/${s}/chain.pem /etc/ssl/stacks/chain.pem
287
287
  else
288
288
  echo "Failed to obtain certificate!"
289
289
  fi
290
290
 
291
- ${n?oe(c):"# Auto-renewal disabled"}
292
- `}if(!u)throw Error("dnsProvider configuration is required for DNS-01 challenge with external DNS providers");let d=u.provider.toUpperCase(),b=Xe(u);return`
291
+ ${n?ae(s):"# Auto-renewal disabled"}
292
+ `}if(!l)throw Error("dnsProvider configuration is required for DNS-01 challenge with external DNS providers");let u=l.provider.toUpperCase(),b=nt(l);return`
293
293
  # ==========================================
294
- # Let's Encrypt Certificate Setup (DNS-01 via ${d})
294
+ # Let's Encrypt Certificate Setup (DNS-01 via ${u})
295
295
  # ==========================================
296
296
 
297
297
  # Install certbot
@@ -302,17 +302,17 @@ ${b}
302
302
  # Create DNS challenge hook scripts directory
303
303
  mkdir -p /etc/letsencrypt/hooks
304
304
 
305
- # Create authenticator hook for ${d}
305
+ # Create authenticator hook for ${u}
306
306
  cat > /etc/letsencrypt/hooks/auth-hook.sh << 'AUTHHOOK'
307
307
  #!/bin/bash
308
- # DNS-01 authenticator hook for ${d}
308
+ # DNS-01 authenticator hook for ${u}
309
309
  # This creates the TXT record for ACME challenge
310
310
 
311
311
  DOMAIN="$CERTBOT_DOMAIN"
312
312
  VALIDATION="$CERTBOT_VALIDATION"
313
313
  RECORD_NAME="_acme-challenge.$DOMAIN"
314
314
 
315
- ${et(u)}
315
+ ${it(l)}
316
316
 
317
317
  # Wait for DNS propagation
318
318
  echo "Waiting 60 seconds for DNS propagation..."
@@ -321,17 +321,17 @@ AUTHHOOK
321
321
 
322
322
  chmod +x /etc/letsencrypt/hooks/auth-hook.sh
323
323
 
324
- # Create cleanup hook for ${d}
324
+ # Create cleanup hook for ${u}
325
325
  cat > /etc/letsencrypt/hooks/cleanup-hook.sh << 'CLEANUPHOOK'
326
326
  #!/bin/bash
327
- # DNS-01 cleanup hook for ${d}
327
+ # DNS-01 cleanup hook for ${u}
328
328
  # This removes the TXT record after validation
329
329
 
330
330
  DOMAIN="$CERTBOT_DOMAIN"
331
331
  VALIDATION="$CERTBOT_VALIDATION"
332
332
  RECORD_NAME="_acme-challenge.$DOMAIN"
333
333
 
334
- ${tt(u)}
334
+ ${ot(l)}
335
335
  CLEANUPHOOK
336
336
 
337
337
  chmod +x /etc/letsencrypt/hooks/cleanup-hook.sh
@@ -345,25 +345,25 @@ certbot certonly \\
345
345
  --non-interactive \\
346
346
  --agree-tos \\
347
347
  --email ${t} \\
348
- ${l} \\
349
- ${o}
348
+ ${d} \\
349
+ ${i}
350
350
 
351
351
  # Check if certificate was obtained
352
- if [ -f "${r}/${c}/fullchain.pem" ]; then
352
+ if [ -f "${r}/${s}/fullchain.pem" ]; then
353
353
  echo "Certificate obtained successfully!"
354
354
 
355
355
  # Create symlinks for easier access
356
356
  mkdir -p /etc/ssl/stacks
357
- ln -sf ${r}/${c}/fullchain.pem /etc/ssl/stacks/fullchain.pem
358
- ln -sf ${r}/${c}/privkey.pem /etc/ssl/stacks/privkey.pem
359
- ln -sf ${r}/${c}/cert.pem /etc/ssl/stacks/cert.pem
360
- ln -sf ${r}/${c}/chain.pem /etc/ssl/stacks/chain.pem
357
+ ln -sf ${r}/${s}/fullchain.pem /etc/ssl/stacks/fullchain.pem
358
+ ln -sf ${r}/${s}/privkey.pem /etc/ssl/stacks/privkey.pem
359
+ ln -sf ${r}/${s}/cert.pem /etc/ssl/stacks/cert.pem
360
+ ln -sf ${r}/${s}/chain.pem /etc/ssl/stacks/chain.pem
361
361
  else
362
362
  echo "Failed to obtain certificate!"
363
363
  fi
364
364
 
365
- ${n?oe(c):"# Auto-renewal disabled"}
366
- `}function Xe(e){switch(e.provider){case"porkbun":return`
365
+ ${n?ae(s):"# Auto-renewal disabled"}
366
+ `}function nt(e){switch(e.provider){case"porkbun":return`
367
367
  # Porkbun API credentials
368
368
  export PORKBUN_API_KEY="${e.apiKey}"
369
369
  export PORKBUN_SECRET_KEY="${e.secretKey}"
@@ -374,7 +374,7 @@ export GODADDY_API_SECRET="${e.apiSecret}"
374
374
  export GODADDY_ENV="${e.environment||"production"}"
375
375
  `;case"route53":return`
376
376
  # Route53 uses IAM role credentials
377
- `;default:return""}}function et(e){switch(e.provider){case"porkbun":return`
377
+ `;default:return""}}function it(e){switch(e.provider){case"porkbun":return`
378
378
  # Extract root domain (last two parts)
379
379
  ROOT_DOMAIN=$(echo "$DOMAIN" | awk -F. '{print $(NF-1)"."$NF}')
380
380
  SUBDOMAIN="_acme-challenge"
@@ -418,7 +418,7 @@ curl -s -X PATCH "$API_URL/v1/domains/$ROOT_DOMAIN/records" \\
418
418
  "data": "'"$VALIDATION"'",
419
419
  "ttl": 600
420
420
  }]'
421
- `;default:return'echo "Unsupported DNS provider"'}}function tt(e){switch(e.provider){case"porkbun":return`
421
+ `;default:return'echo "Unsupported DNS provider"'}}function ot(e){switch(e.provider){case"porkbun":return`
422
422
  # Extract root domain
423
423
  ROOT_DOMAIN=$(echo "$DOMAIN" | awk -F. '{print $(NF-1)"."$NF}')
424
424
 
@@ -461,7 +461,7 @@ fi
461
461
 
462
462
  curl -s -X DELETE "$API_URL/v1/domains/$ROOT_DOMAIN/records/TXT/$RECORD_NAME" \\
463
463
  -H "Authorization: sso-key $GODADDY_API_KEY:$GODADDY_API_SECRET"
464
- `;default:return'echo "Unsupported DNS provider"'}}function oe(e){return`
464
+ `;default:return'echo "Unsupported DNS provider"'}}function ae(e){return`
465
465
  # ==========================================
466
466
  # Certificate Auto-Renewal Setup
467
467
  # ==========================================
@@ -506,7 +506,7 @@ systemctl enable certbot-renewal.timer
506
506
  systemctl start certbot-renewal.timer
507
507
 
508
508
  echo "Certificate auto-renewal configured"
509
- `}function eo(e){let{httpPort:t=80,httpsPort:r=443,certPath:n="/etc/ssl/stacks",redirectHttp:o=!0}=e;return`
509
+ `}function lo(e){let{httpPort:t=80,httpsPort:r=443,certPath:n="/etc/ssl/stacks",redirectHttp:i=!0}=e;return`
510
510
  // HTTPS Server with Let's Encrypt certificates
511
511
  import { readFileSync, existsSync } from 'node:fs'
512
512
 
@@ -532,7 +532,7 @@ if (hasCerts) {
532
532
  })
533
533
  console.log(\`HTTPS server running on port \${HTTPS_PORT}\`)
534
534
 
535
- ${o?`
535
+ ${i?`
536
536
  // Start HTTP server for redirect
537
537
  const httpServer = Bun.serve({
538
538
  port: HTTP_PORT,
@@ -592,5 +592,5 @@ async function handleRequest(request: Request): Promise<Response> {
592
592
  // Implement your request handling here
593
593
  return new Response('Hello from Stacks!')
594
594
  }
595
- `}async function to(e){let{domain:t,challengeValue:r,hostedZoneId:n,dnsProvider:o,region:l="us-east-1"}=e;if(o){let s=await J(o).upsertRecord(t,{name:`_acme-challenge.${t}`,type:"TXT",content:r,ttl:60});if(!s.success)throw Error(`Failed to create DNS challenge record: ${s.message}`);return}if(n){await new j(l).changeResourceRecordSets({HostedZoneId:n,ChangeBatch:{Comment:"ACME DNS-01 challenge",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:`_acme-challenge.${t}`,Type:"TXT",TTL:60,ResourceRecords:[{Value:`"${r}"`}]}}]}});return}throw Error("Either dnsProvider or hostedZoneId must be provided")}async function ro(e){let{domain:t,challengeValue:r,hostedZoneId:n,dnsProvider:o,region:l="us-east-1"}=e;if(o){let s=await J(o).deleteRecord(t,{name:`_acme-challenge.${t}`,type:"TXT",content:r});if(!s.success)console.warn(`Failed to delete DNS challenge record: ${s.message}`);return}if(n){await new j(l).changeResourceRecordSets({HostedZoneId:n,ChangeBatch:{Comment:"Remove ACME DNS-01 challenge",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:`_acme-challenge.${t}`,Type:"TXT",TTL:60,ResourceRecords:[{Value:`"${r}"`}]}}]}});return}throw Error("Either dnsProvider or hostedZoneId must be provided")}function no(e){try{let{execSync:t}=Je("node:child_process"),r=t(`openssl x509 -checkend 2592000 -noout -in ${e}/cert.pem`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return!1}catch{return!0}}import{createHash as we,createSign as rt,generateKeyPairSync as ve}from"node:crypto";var Oe={production:"https://acme-v02.api.letsencrypt.org/directory",staging:"https://acme-staging-v02.api.letsencrypt.org/directory"};class nt{directoryUrl;email;accountKey;accountUrl=null;directory=null;nonce=null;constructor(e){this.directoryUrl=e.staging?Oe.staging:Oe.production,this.email=e.email,this.accountKey=e.accountKey||this.generateAccountKey()}generateAccountKey(){let{privateKey:e}=ve("ec",{namedCurve:"P-256"});return e.export({type:"pkcs8",format:"pem"})}async getDirectory(){if(this.directory)return this.directory;let e=await fetch(this.directoryUrl);if(!e.ok)throw Error(`Failed to fetch ACME directory: ${e.status}`);return this.directory=await e.json(),this.directory}async getNonce(){if(this.nonce){let n=this.nonce;return this.nonce=null,n}let e=await this.getDirectory(),r=(await fetch(e.newNonce,{method:"HEAD"})).headers.get("replay-nonce");if(!r)throw Error("Failed to get nonce from ACME server");return r}getJwk(){let e=this.accountKey.split(`
596
- `).filter((l)=>!l.startsWith("-----")).join(""),t=Buffer.from(e,"base64"),r=t.length-65,n=t.subarray(r+1,r+33),o=t.subarray(r+33,r+65);return{kty:"EC",crv:"P-256",x:this.base64UrlEncode(n),y:this.base64UrlEncode(o)}}getJwkThumbprint(){let e=this.getJwk(),t=JSON.stringify({crv:e.crv,kty:e.kty,x:e.x,y:e.y}),r=we("sha256").update(t).digest();return this.base64UrlEncode(r)}base64UrlEncode(e){return(typeof e==="string"?Buffer.from(e):e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async signPayload(e,t){let r=await this.getNonce(),n=this.getJwk(),o={alg:"ES256",nonce:r,url:e};if(this.accountUrl)o.kid=this.accountUrl;else o.jwk=n;let l=this.base64UrlEncode(JSON.stringify(o)),c=t===""?"":this.base64UrlEncode(JSON.stringify(t)),s=`${l}.${c}`,u=rt("SHA256");u.update(s);let h=u.sign(this.accountKey),d=h.subarray(4,4+h[3]),b=4+h[3]+2,A=h.subarray(b,b+h[b-1]),T=Buffer.alloc(32),g=Buffer.alloc(32);d.copy(T,32-d.length),A.copy(g,32-A.length);let m=Buffer.concat([T,g]);return JSON.stringify({protected:l,payload:c,signature:this.base64UrlEncode(m)})}async acmeRequest(e,t){let r=await this.signPayload(e,t),n=await fetch(e,{method:"POST",headers:{"Content-Type":"application/jose+json"},body:r}),o=n.headers.get("replay-nonce");if(o)this.nonce=o;let l,c=n.headers.get("content-type");if(c?.includes("application/json")||c?.includes("application/problem+json"))l=await n.json();else l=await n.text();if(!n.ok)throw Error(`ACME request failed: ${JSON.stringify(l)}`);return{body:l,headers:n.headers}}async registerAccount(){let e=await this.getDirectory(),{body:t,headers:r}=await this.acmeRequest(e.newAccount,{termsOfServiceAgreed:!0,contact:[`mailto:${this.email}`]}),n=r.get("location");if(!n)throw Error("No account URL returned");return this.accountUrl=n,n}async createOrder(e){if(!this.accountUrl)await this.registerAccount();let t=await this.getDirectory(),{body:r,headers:n}=await this.acmeRequest(t.newOrder,{identifiers:e.map((l)=>({type:"dns",value:l}))}),o=n.get("location");if(!o)throw Error("No order URL returned");return{orderUrl:o,authorizations:r.authorizations,finalize:r.finalize}}async getAuthorization(e){let{body:t}=await this.acmeRequest(e,""),r=t.identifier.value,n=this.getJwkThumbprint(),o=t.challenges.filter((l)=>l.type==="http-01"||l.type==="dns-01").map((l)=>{let c=`${l.token}.${n}`;if(l.type==="http-01")return{type:"http-01",token:l.token,keyAuthorization:c,identifier:`/.well-known/acme-challenge/${l.token}`};else{let s=this.base64UrlEncode(we("sha256").update(c).digest());return{type:"dns-01",token:l.token,keyAuthorization:c,identifier:`_acme-challenge.${r}`,dnsValue:s}}});return{domain:r,challenges:o}}async respondToChallenge(e){await this.acmeRequest(e,{})}async waitForAuthorization(e,t=30){for(let r=0;r<t;r++){let{body:n}=await this.acmeRequest(e,"");if(n.status==="valid")return;if(n.status==="invalid")throw Error(`Authorization failed: ${JSON.stringify(n)}`);await new Promise((o)=>setTimeout(o,2000))}throw Error("Authorization timed out")}generateCsr(e){let{privateKey:t}=ve("rsa",{modulusLength:2048}),r=t.export({type:"pkcs8",format:"pem"});return{csr:this.createSimpleCsr(e,t),privateKey:r}}createSimpleCsr(e,t){throw Error("CSR generation requires additional implementation. Consider using the shell-based certbot approach instead.")}async finalizeOrder(e,t){let{csr:r,privateKey:n}=this.generateCsr(t),{body:o}=await this.acmeRequest(e,{csr:this.base64UrlEncode(Buffer.from(r,"base64"))}),l=o.certificate;if(!l)throw Error("Certificate not immediately available - polling not implemented");let s=await(await fetch(l)).text(),u=s.split(/(?=-----BEGIN CERTIFICATE-----)/g),h=u[0],d=u.slice(1).join("");return{certificate:h,privateKey:n,chain:d,fullchain:s,expiresAt:new Date(Date.now()+7776000000)}}getAccountKey(){return this.accountKey}}var Ne=["js","mjs","cjs","css","map","woff","woff2","ttf","otf","eot","png","jpg","jpeg","gif","webp","avif","svg","ico","mp4","webm","ogg","mp3","wav","pdf","wasm"],it=[{name:"x-stx-router",value:"true"}];function W(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function ke(e){return`{${e.map(W).join(" ")}}`}function ot(e){let t=`http.request.headers[${W(e.name.toLowerCase())}]`;return e.value===void 0?`len(${t}) > 0`:`any(${t}[*] == ${W(e.value)})`}function ae(e){if(e.length===1)return`http.host eq ${W(e[0])}`;return`http.host in ${ke(e)}`}function se(e,t={}){if(t.enabled===!1||e.length===0)return[];let r=ae(e),n=[],l=(t.bypassPaths??[]).map((T)=>`starts_with(http.request.uri.path, ${W(T)})`),s=(t.negotiatedRequestHeaders??it).map(ot),u=[...l,...s],h=u.length>0?`(${u.join(" or ")})`:void 0;if(h)n.push({action:"set_cache_settings",description:"bypass cache",expression:`(${r} and ${h})`,enabled:!0,action_parameters:{cache:!1}});let d=h?`${r} and not ${h}`:r,b=t.assetExtensions??Ne,A=b.length>0?`lower(http.request.uri.path.extension) in ${ke([...b])}`:void 0;if(A)n.push({action:"set_cache_settings",description:"cache fingerprinted assets",expression:`(${d} and ${A})`,enabled:!0,action_parameters:{cache:!0,edge_ttl:{mode:"override_origin",default:t.assetEdgeTtl??2592000},browser_ttl:{mode:"override_origin",default:t.assetBrowserTtl??31536000}}});return n.push({action:"set_cache_settings",description:"cache documents",expression:A?`(${d} and not ${A})`:`(${d})`,enabled:!0,action_parameters:{cache:!0,edge_ttl:{mode:"override_origin",default:t.documentEdgeTtl??3600},browser_ttl:{mode:"override_origin",default:t.documentBrowserTtl??0}}}),n}function ce(e,t,r){if(e.length===0||!t||!r)return[];return[{action:"rewrite",description:"origin guard header",expression:`(${ae(e)})`,enabled:!0,action_parameters:{headers:{[t]:{operation:"set",value:r}}}}]}var N=(e)=>e===void 0?void 0:e?"on":"off";function le(e){let t={ssl:e.ssl,always_use_https:N(e.alwaysUseHttps),automatic_https_rewrites:N(e.automaticHttpsRewrites),min_tls_version:e.minTlsVersion,tls_1_3:N(e.tls13),brotli:N(e.brotli),http3:N(e.http3),"0rtt":N(e.zeroRtt),early_hints:N(e.earlyHints),browser_cache_ttl:e.browserCacheTtl,always_online:N(e.alwaysOnline),websockets:N(e.websockets),email_obfuscation:N(e.emailObfuscation)};if(e.hsts)t.security_header={strict_transport_security:{enabled:e.hsts.enabled,max_age:e.hsts.maxAge??31536000,include_subdomains:e.hsts.includeSubdomains??!1,preload:e.hsts.preload??!1,nosniff:e.hsts.noSniff??!0}};for(let r of Object.keys(t))if(t[r]===void 0)delete t[r];return{...t,...e.raw??{}}}var H={ssl:"strict",alwaysUseHttps:!0,automaticHttpsRewrites:!0,minTlsVersion:"1.2",tls13:!0,brotli:!0,http3:!0,earlyHints:!0,alwaysOnline:!0,emailObfuscation:!1,browserCacheTtl:0};import{connect as at}from"node:tls";async function de(e){let{address:t,serverName:r,port:n=443,timeoutMs:o=5000}=e;return new Promise((l)=>{let c=!1,s=(h)=>{if(c)return;c=!0;try{u.destroy()}catch{}l(h)},u=at({host:t,port:n,servername:r,rejectUnauthorized:!1,timeout:o});u.once("secureConnect",()=>{if(u.authorized){s({reachable:!0,trusted:!0});return}s({reachable:!0,trusted:!1,reason:u.authorizationError?String(u.authorizationError):"origin certificate is not trusted for this hostname"})}),u.once("timeout",()=>{s({reachable:!1,trusted:!1,reason:`no TLS handshake within ${o}ms`})}),u.once("error",(h)=>{s({reachable:!1,trusted:!1,reason:h.message})})})}function st(e,t){let r=t.replace(/\.$/,"").toLowerCase();return e.some((n)=>{let o=n.replace(/\.$/,"").toLowerCase();if(o===r)return!0;if(!o.startsWith("*."))return!1;let l=o.slice(2);if(!r.endsWith(`.${l}`))return!1;return!r.slice(0,r.length-l.length-1).includes(".")})}async function ct(e){let{provider:t,zone:r,hosts:n,ipv4:o,ipv6:l,proxied:c=!0,settings:s=H,cache:u,originGuard:h,purge:d=!0,ttl:b=300,skipOriginProbe:A=!1,skipEdgeCertificateCheck:T=!1}=e,g={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(n.length===0)return g;let m=[],a=c&&!T?await t.listEdgeCertificateHosts(r):null;for(let i of n){let p=c;if(p&&a&&!st(a,i)){p=!1;let C=a.length===0?"the zone has no active edge certificate yet":`no active edge certificate covers it (${a.join(", ")})`;g.deferredProxy.push({host:i,reason:C}),g.warnings.push(`${i}: publishing DNS-only — ${C}. Proxying it would make Cloudflare terminate TLS with no certificate for the name, which fails the handshake outright rather than degrading. Universal SSL covers the apex and ONE level of subdomain, so a deeper name needs its own certificate; otherwise re-run the deploy once the certificate is active.`)}if(p&&!A){let C=await de({address:o,serverName:i});if(!C.trusted){p=!1;let S=C.reason||"origin is not serving a trusted certificate";g.deferredProxy.push({host:i,reason:S}),g.warnings.push(`${i}: publishing DNS-only for now — the origin does not yet serve a certificate this proxy can verify (${S}). The origin issues certificates over HTTP-01, which needs the name to reach it directly; re-run the deploy once it has one and the record will be proxied.`)}}if(p)m.push(i);let f=[{type:"A",content:o}];if(l&&ue(i))f.push({type:"AAAA",content:l});for(let{type:C,content:S}of f){let R=await t.upsertRecord(r,{name:i,type:C,content:S,ttl:b,proxied:p});if(R.success)g.records.push({host:i,type:C,content:S,proxied:p});else g.warnings.push(`${i} ${C} → ${S} failed: ${R.message||"unknown provider error"}`)}}if(m.length===0){if(c)g.warnings.push("No host is proxied yet, so zone settings, cache rules and purge were skipped — they only take effect through the proxy.");return g}try{let i=le(s),p=await t.applyZoneSettings(r,i);g.settingsChanged=p.changed;for(let f of p.failed)g.warnings.push(`zone setting '${f.id}' could not be applied: ${f.error}`)}catch(i){g.warnings.push(`zone settings could not be read: ${i instanceof Error?i.message:String(i)}`)}let y=se(m,u);if(y.length>0){let i=await t.putManagedPhaseRules(r,"http_request_cache_settings",y);if(i.success)g.cacheRules=y.length;else g.warnings.push(`cache rules could not be written: ${i.message}`)}if(h){let i=ce(m,h.header,h.value);if(i.length>0){let p=await t.putManagedPhaseRules(r,"http_request_late_transform",i);if(p.success)g.originGuard=!0;else g.warnings.push(`origin guard header could not be written: ${p.message}. `+"The gateway will reject requests that lack it — disable the guard or grant the token Transform Rules: Edit.")}}if(d){if(g.purged=await t.purgeCache(r,{hosts:m}),!g.purged)g.warnings.push("edge cache purge failed — new content may take until TTL expiry to appear.")}return g}var lt=(e)=>process.env[e];function xe(e,t){let r=e.replace(/\.$/,"").toLowerCase();if(t){let n=t.replace(/\.$/,"").toLowerCase();if(r===n||r.endsWith(`.${n}`))return n}return r.split(".").slice(-2).join(".")}function dt(e,t={}){let r=t.env??lt,n=e.infrastructure?.compute?.proxy?.cdn,o=[];if(!n||n.provider!=="cloudflare")return{plan:null,errors:o};if(n.originDomain)o.push(`compute.proxy.cdn.originDomain (${n.originDomain}) is ignored for Cloudflare: the proxy forwards to the address in the record it fronts, `+"so no separate origin hostname is needed — and publishing one gives clients a documented way around the edge.");let l=r("CLOUDFLARE_API_TOKEN");if(!l)return o.push("CLOUDFLARE_API_TOKEN is not set — the Cloudflare CDN cannot be reconciled."),{plan:null,errors:o};let c=e.sites??{},s=n.frontedHosts?.length?[...new Set(n.frontedHosts.map((A)=>A.toLowerCase()))]:pe(c,{autoWww:e.infrastructure?.compute?.proxy?.autoWww!==!1});if(s.length===0)return o.push("No hostnames to front — set compute.proxy.cdn.frontedHosts, or give a site a domain."),{plan:null,errors:o};let u=e.infrastructure?.dns?.domain,h=new Set(s.map((A)=>xe(A,u)));if(h.size>1)return o.push(`Fronted hosts span more than one zone (${[...h].join(", ")}). A Cloudflare zone is configured as a unit, so run one CDN config per zone.`),{plan:null,errors:o};let d=n.cloudflare??{},b=n.secret?{header:n.secretHeader??"X-Origin-Verify",value:n.secret}:void 0;return{plan:{zone:[...h][0],hosts:s,apiToken:l,zoneId:d.zoneId??r("CLOUDFLARE_ZONE_ID"),accountId:d.accountId??r("CLOUDFLARE_ACCOUNT_ID"),proxied:d.proxied!==!1,settings:d.settings??H,cache:d.cache,originGuard:b,purge:d.purgeOnDeploy!==!1,skipOriginProbe:d.skipOriginProbe===!0},errors:o}}export{Du as ABTestManager,hr as ACMClient,yr as ACMDnsValidator,Oe as ACME_DIRECTORIES,M as AI,xf as API_IDEMPOTENCY_TTL_MS,Nf as API_TOKEN_DEFAULT_TTL_MS,kf as API_TOKEN_MAX_TTL_MS,Vy as API_VERSION,Cf as AUTHORIZATION_CAPABILITIES,of as AUTH_ACTION_TOKEN_TTL_MS,af as AUTH_MFA_CHALLENGE_TTL_MS,sf as AUTH_OIDC_TRANSACTION_TTL_MS,nf as AUTH_SESSION_ABSOLUTE_TTL_MS,rf as AUTH_SESSION_IDLE_TTL_MS,Fc as AWSAPIError,bt as AWSClient,Le as AWSCloudFormationClient,Me as AWSCloudFrontClient,gu as AWSConfigManager,Os as AWS_PSEUDO_PARAMETERS,Id as AWS_REGIONS,nt as AcmeClient,Dt as AlertEvaluator,It as AlertStore,Gh as AnomalyConfigStore,Pe as ApiGateway,ky as ApiServiceError,Gr as ApplicationAutoScalingClient,vs as Arn,Ps as AssetHasher,Ts as Auth,cf as AuthenticationStore,Ly as AutomationApiService,Lf as AutomationIdentityStore,tS as AwsAuroraDataAdapter,aS as AwsAuroraTransport,QS as AwsDatabaseBackupSource,Sn as AwsDriver,rS as AwsElastiCacheDataAdapter,sS as AwsElastiCacheTransport,jy as AwsIamCapabilityScanner,sA as AwsInfrastructureBackupSource,eS as AwsRdsDataAdapter,oS as AwsRdsTransport,wS as AwsRegionalDriver,pA as AwsSecretsManagerConfigurationBackend,vy as AwsSpendTransport,mA as AwsSsmConfigurationBackend,JS as BackupCoordinator,uu as BackupManager,US as BackupStore,zp as BatchProcessingManager,kr as BedrockClient,Nr as BedrockRuntimeClient,xg as BitbucketSourceAdapter,Tu as BlueGreenManager,Dp as BounceComplaintHandler,np as BuildOptimizationManager,cS as BunDockerRuntime,iA as BunDockerVolumeRuntime,tA as BunFilesystemArchiveRuntime,ms as CDN,pt as CHAIN_HEADER,Qt as CLOUDFLARE_MANAGED_RULE_PREFIX,Ud as COMMON_CROSS_ACCOUNT_ROLES,hf as CONTROL_PLANE_SCHEMA_VERSION,ne as Cache,Pu as CanaryManager,Yu as CertificateManager,hg as CloudBlockVolumeDriver,In as CloudDriverFactory,Nc as CloudError,Ns as CloudFormationBuilder,Le as CloudFormationClient,Me as CloudFrontClient,yu as CloudTrailManager,Pr as CloudWatchLogsClient,Xt as CloudflareProvider,md as CommandHistory,Es as Communication,Ag as ComposeApplicationService,Sg as ComposeApplicationStore,xr as ComprehendClient,w as Compute,Oy as ComputeSpendTransport,kc as ConfigurationError,gA as ConfigurationService,cA as ConfigurationStore,Ir as ConnectClient,iS as ContainerDataAdapter,op as ContainerRegistryManager,aA as ControlPlaneBackupSource,HS as ControlPlaneCleanupDriver,vf as ControlPlaneStore,hh as CounterTracker,xc as CredentialError,Cd as CrossRegionReferenceManager,Qs as DASHBOARD_ENTRY,Xs as DASHBOARD_PORT_BASE,ec as DASHBOARD_PORT_SPAN,Ys as DASHBOARD_STATE_DIR,ai as DEFAULT_ATTACK_MODE_HOURS,Nt as DEFAULT_DDOS_THRESHOLDS,mh as DEFAULT_METER_MAPPINGS,ih as DEFAULT_PRICE_BOOK,gt as DEFAULT_RECURSION_LIMITS,Zc as DEFAULT_SERVICE_LIMITS,La as DEFAULT_STATE_DIR,Ne as DEFAULT_STATIC_ASSET_EXTENSIONS,cy as DEFAULT_TELEMETRY_POLICY,Ah as DEFAULT_THRESHOLDS,ig as DEPLOYMENT_QUEUE_KINDS,ut as DEPTH_HEADER,Uh as DETECTABLE_SIGNALS,OC as DIAGNOSTIC_PRESETS,Wp as DLQMonitoringManager,fs as DNS,Tp as DNSSECManager,QC as DataServiceLifecycle,JC as DataServiceStore,q as Database,Uu as DatabaseUserManager,Wc as DebugLogger,ls as DependencyGraph,$s as Deployment,Lc as DeploymentError,mu as DisasterRecoveryManager,fr as DnsProviderFactory,lS as DockerDataTransport,RC as DockerDiscoveryAdapter,fg as DockerNamedVolumeDriver,oA as DockerVolumeBackupSource,eg as DurableOperationQueue,tg as DurableQueueWorker,wr as DynamoDBClient,qt as EC2Client,Cr as ECRClient,Sr as ECSClient,Zr as EFSClient,Dr as ELBv2Client,jg as ENFORCEMENT_ACTIONS,wh as ENFORCEMENT_DESCRIPTIONS,Jg as ENFORCEMENT_SEVERITY,IC as EcsRuntimeAdapter,ri as EdgeRateLimiter,Hr as ElastiCacheClient,L as Email,Lp as EmailAdvanced,wp as EmailAnalyticsManager,Pt as EmailClient,Mp as EmailHandlers,kp as EmailTemplateManager,dS as EncryptedDataSecretStore,Vc as ErrorCodes,Wr as EventBridgeClient,GC as EventBridgeJobAdapter,fA as ExternalConfigurationBackend,_p as FIFOQueueManager,Jh as FOCUS_VERSION,Qc as FileCache,K as FileSystem,rA as FilesystemBackupSource,gS as FleetService,fS as FleetStore,ws as Fn,Lg as GiteaSourceAdapter,Ng as GithubSourceAdapter,kg as GitlabSourceAdapter,Sd as GlobalResourceManager,Yt as GoDaddyProvider,Su as GuardDutyManager,cl as HashCache,_m as HealthCheckManager,vt as HealthCheckRunner,An as HetznerClient,$n as HetznerDriver,Rt as IAMClient,Qr as IPV6_EXCLUDED_HOST_LABELS,tp as ImageScanningManager,He as InfrastructureGenerator,$f as InvalidOperationTransitionError,ys as JobLoader,UC as JobProviderReconciler,qC as JobService,WC as JobStore,Br as KendraClient,wm as LARAVEL_SERVERLESS_BUILD_STEPS,$r as LambdaClient,mp as LambdaConcurrencyManager,Sp as LambdaDLQManager,gp as LambdaDestinationsManager,lp as LambdaLayersManager,DC as LambdaRuntimeAdapter,yp as LambdaVPCManager,up as LambdaVersionsManager,uA as LocalEncryptedConfigurationBackend,nA as LogicalDatabaseBackupSource,Lu as LogsManager,Xp as MANAGED_NODE_VERSIONS,Hn as MANAGEMENT_DASHBOARD_SITE,oc as MANAGEMENT_DASHBOARD_SITE_PREFIX,oi as MAX_CONTROL_HOURS,Ef as MAX_CONTROL_PLANE_ERROR_BYTES,Df as MAX_CONTROL_PLANE_JSON_BYTES,Zg as METERS,qg as METER_KEYS,Yg as MICRO_CENTS,Ph as MIN_PROJECTION_CONFIDENCE,rn as MTA_STS_PORT,_S as MaintenanceService,FS as MaintenanceStore,bs as Messaging,ku as MetricsManager,_u as MigrationManager,Nl as MockCloudFormation,xl as MockDynamoDB,kl as MockS3,Ie as Monitoring,_d as MultiAccountManager,hd as MultiRegionManager,Yl as MultiStepProgress,Re as Network,Wm as NetworkSecurityManager,wt as NotificationRouter,vr as OpenSearchClient,Tf as OptimisticConcurrencyError,Bd as OrganizationManager,Om as PHP_DEFAULT_EXCLUDES,im as PHP_LAYER_EXTENSIONS,jt as PROXIABLE_RECORD_TYPES,Ds as ParameterStore,zu as PerformanceManager,$e as Permissions,_r as PersonalizeClient,hs as Phone,Fp as PhoneAdvanced,gs as PhoneHandlers,SS as PlacementService,CS as PlacementStore,Fr as PollyClient,Jt as PorkbunProvider,zy as PreDeployScanner,Ml as PreviewEnvironmentManager,ng as PreviewEnvironmentService,rg as PreviewEnvironmentStore,Wl as PreviewNotificationService,Jl as ProgressBar,wu as ProgressiveDeploymentManager,si as ProtectionControlStore,Ya as Pseudo,re as Queue,Yf as QueueCancellationError,Up as QueueManagementManager,ka as QueuePresets,Qf as QueueTimeoutError,Qn as RATE_LIMIT_KEY_SEPARATOR,Er as RDSClient,zd as RECOMMENDED_ACCOUNT_STRUCTURES,Gd as RECOMMENDED_SCPS,Eg as RELEASE_QUEUE_KINDS,dd as REPL,pd as REPLCommandBuilder,ud as REPLContext,gl as RateLimiter,xa as RealtimePresets,sy as RecordingSpendTransport,Ct as RecursionGuard,Z as Redirects,Ad as RegionPairManager,DS as RegionService,IS as RegionStore,ps as Registry,Lr as RekognitionClient,$g as ReleaseService,Tg as ReleaseStore,AS as RemoteBuildService,Wu as ReplicaManager,zm as ResourceManagementManager,Xf as RetryableOperationError,j as Route53Client,Zt as Route53DomainsClient,ir as Route53Provider,Pp as Route53ResolverManager,bp as Route53RoutingManager,NC as RuntimeOperationService,kC as RuntimeStreamRegistry,jS as S3BackupDestinationAdapter,Tt as S3Client,vc as S3Error,Hy as SECRET_PATTERNS,Hh as SENSITIVITY_THRESHOLDS,$t as SESClient,As as SMS,Rr as SNSClient,Ey as SPEND_CYCLE_SECONDS,ry as SPEND_GATE_SETTING,Py as SPEND_LEASE_SETTING,Tr as SQSClient,Ar as SSMClient,Ma as STATE_DIR_ENV_VAR,H as STATIC_SITE_ZONE_SETTINGS,Bt as STSClient,zr as SchedulerClient,De as Search,qy as SecretFindingScanner,Is as Secrets,ju as SecretsManager,br as SecretsManagerClient,qu as SecretsRotationManager,te as Security,bu as SecurityHubManager,Wy as SecurityPostureStore,Ky as SecurityScannerRunner,Xu as SecurityScanningManager,Op as SenderReputationManager,zC as ServerCronJobAdapter,nS as ServerDataAdapter,gg as ServerPathVolumeDriver,sp as ServiceMeshManager,Te as Sftp,qh as SignalSource,Vp as SmsAdvanced,Ur as SmsClient,Ss as SmsHandlers,vg as SourceConnectionStore,Og as SourceProviderError,iy as SpendCapError,ny as SpendGate,Iy as SpendLoopLease,$y as SpendNotificationRouter,Dy as SpendRunner,ey as SpendService,bh as SpendStore,Ql as Spinner,pS as SshFleetDriver,bd as StackDependencyManager,Cs as StacksIntegration,Lm as StaticSiteManager,ee as Storage,Fm as StorageAdvancedManager,qr as SupportClient,Fu as SyntheticsManager,uS as SystemFleetSshTransport,PC as SystemdDiscoveryAdapter,mt as TRACE_HEADER,Xl as TaskList,Ay as TelemetryStore,Se as TemplateBuilder,Xc as TemplateCache,Mr as TextractClient,Or as TranscribeClient,Vr as TranslateClient,zS as TransportDisasterRecoveryDriver,WS as TransportPlatformMaintenanceDriver,RS as TransportRemoteBuildDriver,Zy as TrivyImageScanner,Mf as TsCloudApiError,Ff as TsCloudClient,by as URGENT_SPEND_EVENTS,vh as USER_VISIBLE_ACTIONS,vS as UnavailableRegionalDriver,lr as UnifiedDnsValidator,Pf as UnsupportedSchemaVersionError,Mc as ValidationError,Kr as VoiceClient,pg as VolumeService,sg as VolumeStore,Rs as Workflow,Ou as XRayManager,Eu as abTestManager,Ig as activateImmutableRelease,gC as ageSeconds,Ch as aggregateDeltas,ds as analyzeStackDiff,Wh as anomalyOptionsForSignal,di as applyControlsToDdos,li as applyControlsToRateLimits,_t as applyMitigationFactor,sr as applyZoneMigration,Yp as artifactKey,Rg as assertReleaseStrategy,oy as assertSpendAllows,tC as attachProvenanceToRelease,Qy as attachSbomToRelease,Xy as attachVulnerabilitySummary,df as authEncryptionKeyFile,bf as authorizeOrganization,vC as authorizeRuntimePath,od as autocomplete,hu as awsConfigManager,ZS as backupCredentialStatus,pu as backupManager,dl as batch,Gp as batchProcessingManager,ff as beginOidcAuthorization,$u as blueGreenManager,Ep as bounceComplaintHandler,lh as budgetWindow,bi as buildAndPushServerlessImage,um as buildBunRuntimeLayerZip,ks as buildCloudFormationTemplate,jf as buildComposeLogsCommand,qf as buildComposeRuntimeCommand,Zf as buildComposeScaleCommand,Jf as buildComposeShellCommand,Ti as buildFunctionEnv,Wn as buildHostCleanupScript,ja as buildMailEnv,qn as buildManagementDashboardArtifact,_i as buildMediaCdnPlan,tn as buildMtaStsPolicy,nn as buildMtaStsServer,dm as buildNodeRuntimeLayerZip,ip as buildOptimizationManager,ce as buildOriginGuardRule,vm as buildPhpRuntimeLayerZip,_n as buildSiteDeployScript,En as buildSshArgs,se as buildStaticSiteCacheRules,Bn as buildStaticSiteDeployScript,hC as bytes,Iu as canaryManager,OS as canonicalJson,pC as capabilities,yS as capacity,bl as categorizeChanges,Qu as certificateManager,Uc as checkIAMPermissions,ym as checkInvocation,jc as checkServiceQuotas,hl as chunk,ro as cleanupDns01Challenge,wa as clearSigningKeyCache,Wg as cloneSourceBinding,$l as cloudConfigSchema,Dn as cloudDrivers,Cu as cloudTrailManager,km as collectPhpAppEntries,jr as collectServerDnsDomains,Cg as completeComposeVolumeDeletion,gf as completeOidcAuthorization,uc as composePresets,Kf as composeProjectName,nm as composeServerlessAppTemplate,Ny as compositeSpendTransport,XS as compressBackup,Zm as config,YC as connectionGuidance,ap as containerRegistryManager,If as controlPlaneDatabaseFile,yf as controlPlaneMigrations,Bs as createApiBackendPreset,By as createApiV1Handler,PS as createAsgBuildDriver,YS as createBackupQueueHandlers,$m as createCliHandler,Pn as createCloudDriver,Ce as createCloudFrontPolicy,Ic as createCredentialProvider,Js as createDashboardSite,Us as createDataPipelinePreset,XC as createDataServiceQueueHandlers,ag as createDeploymentQueueHandlers,J as createDnsProvider,$S as createEcsBuildDriver,ay as createEnforcementHandlers,Bc as createError,Vs as createExistingStaticFullStackPreset,mS as createFleetQueueHandlers,_s as createFullStackAppPreset,ur as createGoDaddyValidator,Pm as createHandlers,Rm as createHttpHandler,Hs as createJamstackPreset,ZC as createJobQueueHandlers,Zs as createLaravelPreset,Ks as createMLApiPreset,BS as createMaintenanceQueueHandlers,Mi as createMediaAccessToken,zs as createMicroservicesPreset,Ll as createMockAWS,Ls as createNodeJsServerPreset,Ms as createNodeJsServerlessPreset,Kt as createObjectStorageClient,dr as createPorkbunValidator,pc as createPreset,Ra as createPresignedUrl,Ta as createPresignedUrlAsync,Tm as createQueueHandler,Gs as createRealtimeAppPreset,ES as createRegionQueueHandlers,eC as createReleaseProvenance,wg as createReleaseQueueHandlers,bS as createRemoteBuildQueueHandlers,pr as createRoute53Validator,EC as createRuntimeAdapters,Oc as createS3Client,TS as createServerBuildDriver,js as createServerlessLaravelPreset,Fs as createServerlessNodePreset,Mg as createSourceAdapter,xs as createStaticSitePreset,qs as createTraditionalWebAppPreset,mg as createVolumeQueueHandlers,Ws as createWordPressPreset,qp as createZip,Rd as crossRegionReferenceManager,vi as dashboardActions,zn as dashboardCredentialsFile,jC as dataServiceCapabilities,Ku as databaseUserManager,Jm as decodeBase32,eA as decompressBackup,qS as decryptBackup,Um as defaultConfig,Il as defaultLocalConfig,ii as defaultRateLimitRules,Ci as deleteStaticSite,jn as deployAllComputeSites,$i as deployServerlessApp,Ai as deploySite,Zn as deploySiteRelease,gi as deployStaticSite,Si as deployStaticSiteFull,pi as deployStaticSiteWithExternalDns,mi as deployStaticSiteWithExternalDnsFull,Ga as deploymentCoexistenceError,tc as deriveManagementDashboardPort,ci as describePosture,HC as desiredJobProviderState,_h as detectAnomalies,Ha as detectDeploymentTargets,mr as detectDnsProvider,Bh as detectLatestAnomaly,zc as detectMisconfigurations,Sa as detectServiceRegion,Bf as diffCompose,Cl as diffTemplates,Bg as discoverGitRefs,mf as discoverOidcProvider,yC as discoverRuntimeInventory,Hp as dlqMonitoringManager,gr as dnsProviders,$p as dnssecManager,bC as dockerWorkloads,kS as documentDigest,fu as drManager,CC as ecsWorkloads,Rf as effectiveCapabilities,vp as emailAnalyticsManager,xp as emailTemplateManager,jm as encodeBase32,KS as encryptBackup,iC as ensureDefaultSecurityPolicies,Ln as ensureFirewall,Kn as ensureManagementDashboard,Mn as ensureServer,xn as ensureSshKey,pn as escapeSecLang,Dh as evaluateBudget,Ot as evaluateTelemetryAlertRules,_C as eventBridgeScheduleInput,Am as eventToRequest,Vh as ewma,_f as exportCompose,or as exportRoute53Zone,dc as extendPreset,Bp as fifoQueueManager,sl as findChangedFiles,fh as findMapping,Xg as findPriceEntry,jd as formatAccountStructure,Kl as formatBytes,Ry as formatCents,us as formatDiff,ql as formatDuration,sd as formatFlagSuggestions,fd as formatHistory,gd as formatHistoryStats,jl as formatKeyValue,Zl as formatList,Ul as formatProgressBar,Md as formatRegion,Fd as formatRegionList,Uy as formatScanResults,td as formatSuggestion,zl as formatTable,$h as formatTimeToExhaustion,Gl as formatTree,Rc as fromEC2Metadata,Tc as fromECSMetadata,Ac as fromEnvironment,bc as fromSharedCredentials,$c as fromWebIdentity,ft as functionFingerprint,pe as gatewayHostnames,cm as generateAppImageDockerfile,lu as generateApprovalConfig,Zp as generateBootstrap,_l as generateCleanupWorkflow,Bl as generateCostReportWorkflow,qd as generateCrossAccountRoleCF,Jy as generateCycloneDxSbom,au as generateDeploymentConfig,tu as generateDeploymentPipeline,Jd as generateDeploymentWorkflow,ui as generateExternalDnsStaticSiteTemplate,eo as generateHttpsServerCode,Yy as generateImageSbom,Xi as generateLetsEncryptUserData,be as generateLogicalId,ou as generateManualPipeline,eu as generateMatrixWorkflow,su as generateMultiEnvConfig,ru as generateMultiEnvPipeline,Yd as generateMultiEnvWorkflow,Qd as generatePRPreviewWorkflow,du as generateParallelConfig,Im as generatePhpFpmConfig,sm as generatePhpLayerDockerfile,nu as generatePreviewPipeline,Vl as generatePreviewWorkflow,Ae as generateResourceName,cu as generateScheduledConfig,iu as generateScheduledPipeline,Xd as generateScheduledWorkflow,fi as generateStaticSiteTemplate,Cn as generateUbuntuAppCloudInit,wc as getAccountId,Ed as getAllRegions,kd as getClosestRegion,cd as getCommandUsage,Hf as getComposeTemplate,Km as getConfig,nd as getContextualHelp,Pc as getCredentials,Rl as getDeploymentStrategy,Tl as getDiffStats,Sl as getDiffSummary,_c as getErrorDetails,Dl as getLocalConfig,vl as getLocalCredentials,wl as getLocalEndpoint,Ol as getLocalEnvVars,Jc as getQuotaUsageSummary,Kd as getRecommendedStructure,Dd as getRegion,Vd as getRegionStats,vd as getRegionsByCompliance,wd as getRegionsByLocation,Od as getRegionsByPricingTier,Kc as getRequiredPermissions,va as getSigningKeyCacheSize,Qa as getTimestamp,Xn as globMatches,fn as globToRegex,Td as globalResourceManager,Ih as governingLimitCents,Au as guardDutyManager,My as handleSpendRequest,un as hasAutoWwwVariant,ic as hasManagementDashboardSite,an as hasProxyUpstream,nl as hashBuffer,il as hashDirectory,tl as hashFile,ol as hashManifest,rl as hashString,Bm as healthCheckManager,ue as hostAcceptsIpv6,ae as hostCondition,Ym as hotp,uh as hourBucket,ph as hourBucketsBetween,rp as imageScanningManager,Ri as infraEnvFromOutputs,yt as inspectInvocation,fm as installRecursionFetch,yi as invalidateCache,pm as invocationContext,rd as isLikelyTypo,El as isLocalDevelopment,sc as isManagementDashboardSiteName,Oa as isNodeCryptoAvailable,xh as isOperationAllowed,Et as isQuietHours,mn as isSafePattern,Wa as isStatePath,kt as isValidCidr,Nd as isValidRegion,oh as isValidTimeZone,Na as isWebCryptoAvailable,FC as jobProviderCapability,Ht as keyMatchesFilters,fp as lambdaConcurrencyManager,Ap as lambdaDLQManager,hp as lambdaDestinationsManager,dp as lambdaLayersManager,Cp as lambdaVPCManager,pp as lambdaVersionsManager,SC as lambdaWorkloads,Em as laravelServerlessEnvDefaults,Wf as listComposeTemplates,Gg as listSourceReferences,qm as loadCloudConfig,uy as loadTelemetryPolicy,Mu as logsManager,jh as lookbackHoursForSignal,Ka as mailEnabled,Za as mailFirewallPorts,VS as maintenanceWindowOpen,$a as makeAWSRequest,Ia as makeAWSRequestAsync,Pa as makeAWSRequestOnce,ac as managementDashboardSiteName,NS as manifestDigest,ef as matchTotpCounter,Vi as mediaObjectHeaders,Lh as median,Mh as medianAbsoluteDeviation,Eh as mergeDecisions,mc as mergeInfrastructure,nh as mergePriceBooks,yh as meterTelemetry,xu as metricsManager,zt as migrateObjectStorage,Bu as migrationManager,Wd as multiAccountManager,yd as multiRegionManager,no as needsRenewal,Hm as networkSecurityManager,LC as nextScheduleRuns,Yr as normalizePublicIpv6,mC as normalizeRuntimeStatus,xC as normalizeScheduleExpression,Fg as normalizeSourceEvent,Rn as normalizeSshPublicKey,ly as normalizeTelemetryPolicy,_y as openApiDocument,Zh as optionsForSignal,Hd as organizationManager,xm as packagePhpApp,Qp as packageServerlessApp,ll as parallel,ul as parallelMap,pl as parallelWithRetry,ht as parseChain,Vf as parseCompose,Gf as parseComposeCatalog,AC as parseDockerInspect,lA as parseDotenv,Ea as parseJSONResponse,TC as parseSystemdRecords,Da as parseXMLResponse,hy as pathTemplate,Th as percentOfLimit,Gu as performanceManager,am as phpLayerBuildStage,om as phpLayerPackages,Dm as phpRuntimeLayerAssets,Uf as planComposeTemplateUpgrade,Oh as planEnforcement,Vt as planMitigation,ar as planZoneMigration,er as policyTag,Fl as previewManager,Hl as previewNotifications,MC as previewSchedule,dh as previousBudgetWindow,eh as priceUsage,th as priceUsageLines,de as probeOriginTls,yl as processInChunks,Vg as processSourceWebhook,cC as productionChangeReview,vu as progressiveDeploymentManager,Rh as projectSpend,St as propagationHeaders,Gt as providerEndpoint,xS as publicKeyFingerprint,tr as qualifyName,Kp as queueManagementManager,al as quickHash,ni as rateLimitHeaders,ti as rateLimitKey,Xr as reconcileAddressRecords,ct as reconcileCloudflareCdn,nr as reconcileDeclaredRecords,BC as reconcileJobObservation,Ug as reconcileSourceWebhook,sC as recordDashboardHostPosture,oC as recordPreDeploySecretScan,aC as recordSkippedSecretScan,At as recursionBlockedResponse,fC as redactRuntimeConfig,fy as redactTelemetryText,gy as redactTelemetryValue,Pi as redeployServerlessApp,$d as regionPairManager,bg as releaseStrategyCapabilities,Pg as releaseTrafficPlan,Jn as reloadRpxGateway,Wt as remapKey,Kg as removeSourceWebhook,Jr as removeStaleServerAddressRecords,zf as renderComposeTemplate,Ft as renderDdosInstallScript,Mt as renderNftablesRuleset,VC as renderServerCron,Lt as renderSysctlFile,gn as renderWafConfig,hn as renderWafInstallScript,Yn as renewRpxCertificates,Hu as replicaManager,xy as requestHash,Al as requiresReplacement,hm as resetRecursionRuntime,Sm as resolveApp,Ua as resolveAppDatabase,uf as resolveAuthEncryptionKey,Ja as resolveCloudProvider,dt as resolveCloudflareCdnPlan,Dc as resolveCredentials,Oi as resolveDashboardAction,Gn as resolveDashboardAuth,rc as resolveDashboardDomain,nc as resolveDashboardDomains,rr as resolveDeclaredRecords,os as resolveDeployBucketName,za as resolveDeploymentMode,Vn as resolveExecStart,bn as resolveHetznerApiToken,qa as resolveMailService,lc as resolveManagementDashboardSite,cc as resolveManagementDashboardSites,Ut as resolveObjectStorage,es as resolveProjectStackName,on as resolveProxyUpstreams,rm as resolveQueueNames,og as resolveQueuedDeploymentCommand,tm as resolveQueues,mm as resolveRecursionConfig,Ec as resolveRegion,wC as resolveRuntimeInventory,as as resolveServerlessAppStackName,ss as resolveServerlessArtifactBucketName,cs as resolveServerlessAssetBucketName,em as resolveServerlessRuntime,ns as resolveSiteBucketName,sn as resolveSiteDeployTarget,cn as resolveSiteKind,rs as resolveSiteResourceName,ts as resolveSiteStackName,Ba as resolveStatePath,is as resolveStorageBucketName,Un as resolveUiSource,xe as resolveZoneApex,Gm as resourceManagementManager,bm as responseToResult,Fh as robustZScore,Sf as roleCapabilities,Dg as rollbackImmutableRelease,Ii as rollbackServerlessApp,rh as roundCents,Ip as route53ResolverManager,Rp as route53RoutingManager,zh as routeMatches,ei as ruleMatches,jp as runBuildHooks,Nh as runEnforcement,Nm as runPhpBuildHooks,Ei as runRemoteCommand,dC as runtimeId,wi as sanitizeCloudConfig,wf as sanitizeControlPlaneValue,Xa as sanitizeName,pf as sanitizeOidcReturnPath,py as saveTelemetryPolicy,Gy as scanForSecrets,Af as scopeContains,Sh as scopeKey,On as scpUpload,id as searchCommands,Of as searchControlPlane,Ju as secretsManager,Zu as secretsRotationManager,lC as secureContainerRelease,Ru as securityHubManager,ep as securityScanningManager,nC as securityScope,lf as sendAuthenticationEmail,Np as senderReputationManager,ml as sequence,dA as serializeDotenv,Fn as serverPublicIpv4,cp as serviceMeshManager,Di as setMaintenance,Fa as setStateDir,to as setupDns01Challenge,Jp as sha256,gm as sharedRecursionGuard,lm as sharedRuntimeLoop,dn as shipsARelease,Li as signCloudFrontCookies,xi as signCloudFrontUrl,Aa as signRequest,ba as signRequestAsync,Kh as signalDefinition,Ty as spendNotificationText,Fy as spendOpenApiPaths,wn as sshExec,vn as sshExecOrThrow,Pd as stackDependencyManager,Ni as startLocalDashboardServer,wy as startSpendLoop,Va as stateDir,_a as statePath,Mm as staticSiteManager,Vm as storageAdvancedManager,Xh as streamFocusJsonl,kh as strongestActiveAction,ed as suggestCommand,ad as suggestFlags,qc as suggestIAMPolicy,Yc as suggestQuotaIncrease,Ld as suggestRegionPairs,xd as suggestRegions,zg as syncSourceRepositories,yg as synchronizeComposeVolumes,hA as synchronizeConfiguredConfiguration,KC as synchronizeConfiguredJobs,Vu as syntheticsManager,xt as sysctlHardening,$C as systemdWorkloads,Sy as telemetryBucketLabel,yy as telemetryCursor,my as telemetryEstimatedMonthlyCost,Cy as telemetryPercentile,dy as telemetryPolicyKey,el as templateCache,Hg as testSourceConnection,Qg as tieredMicroCents,le as toCloudflareZoneSettings,Qh as toFocusJsonl,Yh as toFocusRecords,Qm as totp,tf as totpUri,uC as unsupportedCapabilities,cg as unsupportedVolumeCapabilities,MS as updateCompatibility,hi as uploadStaticFiles,gh as usageDeltaKey,ch as utcInstantOfLocal,Zd as validateAccountStructure,Pl as validateAgainstSchema,ug as validateAttachment,GS as validateBackupDestination,ld as validateCommand,Hc as validateConfiguration,Gc as validateCredentials,ln as validateDeploymentConfig,dg as validateMountPath,je as validateResourceLimits,ze as validateTemplate,Ze as validateTemplateSize,en as verifyAddressRecord,rC as verifyArtifactSignature,Fi as verifyMediaAccessToken,Xm as verifyTotp,LS as verifyUpdateSignature,cr as verifyZoneParity,lg as volumeCapabilities,yn as wafEventTelemetry,kn as waitForCloudInit,Nn as waitForSsh,_g as webhookEndpoint,Cc as withCDN,yc as withCache,hc as withDatabase,Cm as withInvocation,fc as withMonitoring,Sc as withQueue,gc as withSecurity,fl as withTimeout,Tn as wrapCloudInitUserData,Nu as xrayManager,hS as zeroCapacity,ty as zeroFill,sh as zoneOffsetMs,ah as zonedParts};
595
+ `}async function uo(e){let{domain:t,challengeValue:r,hostedZoneId:n,dnsProvider:i,region:d="us-east-1"}=e;if(i){let a=await Y(i).upsertRecord(t,{name:`_acme-challenge.${t}`,type:"TXT",content:r,ttl:60});if(!a.success)throw Error(`Failed to create DNS challenge record: ${a.message}`);return}if(n){await new J(d).changeResourceRecordSets({HostedZoneId:n,ChangeBatch:{Comment:"ACME DNS-01 challenge",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:`_acme-challenge.${t}`,Type:"TXT",TTL:60,ResourceRecords:[{Value:`"${r}"`}]}}]}});return}throw Error("Either dnsProvider or hostedZoneId must be provided")}async function po(e){let{domain:t,challengeValue:r,hostedZoneId:n,dnsProvider:i,region:d="us-east-1"}=e;if(i){let a=await Y(i).deleteRecord(t,{name:`_acme-challenge.${t}`,type:"TXT",content:r});if(!a.success)console.warn(`Failed to delete DNS challenge record: ${a.message}`);return}if(n){await new J(d).changeResourceRecordSets({HostedZoneId:n,ChangeBatch:{Comment:"Remove ACME DNS-01 challenge",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:`_acme-challenge.${t}`,Type:"TXT",TTL:60,ResourceRecords:[{Value:`"${r}"`}]}}]}});return}throw Error("Either dnsProvider or hostedZoneId must be provided")}function mo(e){try{let{execSync:t}=Z("node:child_process"),r=t(`openssl x509 -checkend 2592000 -noout -in ${e}/cert.pem`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return!1}catch{return!0}}import{createHash as Oe,createSign as at,generateKeyPairSync as Ne}from"node:crypto";var ke={production:"https://acme-v02.api.letsencrypt.org/directory",staging:"https://acme-staging-v02.api.letsencrypt.org/directory"};class st{directoryUrl;email;accountKey;accountUrl=null;directory=null;nonce=null;constructor(e){this.directoryUrl=e.staging?ke.staging:ke.production,this.email=e.email,this.accountKey=e.accountKey||this.generateAccountKey()}generateAccountKey(){let{privateKey:e}=Ne("ec",{namedCurve:"P-256"});return e.export({type:"pkcs8",format:"pem"})}async getDirectory(){if(this.directory)return this.directory;let e=await fetch(this.directoryUrl);if(!e.ok)throw Error(`Failed to fetch ACME directory: ${e.status}`);return this.directory=await e.json(),this.directory}async getNonce(){if(this.nonce){let n=this.nonce;return this.nonce=null,n}let e=await this.getDirectory(),r=(await fetch(e.newNonce,{method:"HEAD"})).headers.get("replay-nonce");if(!r)throw Error("Failed to get nonce from ACME server");return r}getJwk(){let e=this.accountKey.split(`
596
+ `).filter((d)=>!d.startsWith("-----")).join(""),t=Buffer.from(e,"base64"),r=t.length-65,n=t.subarray(r+1,r+33),i=t.subarray(r+33,r+65);return{kty:"EC",crv:"P-256",x:this.base64UrlEncode(n),y:this.base64UrlEncode(i)}}getJwkThumbprint(){let e=this.getJwk(),t=JSON.stringify({crv:e.crv,kty:e.kty,x:e.x,y:e.y}),r=Oe("sha256").update(t).digest();return this.base64UrlEncode(r)}base64UrlEncode(e){return(typeof e==="string"?Buffer.from(e):e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async signPayload(e,t){let r=await this.getNonce(),n=this.getJwk(),i={alg:"ES256",nonce:r,url:e};if(this.accountUrl)i.kid=this.accountUrl;else i.jwk=n;let d=this.base64UrlEncode(JSON.stringify(i)),s=t===""?"":this.base64UrlEncode(JSON.stringify(t)),a=`${d}.${s}`,l=at("SHA256");l.update(a);let p=l.sign(this.accountKey),u=p.subarray(4,4+p[3]),b=4+p[3]+2,C=p.subarray(b,b+p[b-1]),T=Buffer.alloc(32),g=Buffer.alloc(32);u.copy(T,32-u.length),C.copy(g,32-C.length);let m=Buffer.concat([T,g]);return JSON.stringify({protected:d,payload:s,signature:this.base64UrlEncode(m)})}async acmeRequest(e,t){let r=await this.signPayload(e,t),n=await fetch(e,{method:"POST",headers:{"Content-Type":"application/jose+json"},body:r}),i=n.headers.get("replay-nonce");if(i)this.nonce=i;let d,s=n.headers.get("content-type");if(s?.includes("application/json")||s?.includes("application/problem+json"))d=await n.json();else d=await n.text();if(!n.ok)throw Error(`ACME request failed: ${JSON.stringify(d)}`);return{body:d,headers:n.headers}}async registerAccount(){let e=await this.getDirectory(),{body:t,headers:r}=await this.acmeRequest(e.newAccount,{termsOfServiceAgreed:!0,contact:[`mailto:${this.email}`]}),n=r.get("location");if(!n)throw Error("No account URL returned");return this.accountUrl=n,n}async createOrder(e){if(!this.accountUrl)await this.registerAccount();let t=await this.getDirectory(),{body:r,headers:n}=await this.acmeRequest(t.newOrder,{identifiers:e.map((d)=>({type:"dns",value:d}))}),i=n.get("location");if(!i)throw Error("No order URL returned");return{orderUrl:i,authorizations:r.authorizations,finalize:r.finalize}}async getAuthorization(e){let{body:t}=await this.acmeRequest(e,""),r=t.identifier.value,n=this.getJwkThumbprint(),i=t.challenges.filter((d)=>d.type==="http-01"||d.type==="dns-01").map((d)=>{let s=`${d.token}.${n}`;if(d.type==="http-01")return{type:"http-01",token:d.token,keyAuthorization:s,identifier:`/.well-known/acme-challenge/${d.token}`};else{let a=this.base64UrlEncode(Oe("sha256").update(s).digest());return{type:"dns-01",token:d.token,keyAuthorization:s,identifier:`_acme-challenge.${r}`,dnsValue:a}}});return{domain:r,challenges:i}}async respondToChallenge(e){await this.acmeRequest(e,{})}async waitForAuthorization(e,t=30){for(let r=0;r<t;r++){let{body:n}=await this.acmeRequest(e,"");if(n.status==="valid")return;if(n.status==="invalid")throw Error(`Authorization failed: ${JSON.stringify(n)}`);await new Promise((i)=>setTimeout(i,2000))}throw Error("Authorization timed out")}generateCsr(e){let{privateKey:t}=Ne("rsa",{modulusLength:2048}),r=t.export({type:"pkcs8",format:"pem"});return{csr:this.createSimpleCsr(e,t),privateKey:r}}createSimpleCsr(e,t){throw Error("CSR generation requires additional implementation. Consider using the shell-based certbot approach instead.")}async finalizeOrder(e,t){let{csr:r,privateKey:n}=this.generateCsr(t),{body:i}=await this.acmeRequest(e,{csr:this.base64UrlEncode(Buffer.from(r,"base64"))}),d=i.certificate;if(!d)throw Error("Certificate not immediately available - polling not implemented");let a=await(await fetch(d)).text(),l=a.split(/(?=-----BEGIN CERTIFICATE-----)/g),p=l[0],u=l.slice(1).join("");return{certificate:p,privateKey:n,chain:u,fullchain:a,expiresAt:new Date(Date.now()+7776000000)}}getAccountKey(){return this.accountKey}}var xe=["js","mjs","cjs","css","map","woff","woff2","ttf","otf","eot","png","jpg","jpeg","gif","webp","avif","svg","ico","mp4","webm","ogg","mp3","wav","pdf","wasm"],ct=[{name:"x-stx-router",value:"true"}];function W(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function Le(e){return`{${e.map(W).join(" ")}}`}function lt(e){let t=`http.request.headers[${W(e.name.toLowerCase())}]`;return e.value===void 0?`len(${t}) > 0`:`any(${t}[*] == ${W(e.value)})`}function se(e){if(e.length===1)return`http.host eq ${W(e[0])}`;return`http.host in ${Le(e)}`}function ce(e,t={}){if(t.enabled===!1||e.length===0)return[];let r=se(e),n=[],d=(t.bypassPaths??[]).map((T)=>`starts_with(http.request.uri.path, ${W(T)})`),a=(t.negotiatedRequestHeaders??ct).map(lt),l=[...d,...a],p=l.length>0?`(${l.join(" or ")})`:void 0;if(p)n.push({action:"set_cache_settings",description:"bypass cache",expression:`(${r} and ${p})`,enabled:!0,action_parameters:{cache:!1}});let u=p?`${r} and not ${p}`:r,b=t.assetExtensions??xe,C=b.length>0?`lower(http.request.uri.path.extension) in ${Le([...b])}`:void 0;if(C)n.push({action:"set_cache_settings",description:"cache fingerprinted assets",expression:`(${u} and ${C})`,enabled:!0,action_parameters:{cache:!0,edge_ttl:{mode:"override_origin",default:t.assetEdgeTtl??2592000},browser_ttl:{mode:"override_origin",default:t.assetBrowserTtl??31536000}}});return n.push({action:"set_cache_settings",description:"cache documents",expression:C?`(${u} and not ${C})`:`(${u})`,enabled:!0,action_parameters:{cache:!0,edge_ttl:{mode:"override_origin",default:t.documentEdgeTtl??3600},browser_ttl:{mode:"override_origin",default:t.documentBrowserTtl??0}}}),n}function le(e,t,r){if(e.length===0||!t||!r)return[];return[{action:"rewrite",description:"origin guard header",expression:`(${se(e)})`,enabled:!0,action_parameters:{headers:{[t]:{operation:"set",value:r}}}}]}var N=(e)=>e===void 0?void 0:e?"on":"off";function de(e){let t={ssl:e.ssl,always_use_https:N(e.alwaysUseHttps),automatic_https_rewrites:N(e.automaticHttpsRewrites),min_tls_version:e.minTlsVersion,tls_1_3:N(e.tls13),brotli:N(e.brotli),http3:N(e.http3),"0rtt":N(e.zeroRtt),early_hints:N(e.earlyHints),browser_cache_ttl:e.browserCacheTtl,always_online:N(e.alwaysOnline),websockets:N(e.websockets),email_obfuscation:N(e.emailObfuscation)};if(e.hsts)t.security_header={strict_transport_security:{enabled:e.hsts.enabled,max_age:e.hsts.maxAge??31536000,include_subdomains:e.hsts.includeSubdomains??!1,preload:e.hsts.preload??!1,nosniff:e.hsts.noSniff??!0}};for(let r of Object.keys(t))if(t[r]===void 0)delete t[r];return{...t,...e.raw??{}}}var H={ssl:"strict",alwaysUseHttps:!0,automaticHttpsRewrites:!0,minTlsVersion:"1.2",tls13:!0,brotli:!0,http3:!0,earlyHints:!0,alwaysOnline:!0,emailObfuscation:!1,browserCacheTtl:0};import{connect as dt}from"node:tls";async function ue(e){let{address:t,serverName:r,port:n=443,timeoutMs:i=5000}=e;return new Promise((d)=>{let s=!1,a=(p)=>{if(s)return;s=!0;try{l.destroy()}catch{}d(p)},l=dt({host:t,port:n,servername:r,rejectUnauthorized:!1,timeout:i});l.once("secureConnect",()=>{if(l.authorized){a({reachable:!0,trusted:!0});return}a({reachable:!0,trusted:!1,reason:l.authorizationError?String(l.authorizationError):"origin certificate is not trusted for this hostname"})}),l.once("timeout",()=>{a({reachable:!1,trusted:!1,reason:`no TLS handshake within ${i}ms`})}),l.once("error",(p)=>{a({reachable:!1,trusted:!1,reason:p.message})})})}function ut(e,t){let r=t.replace(/\.$/,"").toLowerCase();return e.some((n)=>{let i=n.replace(/\.$/,"").toLowerCase();if(i===r)return!0;if(!i.startsWith("*."))return!1;let d=i.slice(2);if(!r.endsWith(`.${d}`))return!1;return!r.slice(0,r.length-d.length-1).includes(".")})}async function pt(e){let{provider:t,zone:r,hosts:n,ipv4:i,ipv6:d,proxied:s=!0,settings:a=H,cache:l,originGuard:p,purge:u=!0,ttl:b=300,skipOriginProbe:C=!1,skipEdgeCertificateCheck:T=!1}=e,g={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(n.length===0)return g;let m=[],c=s&&!T?await t.listEdgeCertificateHosts(r):null;for(let o of n){let f=s;if(f&&c&&!ut(c,o)){f=!1;let S=c.length===0?"the zone has no active edge certificate yet":`no active edge certificate covers it (${c.join(", ")})`;g.deferredProxy.push({host:o,reason:S}),g.warnings.push(`${o}: publishing DNS-only — ${S}. Proxying it would make Cloudflare terminate TLS with no certificate for the name, which fails the handshake outright rather than degrading. Universal SSL covers the apex and ONE level of subdomain, so a deeper name needs its own certificate; otherwise re-run the deploy once the certificate is active.`)}if(f&&!C){let S=await ue({address:i,serverName:o});if(!S.trusted){f=!1;let A=S.reason||"origin is not serving a trusted certificate";g.deferredProxy.push({host:o,reason:A}),g.warnings.push(`${o}: publishing DNS-only for now — the origin does not yet serve a certificate this proxy can verify (${A}). The origin issues certificates over HTTP-01, which needs the name to reach it directly; re-run the deploy once it has one and the record will be proxied.`)}}if(f)m.push(o);let h=[{type:"A",content:i}];if(d&&pe(o))h.push({type:"AAAA",content:d});for(let{type:S,content:A}of h){let R=await t.upsertRecord(r,{name:o,type:S,content:A,ttl:b,proxied:f});if(R.success)g.records.push({host:o,type:S,content:A,proxied:f});else g.warnings.push(`${o} ${S} → ${A} failed: ${R.message||"unknown provider error"}`)}}if(m.length===0){if(s)g.warnings.push("No host is proxied yet, so zone settings, cache rules and purge were skipped — they only take effect through the proxy.");return g}try{let o=de(a),f=await t.applyZoneSettings(r,o);g.settingsChanged=f.changed;for(let h of f.failed)g.warnings.push(`zone setting '${h.id}' could not be applied: ${h.error}`)}catch(o){g.warnings.push(`zone settings could not be read: ${o instanceof Error?o.message:String(o)}`)}let y=ce(m,l);if(y.length>0){let o=await t.putManagedPhaseRules(r,"http_request_cache_settings",y);if(o.success)g.cacheRules=y.length;else g.warnings.push(`cache rules could not be written: ${o.message}`)}if(p){let o=le(m,p.header,p.value);if(o.length>0){let f=await t.putManagedPhaseRules(r,"http_request_late_transform",o);if(f.success)g.originGuard=!0;else g.warnings.push(`origin guard header could not be written: ${f.message}. `+"The gateway will reject requests that lack it — disable the guard or grant the token Transform Rules: Edit.")}}if(u){if(g.purged=await t.purgeCache(r,{hosts:m}),!g.purged)g.warnings.push("edge cache purge failed — new content may take until TTL expiry to appear.")}return g}var mt=(e)=>process.env[e];function Fe(e,t){let r=e.replace(/\.$/,"").toLowerCase();if(t){let n=t.replace(/\.$/,"").toLowerCase();if(r===n||r.endsWith(`.${n}`))return n}return r.split(".").slice(-2).join(".")}function ft(e,t={}){let r=t.env??mt,n=e.infrastructure?.compute?.proxy?.cdn,i=[];if(!n||n.provider!=="cloudflare")return{plan:null,errors:i};if(n.originDomain)i.push(`compute.proxy.cdn.originDomain (${n.originDomain}) is ignored for Cloudflare: the proxy forwards to the address in the record it fronts, `+"so no separate origin hostname is needed — and publishing one gives clients a documented way around the edge.");let d=r("CLOUDFLARE_API_TOKEN");if(!d)return i.push("CLOUDFLARE_API_TOKEN is not set — the Cloudflare CDN cannot be reconciled."),{plan:null,errors:i};let s=e.sites??{},a=n.frontedHosts?.length?[...new Set(n.frontedHosts.map((C)=>C.toLowerCase()))]:me(s,{autoWww:e.infrastructure?.compute?.proxy?.autoWww!==!1});if(a.length===0)return i.push("No hostnames to front — set compute.proxy.cdn.frontedHosts, or give a site a domain."),{plan:null,errors:i};let l=e.infrastructure?.dns?.domain,p=new Set(a.map((C)=>Fe(C,l)));if(p.size>1)return i.push(`Fronted hosts span more than one zone (${[...p].join(", ")}). A Cloudflare zone is configured as a unit, so run one CDN config per zone.`),{plan:null,errors:i};let u=n.cloudflare??{},b=n.secret?{header:n.secretHeader??"X-Origin-Verify",value:n.secret}:void 0;return{plan:{zone:[...p][0],hosts:a,apiToken:d,zoneId:u.zoneId??r("CLOUDFLARE_ZONE_ID"),accountId:u.accountId??r("CLOUDFLARE_ACCOUNT_ID"),proxied:u.proxied!==!1,settings:u.settings??H,cache:u.cache,originGuard:b,purge:u.purgeOnDeploy!==!1,skipOriginProbe:u.skipOriginProbe===!0},errors:i}}var ht=26214400;var yt=new Set(["/_headers","/_redirects","/_routes.json","/_worker.js"]);class Me{name="cloudflare-pages";apiToken;accountId;constructor(e){if(!e.apiToken)throw Error("Cloudflare Pages needs an API token");if(!e.accountId)throw Error("Cloudflare Pages needs an account id");this.apiToken=e.apiToken,this.accountId=e.accountId}async request(e,t,r){return fe(e,`/accounts/${this.accountId}${t}`,`Bearer ${this.apiToken}`,r)}async getProject(e){try{return await this.request("GET",`/pages/projects/${e}`)}catch(t){if(t instanceof Error&&/\b8000007\b|not found/i.test(t.message))return null;throw t}}async ensureProject(e,t="main"){let r=await this.getProject(e);if(r)return r;return this.request("POST","/pages/projects",{name:e,production_branch:t})}async uploadToken(e){return(await this.request("GET",`/pages/projects/${e}/upload-token`)).jwt}async missingHashes(e,t){let r=await fe("POST","/pages/assets/check-missing",`Bearer ${e}`,{hashes:t});return new Set(r)}async uploadBatch(e,t){let r=t.map((n)=>({key:n.hash,value:n.base64,metadata:{contentType:St(n.extension)},base64:!0}));await fe("POST","/pages/assets/upload",`Bearer ${e}`,r)}async createDeployment(e,t,r){let n={};for(let d of t)n[d.path]=d.hash;let i=new FormData;if(i.append("manifest",JSON.stringify(n)),r)i.append("branch",r);return this.request("POST",`/pages/projects/${e}/deployments`,i)}async deployDirectory(e){let t=await Be(e.directory);if(t.length===0)throw Error(`No files to deploy in ${e.directory}`);let r=await this.uploadToken(e.project),n=await this.missingHashes(r,t.map((l)=>l.hash)),i=t.filter((l)=>n.has(l.hash)),d=[];for(let l=0;l<i.length;l+=100)d.push(i.slice(l,l+100));let s=0;for(let l=0;l<d.length;l+=4){let p=d.slice(l,l+4);await Promise.all(p.map((u)=>this.uploadBatch(r,u))),s+=p.reduce((u,b)=>u+b.length,0),e.onProgress?.(s,i.length)}return{deployment:await this.createDeployment(e.project,t,e.branch),total:t.length,uploaded:i.length,uploadedBytes:i.reduce((l,p)=>l+p.size,0)}}async listCustomDomains(e){return(await this.request("GET",`/pages/projects/${e}/domains`)).map((r)=>r.name)}async attachCustomDomain(e,t){if((await this.listCustomDomains(e)).includes(t))return!1;return await this.request("POST",`/pages/projects/${e}/domains`,{name:t}),!0}}function Ct(e,t){return{type:"CNAME",name:e,value:t.endsWith(".pages.dev")?t:`${t}.pages.dev`,ttl:1,proxied:!0}}async function _e(e,t){let{blake3:r}=await import("./chunk-6kpbveb8.js").then((m)=>gt(m.default,1));return(await r(e+t)).slice(0,32)}async function Be(e){let{readdir:t}=await import("node:fs/promises"),{join:r,relative:n,sep:i}=await import("node:path"),d=[];async function s(a){let l=await t(a,{withFileTypes:!0});for(let p of l){let u=r(a,p.name);if(p.isDirectory()){await s(u);continue}if(!p.isFile())continue;let b=`/${n(e,u).split(i).join("/")}`;if(yt.has(b))continue;let C=await Bun.file(u).bytes();if(C.byteLength>26214400)throw Error(`${b} is ${C.byteLength} bytes, over the Cloudflare Pages limit of 26214400`);let T=Buffer.from(C).toString("base64"),g=p.name.lastIndexOf("."),m=g>0?p.name.slice(g+1):"";d.push({path:b,hash:await _e(T,m),base64:T,extension:m,size:C.byteLength})}}return await s(e),d.sort((a,l)=>a.path.localeCompare(l.path)),d}function St(e){return{html:"text/html; charset=utf-8",css:"text/css; charset=utf-8",js:"application/javascript; charset=utf-8",mjs:"application/javascript; charset=utf-8",json:"application/json; charset=utf-8",map:"application/json; charset=utf-8",xml:"application/xml; charset=utf-8",txt:"text/plain; charset=utf-8",svg:"image/svg+xml",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",avif:"image/avif",ico:"image/x-icon",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",pdf:"application/pdf",webmanifest:"application/manifest+json"}[e.toLowerCase()]||"application/octet-stream"}async function fe(e,t,r,n){let i={Authorization:r},d;if(n instanceof FormData)d=n;else if(n!==void 0)i["Content-Type"]="application/json",d=JSON.stringify(n);let s=await fetch(`https://api.cloudflare.com/client/v4${t}`,{method:e,headers:i,body:d}),a=await s.text(),l;try{l=JSON.parse(a)}catch{throw Error(`Cloudflare Pages API returned ${s.status} with a non-JSON body: ${a.slice(0,200)}`)}if(!l.success){let p=(l.errors??[]).map((u)=>`${u.code}: ${u.message}`).join(", ");throw Error(`Cloudflare Pages API error (${s.status}): ${p||a.slice(0,200)}`)}return l.result}export{Vu as ABTestManager,$r as ACMClient,Dr as ACMDnsValidator,ke as ACME_DIRECTORIES,F as AI,Kf as API_IDEMPOTENCY_TTL_MS,Uf as API_TOKEN_DEFAULT_TTL_MS,jf as API_TOKEN_MAX_TTL_MS,Yy as API_VERSION,Of as AUTHORIZATION_CAPABILITIES,Cf as AUTH_ACTION_TOKEN_TTL_MS,Sf as AUTH_MFA_CHALLENGE_TTL_MS,Af as AUTH_OIDC_TRANSACTION_TTL_MS,yf as AUTH_SESSION_ABSOLUTE_TTL_MS,hf as AUTH_SESSION_IDLE_TTL_MS,Jc as AWSAPIError,vt as AWSClient,Ve as AWSCloudFormationClient,We as AWSCloudFrontClient,wu as AWSConfigManager,Gs as AWS_PSEUDO_PARAMETERS,Bd as AWS_REGIONS,st as AcmeClient,Ft as AlertEvaluator,Lt as AlertStore,ny as AnomalyConfigStore,Ie as ApiGateway,jy as ApiServiceError,Qr as ApplicationAutoScalingClient,zs as Arn,_s as AssetHasher,Fs as Auth,bf as AuthenticationStore,qy as AutomationApiService,qf as AutomationIdentityStore,fS as AwsAuroraDataAdapter,SS as AwsAuroraTransport,uA as AwsDatabaseBackupSource,wn as AwsDriver,gS as AwsElastiCacheDataAdapter,AS as AwsElastiCacheTransport,cC as AwsIamCapabilityScanner,AA as AwsInfrastructureBackupSource,mS as AwsRdsDataAdapter,CS as AwsRdsTransport,HS as AwsRegionalDriver,$A as AwsSecretsManagerConfigurationBackend,zy as AwsSpendTransport,DA as AwsSsmConfigurationBackend,lA as BackupCoordinator,Pu as BackupManager,iA as BackupStore,rm as BatchProcessingManager,Hr as BedrockClient,Wr as BedrockRuntimeClient,Kg as BitbucketSourceAdapter,Fu as BlueGreenManager,Vp as BounceComplaintHandler,hp as BuildOptimizationManager,bS as BunDockerRuntime,yA as BunDockerVolumeRuntime,fA as BunFilesystemArchiveRuntime,Ds as CDN,bt as CHAIN_HEADER,sr as CLOUDFLARE_MANAGED_RULE_PREFIX,iu as COMMON_CROSS_ACCOUNT_ROLES,Ef as CONTROL_PLANE_SCHEMA_VERSION,ie as Cache,_u as CanaryManager,dp as CertificateManager,Eg as CloudBlockVolumeDriver,Ln as CloudDriverFactory,Uc as CloudError,Us as CloudFormationBuilder,Ve as CloudFormationClient,We as CloudFrontClient,vu as CloudTrailManager,xr as CloudWatchLogsClient,Me as CloudflarePagesProvider,cr as CloudflareProvider,Dd as CommandHistory,Ws as Communication,kg as ComposeApplicationService,Ng as ComposeApplicationStore,zr as ComprehendClient,E as Compute,Gy as ComputeSpendTransport,jc as ConfigurationError,wA as ConfigurationService,bA as ConfigurationStore,Lr as ConnectClient,yS as ContainerDataAdapter,Cp as ContainerRegistryManager,SA as ControlPlaneBackupSource,tA as ControlPlaneCleanupDriver,zf as ControlPlaneStore,Eh as CounterTracker,Kc as CredentialError,Od as CrossRegionReferenceManager,uc as DASHBOARD_ENTRY,pc as DASHBOARD_PORT_BASE,mc as DASHBOARD_PORT_SPAN,dc as DASHBOARD_STATE_DIR,gi as DEFAULT_ATTACK_MODE_HOURS,Wt as DEFAULT_DDOS_THRESHOLDS,Dh as DEFAULT_METER_MAPPINGS,yh as DEFAULT_PRICE_BOOK,Pt as DEFAULT_RECURSION_LIMITS,sl as DEFAULT_SERVICE_LIMITS,qa as DEFAULT_STATE_DIR,xe as DEFAULT_STATIC_ASSET_EXTENSIONS,by as DEFAULT_TELEMETRY_POLICY,kh as DEFAULT_THRESHOLDS,yg as DEPLOYMENT_QUEUE_KINDS,At as DEPTH_HEADER,iy as DETECTABLE_SIGNALS,GC as DIAGNOSTIC_PRESETS,em as DLQMonitoringManager,Is as DNS,Fp as DNSSECManager,uS as DataServiceLifecycle,lS as DataServiceStore,K as Database,ip as DatabaseUserManager,el as DebugLogger,Rs as DependencyGraph,Ms as Deployment,qc as DeploymentError,Du as DisasterRecoveryManager,Tr as DnsProviderFactory,RS as DockerDataTransport,LC as DockerDiscoveryAdapter,Ig as DockerNamedVolumeDriver,CA as DockerVolumeBackupSource,mg as DurableOperationQueue,fg as DurableQueueWorker,_r as DynamoDBClient,rr as EC2Client,Ir as ECRClient,wr as ECSClient,nn as EFSClient,Fr as ELBv2Client,ch as ENFORCEMENT_ACTIONS,Hh as ENFORCEMENT_DESCRIPTIONS,lh as ENFORCEMENT_SEVERITY,BC as EcsRuntimeAdapter,ui as EdgeRateLimiter,Yr as ElastiCacheClient,L as Email,qp as EmailAdvanced,Hp as EmailAnalyticsManager,xt as EmailClient,Zp as EmailHandlers,jp as EmailTemplateManager,TS as EncryptedDataSecretStore,Yc as ErrorCodes,Jr as EventBridgeClient,nS as EventBridgeJobAdapter,IA as ExternalConfigurationBackend,Xp as FIFOQueueManager,ly as FOCUS_VERSION,ul as FileCache,j as FileSystem,gA as FilesystemBackupSource,wS as FleetService,IS as FleetStore,Hs as Fn,qg as GiteaSourceAdapter,Ug as GithubSourceAdapter,jg as GitlabSourceAdapter,Nd as GlobalResourceManager,ar as GoDaddyProvider,Nu as GuardDutyManager,bl as HashCache,Xm as HealthCheckManager,Bt as HealthCheckRunner,En as HetznerClient,kn as HetznerDriver,Ot as IAMClient,cn as IPV6_EXCLUDED_HOST_LABELS,fp as ImageScanningManager,Ke as InfrastructureGenerator,Mf as InvalidOperationTransitionError,vs as JobLoader,iS as JobProviderReconciler,aS as JobService,eS as JobStore,Zr as KendraClient,Hm as LARAVEL_SERVERLESS_BUILD_STEPS,kr as LambdaClient,Dp as LambdaConcurrencyManager,Np as LambdaDLQManager,wp as LambdaDestinationsManager,Rp as LambdaLayersManager,VC as LambdaRuntimeAdapter,vp as LambdaVPCManager,Pp as LambdaVersionsManager,PA as LocalEncryptedConfigurationBackend,hA as LogicalDatabaseBackupSource,qu as LogsManager,pm as MANAGED_NODE_VERSIONS,Yn as MANAGEMENT_DASHBOARD_SITE,Cc as MANAGEMENT_DASHBOARD_SITE_PREFIX,fi as MAX_CONTROL_HOURS,Wf as MAX_CONTROL_PLANE_ERROR_BYTES,Vf as MAX_CONTROL_PLANE_JSON_BYTES,sh as METERS,ah as METER_KEYS,dh as MICRO_CENTS,_h as MIN_PROJECTION_CONFIDENCE,pn as MTA_STS_PORT,XS as MaintenanceService,JS as MaintenanceStore,xs as Messaging,ju as MetricsManager,Xu as MigrationManager,Ul as MockCloudFormation,Kl as MockDynamoDB,jl as MockS3,we as Monitoring,Xd as MultiAccountManager,Ed as MultiRegionManager,dd as MultiStepProgress,Pe as Network,ef as NetworkSecurityManager,_t as NotificationRouter,Br as OpenSearchClient,Ff as OptimisticConcurrencyError,Qd as OrganizationManager,ht as PAGES_MAX_FILE_BYTES,Gm as PHP_DEFAULT_EXCLUDES,ym as PHP_LAYER_EXTENSIONS,ir as PROXIABLE_RECORD_TYPES,Vs as ParameterStore,rp as PerformanceManager,De as Permissions,qr as PersonalizeClient,Es as Phone,Jp as PhoneAdvanced,ws as PhoneHandlers,NS as PlacementService,OS as PlacementStore,jr as PollyClient,or as PorkbunProvider,rC as PreDeployScanner,Zl as PreviewEnvironmentManager,hg as PreviewEnvironmentService,gg as PreviewEnvironmentStore,ed as PreviewNotificationService,ld as ProgressBar,Hu as ProgressiveDeploymentManager,hi as ProtectionControlStore,ds as Pseudo,ne as Queue,dg as QueueCancellationError,im as QueueManagementManager,ja as QueuePresets,ug as QueueTimeoutError,si as RATE_LIMIT_KEY_SEPARATOR,Mr as RDSClient,ru as RECOMMENDED_ACCOUNT_STRUCTURES,nu as RECOMMENDED_SCPS,Wg as RELEASE_QUEUE_KINDS,Td as REPL,$d as REPLCommandBuilder,Pd as REPLContext,wl as RateLimiter,Ka as RealtimePresets,Ay as RecordingSpendTransport,It as RecursionGuard,q as Redirects,kd as RegionPairManager,VS as RegionService,BS as RegionStore,$s as Registry,Gr as RekognitionClient,Mg as ReleaseService,Fg as ReleaseStore,kS as RemoteBuildService,ep as ReplicaManager,rf as ResourceManagementManager,pg as RetryableOperationError,J as Route53Client,nr as Route53DomainsClient,mr as Route53Provider,_p as Route53ResolverManager,xp as Route53RoutingManager,UC as RuntimeOperationService,jC as RuntimeStreamRegistry,cA as S3BackupDestinationAdapter,Nt as S3Client,zc as S3Error,tC as SECRET_PATTERNS,ty as SENSITIVITY_THRESHOLDS,kt as SESClient,ks as SMS,Or as SNSClient,Wy as SPEND_CYCLE_SECONDS,gy as SPEND_GATE_SETTING,_y as SPEND_LEASE_SETTING,Nr as SQSClient,Er as SSMClient,Za as STATE_DIR_ENV_VAR,H as STATIC_SITE_ZONE_SETTINGS,Zt as STSClient,Xr as SchedulerClient,Ee as Search,aC as SecretFindingScanner,Bs as Secrets,cp as SecretsManager,vr as SecretsManagerClient,ap as SecretsRotationManager,re as Security,xu as SecurityHubManager,eC as SecurityPostureStore,oC as SecurityScannerRunner,pp as SecurityScanningManager,Gp as SenderReputationManager,rS as ServerCronJobAdapter,hS as ServerDataAdapter,wg as ServerPathVolumeDriver,Ap as ServiceMeshManager,$e as Sftp,ay as SignalSource,Yp as SmsAdvanced,en as SmsClient,Ns as SmsHandlers,zg as SourceConnectionStore,Gg as SourceProviderError,yy as SpendCapError,hy as SpendGate,By as SpendLoopLease,My as SpendNotificationRouter,Vy as SpendRunner,my as SpendService,xh as SpendStore,ud as Spinner,$S as SshFleetDriver,xd as StackDependencyManager,Os as StacksIntegration,qm as StaticSiteManager,te as Storage,Jm as StorageAdvancedManager,rn as SupportClient,Ju as SyntheticsManager,PS as SystemFleetSshTransport,_C as SystemdDiscoveryAdapter,Rt as TRACE_HEADER,pd as TaskList,ky as TelemetryStore,be as TemplateBuilder,pl as TemplateCache,Ur as TextractClient,Vr as TranscribeClient,Kr as TranslateClient,rA as TransportDisasterRecoveryDriver,eA as TransportPlatformMaintenanceDriver,LS as TransportRemoteBuildDriver,sC as TrivyImageScanner,Zf as TsCloudApiError,Jf as TsCloudClient,xy as URGENT_SPEND_EVENTS,zh as USER_VISIBLE_ACTIONS,zS as UnavailableRegionalDriver,Cr as UnifiedDnsValidator,_f as UnsupportedSchemaVersionError,Zc as ValidationError,tn as VoiceClient,$g as VolumeService,Ag as VolumeStore,Ls as Workflow,Gu as XRayManager,Wu as abTestManager,Bg as activateImmutableRelease,wC as ageSeconds,Oh as aggregateDeltas,Ts as analyzeStackDiff,ey as anomalyOptionsForSignal,Si as applyControlsToDdos,Ci as applyControlsToRateLimits,qt as applyMitigationFactor,hr as applyZoneMigration,dm as artifactKey,Lg as assertReleaseStrategy,Cy as assertSpendAllows,fC as attachProvenanceToRelease,uC as attachSbomToRelease,pC as attachVulnerabilitySummary,Tf as authEncryptionKeyFile,xf as authorizeOrganization,zC as authorizeRuntimePath,Cd as autocomplete,Eu as awsConfigManager,sA as backupCredentialStatus,$u as backupManager,Tl as batch,nm as batchProcessingManager,If as beginOidcAuthorization,Mu as blueGreenManager,Wp as bounceComplaintHandler,Rh as budgetWindow,vi as buildAndPushServerlessImage,Pm as buildBunRuntimeLayerZip,js as buildCloudFormationTemplate,cg as buildComposeLogsCommand,ag as buildComposeRuntimeCommand,sg as buildComposeScaleCommand,lg as buildComposeShellCommand,Ni as buildFunctionEnv,Jn as buildHostCleanupScript,cs as buildMailEnv,ri as buildManagementDashboardArtifact,qi as buildMediaCdnPlan,un as buildMtaStsPolicy,mn as buildMtaStsServer,Tm as buildNodeRuntimeLayerZip,yp as buildOptimizationManager,le as buildOriginGuardRule,zm as buildPhpRuntimeLayerZip,qn as buildSiteDeployScript,Mn as buildSshArgs,ce as buildStaticSiteCacheRules,Zn as buildStaticSiteDeployScript,EC as bytes,Bu as canaryManager,GS as canonicalJson,$C as capabilities,vS as capacity,xl as categorizeChanges,up as certificateManager,il as checkIAMPermissions,vm as checkInvocation,cl as checkServiceQuotas,El as chunk,po as cleanupDns01Challenge,Ha as clearSigningKeyCache,eh as cloneSourceBinding,Ml as cloudConfigSchema,Fn as cloudDrivers,Ou as cloudTrailManager,Be as collectAssets,jm as collectPhpAppEntries,on as collectServerDnsDomains,Og as completeComposeVolumeDeletion,wf as completeOidcAuthorization,Pc as composePresets,og as composeProjectName,hm as composeServerlessAppTemplate,Uy as compositeSpendTransport,pA as compressBackup,cf as config,dS as connectionGuidance,Sp as containerRegistryManager,Bf as controlPlaneDatabaseFile,vf as controlPlaneMigrations,Qs as createApiBackendPreset,Qy as createApiV1Handler,_S as createAsgBuildDriver,dA as createBackupQueueHandlers,Mm as createCliHandler,xn as createCloudDriver,Ae as createCloudFrontPolicy,Bc as createCredentialProvider,lc as createDashboardSite,ic as createDataPipelinePreset,pS as createDataServiceQueueHandlers,Sg as createDeploymentQueueHandlers,Y as createDnsProvider,MS as createEcsBuildDriver,Sy as createEnforcementHandlers,Qc as createError,Ys as createExistingStaticFullStackPreset,DS as createFleetQueueHandlers,Xs as createFullStackAppPreset,Ar as createGoDaddyValidator,_m as createHandlers,Lm as createHttpHandler,tc as createJamstackPreset,sS as createJobQueueHandlers,sc as createLaravelPreset,oc as createMLApiPreset,QS as createMaintenanceQueueHandlers,Ui as createMediaAccessToken,rc as createMicroservicesPreset,ql as createMockAWS,qs as createNodeJsServerPreset,Zs as createNodeJsServerlessPreset,tr as createObjectStorageClient,Sr as createPorkbunValidator,$c as createPreset,La as createPresignedUrl,Fa as createPresignedUrlAsync,Fm as createQueueHandler,nc as createRealtimeAppPreset,WS as createRegionQueueHandlers,mC as createReleaseProvenance,Hg as createReleaseQueueHandlers,xS as createRemoteBuildQueueHandlers,br as createRoute53Validator,WC as createRuntimeAdapters,Gc as createS3Client,FS as createServerBuildDriver,cc as createServerlessLaravelPreset,Js as createServerlessNodePreset,Zg as createSourceAdapter,Ks as createStaticSitePreset,ac as createTraditionalWebAppPreset,Dg as createVolumeQueueHandlers,ec as createWordPressPreset,am as createZip,Ld as crossRegionReferenceManager,Bi as dashboardActions,Xn as dashboardCredentialsFile,cS as dataServiceCapabilities,op as databaseUserManager,df as decodeBase32,mA as decompressBackup,aA as decryptBackup,of as defaultConfig,Bl as defaultLocalConfig,mi as defaultRateLimitRules,Ii as deleteStaticSite,ii as deployAllComputeSites,ki as deployServerlessApp,Ei as deploySite,ni as deploySiteRelease,Pi as deployStaticSite,wi as deployStaticSiteFull,bi as deployStaticSiteWithExternalDns,Ri as deployStaticSiteWithExternalDnsFull,ns as deploymentCoexistenceError,fc as deriveManagementDashboardPort,yi as describePosture,tS as desiredJobProviderState,Xh as detectAnomalies,ts as detectDeploymentTargets,Rr as detectDnsProvider,Qh as detectLatestAnomaly,rl as detectMisconfigurations,Na as detectServiceRegion,Qf as diffCompose,Ol as diffTemplates,Qg as discoverGitRefs,Df as discoverOidcProvider,vC as discoverRuntimeInventory,tm as dlqMonitoringManager,Pr as dnsProviders,Mp as dnssecManager,xC as dockerWorkloads,jS as documentDigest,Iu as drManager,OC as ecsWorkloads,Lf as effectiveCapabilities,zp as emailAnalyticsManager,Kp as emailTemplateManager,lf as encodeBase32,oA as encryptBackup,yC as ensureDefaultSecurityPolicies,Gn as ensureFirewall,ti as ensureManagementDashboard,Un as ensureServer,zn as ensureSshKey,bn as escapeSecLang,Vh as evaluateBudget,Vt as evaluateTelemetryAlertRules,XC as eventBridgeScheduleInput,km as eventToRequest,Yh as ewma,Xf as exportCompose,fr as exportRoute53Zone,Tc as extendPreset,Qp as fifoQueueManager,Al as findChangedFiles,Ih as findMapping,ph as findPriceEntry,cu as formatAccountStructure,od as formatBytes,Ly as formatCents,Ps as formatDiff,ad as formatDuration,Ad as formatFlagSuggestions,Id as formatHistory,wd as formatHistoryStats,cd as formatKeyValue,sd as formatList,id as formatProgressBar,Zd as formatRegion,Jd as formatRegionList,iC as formatScanResults,fd as formatSuggestion,rd as formatTable,Mh as formatTimeToExhaustion,nd as formatTree,Lc as fromEC2Metadata,Fc as fromECSMetadata,kc as fromEnvironment,xc as fromSharedCredentials,Mc as fromWebIdentity,Tt as functionFingerprint,me as gatewayHostnames,bm as generateAppImageDockerfile,Ru as generateApprovalConfig,sm as generateBootstrap,Xl as generateCleanupWorkflow,Ql as generateCostReportWorkflow,au as generateCrossAccountRoleCF,lC as generateCycloneDxSbom,Su as generateDeploymentConfig,fu as generateDeploymentPipeline,lu as generateDeploymentWorkflow,Ai as generateExternalDnsStaticSiteTemplate,lo as generateHttpsServerCode,dC as generateImageSbom,co as generateLetsEncryptUserData,Te as generateLogicalId,Cu as generateManualPipeline,mu as generateMatrixWorkflow,Au as generateMultiEnvConfig,gu as generateMultiEnvPipeline,du as generateMultiEnvWorkflow,uu as generatePRPreviewWorkflow,Tu as generateParallelConfig,Bm as generatePhpFpmConfig,Am as generatePhpLayerDockerfile,hu as generatePreviewPipeline,Yl as generatePreviewWorkflow,Re as generateResourceName,bu as generateScheduledConfig,yu as generateScheduledPipeline,pu as generateScheduledWorkflow,Ti as generateStaticSiteTemplate,In as generateUbuntuAppCloudInit,Hc as getAccountId,Wd as getAllRegions,jd as getClosestRegion,bd as getCommandUsage,tg as getComposeTemplate,af as getConfig,hd as getContextualHelp,_c as getCredentials,Ll as getDeploymentStrategy,Fl as getDiffStats,Nl as getDiffSummary,Xc as getErrorDetails,Vl as getLocalConfig,zl as getLocalCredentials,Hl as getLocalEndpoint,Gl as getLocalEnvVars,ll as getQuotaUsageSummary,ou as getRecommendedStructure,Vd as getRegion,Yd as getRegionStats,zd as getRegionsByCompliance,Hd as getRegionsByLocation,Gd as getRegionsByPricingTier,ol as getRequiredPermissions,za as getSigningKeyCacheSize,us as getTimestamp,ci as globMatches,Tn as globToRegex,Fd as globalResourceManager,Bh as governingLimitCents,ku as guardDutyManager,Zy as handleSpendRequest,An as hasAutoWwwVariant,yc as hasManagementDashboardSite,gn as hasProxyUpstream,hl as hashBuffer,yl as hashDirectory,fl as hashFile,Cl as hashManifest,gl as hashString,Qm as healthCheckManager,pe as hostAcceptsIpv6,se as hostCondition,uf as hotp,Ph as hourBucket,$h as hourBucketsBetween,gp as imageScanningManager,Oi as infraEnvFromOutputs,Dt as inspectInvocation,Im as installRecursionFetch,Di as invalidateCache,$m as invocationContext,gd as isLikelyTypo,Wl as isLocalDevelopment,Ac as isManagementDashboardSiteName,Ga as isNodeCryptoAvailable,Kh as isOperationAllowed,Mt as isQuietHours,Rn as isSafePattern,es as isStatePath,Ht as isValidCidr,Ud as isValidRegion,Ch as isValidTimeZone,Ua as isWebCryptoAvailable,JC as jobProviderCapability,Yt as keyMatchesFilters,Ip as lambdaConcurrencyManager,kp as lambdaDLQManager,Ep as lambdaDestinationsManager,Tp as lambdaLayersManager,Op as lambdaVPCManager,$p as lambdaVersionsManager,NC as lambdaWorkloads,Wm as laravelServerlessEnvDefaults,eg as listComposeTemplates,nh as listSourceReferences,sf as loadCloudConfig,Py as loadTelemetryPolicy,Zu as logsManager,cy as lookbackHoursForSignal,os as mailEnabled,ss as mailFirewallPorts,YS as maintenanceWindowOpen,Ma as makeAWSRequest,Ba as makeAWSRequestAsync,_a as makeAWSRequestOnce,Sc as managementDashboardSiteName,US as manifestDigest,ff as matchTotpCounter,Ki as mediaObjectHeaders,qh as median,Zh as medianAbsoluteDeviation,Wh as mergeDecisions,Dc as mergeInfrastructure,hh as mergePriceBooks,vh as meterTelemetry,Ku as metricsManager,Xt as migrateObjectStorage,Qu as migrationManager,eu as multiAccountManager,vd as multiRegionManager,mo as needsRenewal,tf as networkSecurityManager,qC as nextScheduleRuns,sn as normalizePublicIpv6,DC as normalizeRuntimeStatus,KC as normalizeScheduleExpression,Jg as normalizeSourceEvent,On as normalizeSshPublicKey,Ry as normalizeTelemetryPolicy,Xy as openApiDocument,sy as optionsForSignal,tu as organizationManager,Km as packagePhpApp,um as packageServerlessApp,_e as pagesAssetHash,Ct as pagesDnsRecord,Rl as parallel,Pl as parallelMap,$l as parallelWithRetry,$t as parseChain,Yf as parseCompose,ng as parseComposeCatalog,kC as parseDockerInspect,RA as parseDotenv,Wa as parseJSONResponse,FC as parseSystemdRecords,Va as parseXMLResponse,Ey as pathTemplate,Fh as percentOfLimit,np as performanceManager,Sm as phpLayerBuildStage,Cm as phpLayerPackages,Vm as phpRuntimeLayerAssets,ig as planComposeTemplateUpgrade,Gh as planEnforcement,Kt as planMitigation,gr as planZoneMigration,lr as policyTag,Jl as previewManager,td as previewNotifications,ZC as previewSchedule,Th as previousBudgetWindow,mh as priceUsage,fh as priceUsageLines,ue as probeOriginTls,vl as processInChunks,Yg as processSourceWebhook,bC as productionChangeReview,zu as progressiveDeploymentManager,Lh as projectSpend,wt as propagationHeaders,Qt as providerEndpoint,KS as publicKeyFingerprint,dr as qualifyName,om as queueManagementManager,Sl as quickHash,pi as rateLimitHeaders,di as rateLimitKey,ln as reconcileAddressRecords,pt as reconcileCloudflareCdn,pr as reconcileDeclaredRecords,QC as reconcileJobObservation,ih as reconcileSourceWebhook,AC as recordDashboardHostPosture,CC as recordPreDeploySecretScan,SC as recordSkippedSecretScan,Et as recursionBlockedResponse,IC as redactRuntimeConfig,Iy as redactTelemetryText,wy as redactTelemetryValue,xi as redeployServerlessApp,Md as regionPairManager,xg as releaseStrategyCapabilities,_g as releaseTrafficPlan,oi as reloadRpxGateway,Jt as remapKey,oh as removeSourceWebhook,an as removeStaleServerAddressRecords,rg as renderComposeTemplate,jt as renderDdosInstallScript,Ut as renderNftablesRuleset,YC as renderServerCron,Gt as renderSysctlFile,Pn as renderWafConfig,$n as renderWafInstallScript,ai as renewRpxCertificates,tp as replicaManager,Ky as requestHash,kl as requiresReplacement,Em as resetRecursionRuntime,Nm as resolveApp,is as resolveAppDatabase,Pf as resolveAuthEncryptionKey,ls as resolveCloudProvider,ft as resolveCloudflareCdnPlan,Vc as resolveCredentials,Vi as resolveDashboardAction,Qn as resolveDashboardAuth,gc as resolveDashboardDomain,hc as resolveDashboardDomains,ur as resolveDeclaredRecords,Cs as resolveDeployBucketName,rs as resolveDeploymentMode,Kn as resolveExecStart,vn as resolveHetznerApiToken,as as resolveMailService,Rc as resolveManagementDashboardSite,bc as resolveManagementDashboardSites,er as resolveObjectStorage,ms as resolveProjectStackName,fn as resolveProxyUpstreams,gm as resolveQueueNames,Cg as resolveQueuedDeploymentCommand,fm as resolveQueues,Dm as resolveRecursionConfig,Wc as resolveRegion,HC as resolveRuntimeInventory,Ss as resolveServerlessAppStackName,As as resolveServerlessArtifactBucketName,bs as resolveServerlessAssetBucketName,mm as resolveServerlessRuntime,hs as resolveSiteBucketName,hn as resolveSiteDeployTarget,yn as resolveSiteKind,gs as resolveSiteResourceName,fs as resolveSiteStackName,Qa as resolveStatePath,ys as resolveStorageBucketName,ei as resolveUiSource,Fe as resolveZoneApex,nf as resourceManagementManager,xm as responseToResult,Jh as robustZScore,Nf as roleCapabilities,Vg as rollbackImmutableRelease,Li as rollbackServerlessApp,gh as roundCents,Bp as route53ResolverManager,Lp as route53RoutingManager,ry as routeMatches,li as ruleMatches,cm as runBuildHooks,Uh as runEnforcement,Um as runPhpBuildHooks,Mi as runRemoteCommand,TC as runtimeId,_i as sanitizeCloudConfig,Hf as sanitizeControlPlaneValue,ps as sanitizeName,$f as sanitizeOidcReturnPath,$y as saveTelemetryPolicy,nC as scanForSecrets,kf as scopeContains,Nh as scopeKey,Vn as scpUpload,yd as searchCommands,Gf as searchControlPlane,lp as secretsManager,sp as secretsRotationManager,RC as secureContainerRelease,Lu as securityHubManager,mp as securityScanningManager,hC as securityScope,Rf as sendAuthenticationEmail,Up as senderReputationManager,Dl as sequence,TA as serializeDotenv,jn as serverPublicIpv4,bp as serviceMeshManager,Fi as setMaintenance,Ja as setStateDir,uo as setupDns01Challenge,lm as sha256,wm as sharedRecursionGuard,Rm as sharedRuntimeLoop,Sn as shipsARelease,Gi as signCloudFrontCookies,zi as signCloudFrontUrl,ka as signRequest,xa as signRequestAsync,oy as signalDefinition,Fy as spendNotificationText,Jy as spendOpenApiPaths,_n as sshExec,Bn as sshExecOrThrow,_d as stackDependencyManager,Wi as startLocalDashboardServer,Hy as startSpendLoop,Ya as stateDir,Xa as statePath,Zm as staticSiteManager,Ym as storageAdvancedManager,py as streamFocusJsonl,jh as strongestActiveAction,md as suggestCommand,Sd as suggestFlags,al as suggestIAMPolicy,dl as suggestQuotaIncrease,qd as suggestRegionPairs,Kd as suggestRegions,rh as syncSourceRepositories,vg as synchronizeComposeVolumes,EA as synchronizeConfiguredConfiguration,oS as synchronizeConfiguredJobs,Yu as syntheticsManager,zt as sysctlHardening,MC as systemdWorkloads,Ny as telemetryBucketLabel,vy as telemetryCursor,Dy as telemetryEstimatedMonthlyCost,Oy as telemetryPercentile,Ty as telemetryPolicyKey,ml as templateCache,th as testSourceConnection,uh as tieredMicroCents,de as toCloudflareZoneSettings,uy as toFocusJsonl,dy as toFocusRecords,pf as totp,gf as totpUri,PC as unsupportedCapabilities,bg as unsupportedVolumeCapabilities,ZS as updateCompatibility,$i as uploadStaticFiles,wh as usageDeltaKey,bh as utcInstantOfLocal,su as validateAccountStructure,_l as validateAgainstSchema,Pg as validateAttachment,nA as validateBackupDestination,Rd as validateCommand,tl as validateConfiguration,nl as validateCredentials,Cn as validateDeploymentConfig,Tg as validateMountPath,et as validateResourceLimits,qe as validateTemplate,Qe as validateTemplateSize,dn as verifyAddressRecord,gC as verifyArtifactSignature,ji as verifyMediaAccessToken,mf as verifyTotp,qS as verifyUpdateSignature,yr as verifyZoneParity,Rg as volumeCapabilities,Dn as wafEventTelemetry,Hn as waitForCloudInit,Wn as waitForSsh,Xg as webhookEndpoint,Oc as withCDN,vc as withCache,Ec as withDatabase,Om as withInvocation,Ic as withMonitoring,Nc as withQueue,wc as withSecurity,Il as withTimeout,Nn as wrapCloudInitUserData,Uu as xrayManager,ES as zeroCapacity,fy as zeroFill,Ah as zoneOffsetMs,Sh as zonedParts};