@stacksjs/ts-cloud 0.12.10 → 0.12.12
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.
- package/dist/aws/index.js +1 -1
- package/dist/bin/{chunk-d7ke90zt.js → chunk-0b49jjgr.js} +1 -1
- package/dist/bin/chunk-0xnnkeb1.js +1 -0
- package/dist/bin/{chunk-9a88fp00.js → chunk-227jmf2b.js} +2 -2
- package/dist/bin/chunk-2nyyg44g.js +1 -0
- package/dist/bin/{chunk-e2bybahr.js → chunk-2ztr119n.js} +1 -1
- package/dist/bin/chunk-43xj5cny.js +1 -0
- package/dist/bin/chunk-5w6y9pmz.js +1 -0
- package/dist/bin/{chunk-8ewncfce.js → chunk-5x4rdx8k.js} +1 -1
- package/dist/bin/chunk-6zc6a6t3.js +725 -0
- package/dist/bin/chunk-7aagqqr9.js +1 -0
- package/dist/{chunk-pb47hr0h.js → bin/chunk-85qrgshq.js} +1 -1
- package/dist/bin/{chunk-c0bdafbx.js → chunk-8zk8msx0.js} +1 -1
- package/dist/bin/chunk-9j83q0r4.js +1 -0
- package/dist/bin/{chunk-b4wt9jcg.js → chunk-9nhqbes6.js} +2 -2
- package/dist/bin/chunk-a4js49mx.js +1 -0
- package/dist/bin/{chunk-6tfwm33r.js → chunk-a9e0hvwe.js} +3 -3
- package/dist/bin/{chunk-cd0ps58j.js → chunk-a9tgxf2h.js} +1 -1
- package/dist/bin/chunk-aahrv359.js +1 -0
- package/dist/bin/{chunk-zpe64t4r.js → chunk-bfx23be3.js} +1 -1
- package/dist/bin/{chunk-tfbs8k8v.js → chunk-bpps61am.js} +1 -1
- package/dist/bin/{chunk-ja1vjdn1.js → chunk-bzth6d1s.js} +1 -1
- package/dist/bin/{chunk-0zwknfwp.js → chunk-ca3taw2m.js} +1 -1
- package/dist/bin/chunk-cgzp0328.js +1 -0
- package/dist/{chunk-w2ddj42w.js → bin/chunk-d2aaef9v.js} +1 -1
- package/dist/bin/{chunk-xk08030d.js → chunk-e0z2t4mf.js} +2 -2
- package/dist/bin/{chunk-btsyjhk7.js → chunk-e2dnxp8d.js} +2 -2
- package/dist/bin/{chunk-s4yzes15.js → chunk-empfsmdk.js} +1 -1
- package/dist/bin/chunk-er3mww4m.js +1 -0
- package/dist/bin/{chunk-azymqbcy.js → chunk-fmp5bv0j.js} +1 -1
- package/dist/bin/{chunk-71t1gmsq.js → chunk-g3kp5ddx.js} +1 -1
- package/dist/bin/{chunk-q5cmfpzt.js → chunk-grepda40.js} +1 -1
- package/dist/{chunk-c8cadhgc.js → bin/chunk-h6xqtypj.js} +2 -2
- package/dist/bin/{chunk-3aph4c1w.js → chunk-hwk9ahms.js} +1 -1
- package/dist/bin/{chunk-dz1ec589.js → chunk-jxd3j00s.js} +2 -2
- package/dist/bin/{chunk-my3ewh3a.js → chunk-k1xw3zbm.js} +2 -2
- package/dist/bin/{chunk-ehc63fvs.js → chunk-m07s5esk.js} +1 -1
- package/dist/bin/{chunk-e5ab5twy.js → chunk-m9r5jype.js} +2 -2
- package/dist/bin/{chunk-4q6tad44.js → chunk-n20kbxwb.js} +91 -91
- package/dist/bin/{chunk-kg61p5hw.js → chunk-n2fnav53.js} +2 -2
- package/dist/bin/{chunk-w32xv8n4.js → chunk-nv211m42.js} +2 -2
- package/dist/bin/chunk-psgjy3z4.js +1 -0
- package/dist/bin/chunk-qmnr82da.js +1 -0
- package/dist/bin/{chunk-mcr0r4at.js → chunk-qqpb82ty.js} +2 -2
- package/dist/bin/{chunk-xhwqpgwq.js → chunk-rqc8btkj.js} +1 -1
- package/dist/bin/chunk-rs85xvt7.js +1 -0
- package/dist/bin/{chunk-hq9x489e.js → chunk-t5ngva49.js} +1 -1
- package/dist/bin/{chunk-82mj52xr.js → chunk-t7rcfwqc.js} +1 -1
- package/dist/bin/{chunk-vj2dp0nh.js → chunk-tjgy10zm.js} +6 -6
- package/dist/bin/chunk-v0beqdna.js +1 -0
- package/dist/bin/chunk-vf2s3tba.js +1 -0
- package/dist/bin/{chunk-0thy7q96.js → chunk-vzkfjrx2.js} +74 -75
- package/dist/bin/{chunk-rtecnmts.js → chunk-wcem4cqb.js} +2 -2
- package/dist/bin/chunk-wsh5ervz.js +1 -0
- package/dist/bin/chunk-xenhbdmr.js +1 -0
- package/dist/bin/chunk-xrdpxwbf.js +1 -0
- package/dist/bin/{chunk-mfrf9q4b.js → chunk-y68m9bx7.js} +1 -1
- package/dist/bin/cli.js +143 -143
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/{chunk-982rye5b.js → chunk-2ybcnrte.js} +1 -1
- package/dist/chunk-4884der5.js +1 -0
- package/dist/{bin/chunk-9kf0np8j.js → chunk-4wdxsnn2.js} +1 -1
- package/dist/{bin/chunk-xkfrqqcs.js → chunk-5hhyyhjt.js} +1 -1
- package/dist/chunk-5zkacdw1.js +1 -0
- package/dist/{chunk-557qj7q9.js → chunk-6cxb8d6y.js} +2 -2
- package/dist/chunk-6f68caq0.js +1 -0
- package/dist/{chunk-2qm3rw8b.js → chunk-7z50g5xz.js} +2 -2
- package/dist/chunk-8fh4m5ge.js +1 -0
- package/dist/chunk-97pb7wb1.js +1 -0
- package/dist/{chunk-a368cs92.js → chunk-ac87ds1k.js} +1 -1
- package/dist/{chunk-qrte4gy2.js → chunk-dndxwssj.js} +1 -1
- package/dist/{chunk-y3tbcxb7.js → chunk-ea7tn8nn.js} +89 -90
- package/dist/{bin/chunk-a7w13qfm.js → chunk-ess6vxfj.js} +2 -2
- package/dist/{chunk-rg7d67xk.js → chunk-j06r5rwv.js} +1 -1
- package/dist/{chunk-70v77sqv.js → chunk-j1g67djb.js} +2 -2
- package/dist/{chunk-fbwpm0zm.js → chunk-k8x8mrkr.js} +1 -1
- package/dist/{chunk-82gezmen.js → chunk-mnmz8t7q.js} +1 -1
- package/dist/{chunk-7j100g7w.js → chunk-n1fyryha.js} +1 -1
- package/dist/{chunk-c1hr34a5.js → chunk-n1hg0jxs.js} +2 -2
- package/dist/{chunk-bcffjsnj.js → chunk-n5xmh0ma.js} +1 -1
- package/dist/chunk-q22qfwsc.js +22 -0
- package/dist/{chunk-5hkq5081.js → chunk-q9a1z53k.js} +2 -2
- package/dist/{chunk-fsssdd5k.js → chunk-r8t25tbm.js} +91 -91
- package/dist/chunk-t8hzekmk.js +585 -0
- package/dist/{chunk-2k0mt6j5.js → chunk-whyttetx.js} +1 -1
- package/dist/{chunk-gkj1tpsn.js → chunk-yf8stygs.js} +1 -1
- package/dist/{chunk-jphewtbx.js → chunk-ze5x2bpm.js} +1 -1
- package/dist/{chunk-jxrs1219.js → chunk-zh0apedk.js} +2 -2
- package/dist/{chunk-0hw5wjjg.js → chunk-zjyz926j.js} +1 -1
- package/dist/deploy/index.js +1 -1
- package/dist/dns/index.js +1 -1
- package/dist/drivers/hetzner/cloud-init.d.ts +14 -1
- package/dist/drivers/hetzner/driver.d.ts +2 -15
- package/dist/drivers/hetzner/state.d.ts +17 -2
- package/dist/drivers/index.d.ts +17 -1
- package/dist/drivers/index.js +1 -1
- package/dist/drivers/local-box/driver.d.ts +1 -1
- package/dist/drivers/shared/compute-deploy.d.ts +0 -12
- package/dist/drivers/shared/compute-provision.d.ts +7 -0
- package/dist/drivers/shared/driver-state.d.ts +68 -0
- package/dist/drivers/shared/remote-exec.d.ts +10 -1
- package/dist/drivers/shared/remote-failure.d.ts +41 -0
- package/dist/drivers/shared/rpx-gateway.d.ts +124 -4
- package/dist/drivers/shared/ssh-transport.d.ts +121 -0
- package/dist/drivers/ssh/bootstrap.d.ts +71 -0
- package/dist/drivers/ssh/config.d.ts +94 -0
- package/dist/drivers/ssh/config.test.d.ts +1 -0
- package/dist/drivers/ssh/driver.d.ts +107 -0
- package/dist/drivers/ssh/factory-wiring.test.d.ts +1 -0
- package/dist/drivers/ssh/first-boot.d.ts +38 -0
- package/dist/drivers/ssh/preflight.d.ts +76 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -7
- package/dist/operations/index.js +1 -1
- package/dist/operations/inventory.d.ts +46 -1
- package/dist/protection/index.js +1 -1
- package/dist/push/index.js +1 -1
- package/dist/spend/index.js +1 -1
- package/dist/ui/404.html +1 -1
- package/dist/ui/accept-invitation.html +1 -1
- package/dist/ui/access-denied.html +1 -1
- package/dist/ui/account/automation.html +5 -5
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +5 -5
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +6 -6
- package/dist/ui/data/services.html +6 -6
- package/dist/ui/data/volumes.html +5 -5
- package/dist/ui/index.html +6 -6
- package/dist/ui/infrastructure/topology.html +6 -6
- package/dist/ui/integrations.html +2 -2
- package/dist/ui/operations/alerts.html +6 -6
- package/dist/ui/operations/configuration.html +6 -6
- package/dist/ui/operations/jobs.html +6 -6
- package/dist/ui/operations/maintenance.html +5 -5
- package/dist/ui/operations/observability.html +6 -6
- package/dist/ui/operations/previews.html +6 -6
- package/dist/ui/operations/queue.html +6 -6
- package/dist/ui/operations/regions.html +5 -5
- package/dist/ui/operations/releases.html +6 -6
- package/dist/ui/operations/spend.html +6 -6
- package/dist/ui/operations/workloads.html +5 -5
- package/dist/ui/security.html +1 -1
- package/dist/ui/server/actions.html +5 -5
- package/dist/ui/server/activity.html +2 -2
- package/dist/ui/server/capacity.html +6 -6
- package/dist/ui/server/database.html +5 -5
- package/dist/ui/server/deployments.html +5 -5
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +6 -6
- package/dist/ui/server/fleet.html +5 -5
- package/dist/ui/server/logs.html +6 -6
- package/dist/ui/server/metrics.html +5 -5
- package/dist/ui/server/security.html +2 -2
- package/dist/ui/server/services.html +1 -1
- package/dist/ui/server/sites.html +6 -6
- package/dist/ui/server/ssh-keys.html +6 -6
- package/dist/ui/server/team.html +6 -6
- package/dist/ui/server/terminal.html +2 -2
- package/dist/ui/serverless/alarms.html +6 -6
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/cost.html +2 -2
- package/dist/ui/serverless/data.html +6 -6
- package/dist/ui/serverless/deployments.html +2 -2
- package/dist/ui/serverless/firewall.html +1 -1
- package/dist/ui/serverless/functions.html +6 -6
- package/dist/ui/serverless/logs.html +6 -6
- package/dist/ui/serverless/metrics.html +1 -1
- package/dist/ui/serverless/queues.html +6 -6
- package/dist/ui/serverless/secrets.html +6 -6
- package/dist/ui/serverless/traces.html +6 -6
- package/dist/ui/serverless.html +6 -6
- package/dist/ui-src/src/charts.ts +1 -1
- package/dist/ui-src/src/topology.ts +1 -1
- package/package.json +3 -3
- package/dist/bin/chunk-04dkwaqp.js +0 -1
- package/dist/bin/chunk-5nkqza92.js +0 -1
- package/dist/bin/chunk-64vczwwt.js +0 -1
- package/dist/bin/chunk-7g2ahkse.js +0 -1
- package/dist/bin/chunk-aw8bhggq.js +0 -594
- package/dist/bin/chunk-cxt74wsj.js +0 -1
- package/dist/bin/chunk-djg4zyqk.js +0 -1
- package/dist/bin/chunk-dkaz333b.js +0 -1
- package/dist/bin/chunk-edvvx3hg.js +0 -1
- package/dist/bin/chunk-f06c5np9.js +0 -1
- package/dist/bin/chunk-gq8794k6.js +0 -1
- package/dist/bin/chunk-k3120rx6.js +0 -1
- package/dist/bin/chunk-nw3d4k52.js +0 -1
- package/dist/bin/chunk-p70bc9yr.js +0 -1
- package/dist/bin/chunk-sg1g92cf.js +0 -1
- package/dist/bin/chunk-tvz9c388.js +0 -1
- package/dist/bin/chunk-y1h63vpm.js +0 -1
- package/dist/bin/chunk-zdt2rjk6.js +0 -1
- package/dist/bin/chunk-zh2d4704.js +0 -1
- package/dist/chunk-1bj94sc2.js +0 -1
- package/dist/chunk-3swnmwfc.js +0 -454
- package/dist/chunk-5pbtmy2k.js +0 -1
- package/dist/chunk-7sc8t7v1.js +0 -1
- package/dist/chunk-gny5s4kp.js +0 -1
- package/dist/chunk-qpjcd415.js +0 -22
- package/dist/chunk-xkw7h4pw.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as Ci,b as Si,c as Ai,d as bi,e as Ri,f as Pi,g as Ti,i as $i,j as Ii,k as Di,l as wi,m as Ei,n as vi}from"./chunk-w2ddj42w.js";import{$ as Yh,$a as HS,$b as HA,A as $g,Aa as gS,Ab as gA,Ac as xi,Ad as Tb,B as Ig,Ba as hS,Bb as hA,Bd as $b,C as Dg,Ca as yS,Cb as yA,Cd as Ib,D as wg,Da as CS,Db as CA,Dd as Db,E as Eg,Ea as SS,Eb as SA,Ed as wb,F as vg,Fa as AS,Fb as AA,Fd as Eb,G as Og,Ga as bS,Gb as bA,Gd as vb,H as Ng,Ha as RS,Hb as RA,Hd as Ob,I as kg,Ia as PS,Ib as PA,Ic as Li,Id as Nb,J as xg,Ja as TS,Jb as TA,Jd as kb,K as Lg,Ka as $S,Kb as $A,Kd as xb,L as Fg,La as IS,Lb as IA,Ld as Lb,M as Mg,Ma as DS,Mb as DA,Md as Fb,N as eh,Na as wS,Nb as wA,Nd as Mb,O as th,Oa as ES,Ob as EA,Od as _b,P as rh,Pa as vS,Pb as vA,Pd as eo,Q as nh,Qa as OS,Qb as OA,Qc as Ui,Qd as to,R as ih,Ra as NS,Rb as NA,Rd as ro,S as oh,Sa as kS,Sb as kA,Sd as no,T as zh,Ta as xS,Tb as xA,U as Gh,Ua as LS,Ub as LA,V as Uh,Va as FS,Vb as FA,W as jh,Wa as MS,Wb as MA,X as Kh,Xa as _S,Xb as _A,Y as qh,Ya as BS,Yb as BA,Z as Zh,Za as VS,Zb as VA,_ as Jh,_a as WS,_b as WA,aa as Xh,ab as zS,ac as zA,ad as Ki,ba as Qh,bb as GS,bc as GA,bd as qi,ca as ey,cb as US,cc as UA,cd as Zi,da as ty,db as jS,dc as jA,dd as Ji,ea as ry,eb as KS,ec as KA,ed as Yi,fa as ny,fb as qS,fc as qA,fd as Xi,ga as iy,gb as ZS,gc as ZA,gd as Qi,ha as oy,hb as JS,hc as JA,ia as ay,ib as YS,ic as YA,ja as sy,jb as XS,jc as XA,ka as cy,kb as QS,kc as QA,la as ly,lb as eA,lc as eb,ma as dy,mb as tA,mc as tb,na as uy,nb as rA,nc as rb,oa as py,ob as nA,oc as nb,od as pb,p as Rf,pa as my,pb as iA,pc as ib,pd as mb,q as Pf,qa as fy,qb as oA,qc as ob,qd as fb,r as Tf,ra as aS,rb as aA,rc as ab,rd as gb,s as $f,sa as sS,sb as sA,sc as sb,sd as hb,t as Cg,ta as cS,tb as cA,tc as cb,td as yb,u as Sg,ua as lS,ub as lA,uc as lb,ud as Cb,v as Ag,va as dS,vb as dA,vc as db,vd as Sb,w as bg,wa as uS,wb as uA,wc as ub,wd as Ab,x as Rg,xa as pS,xb as pA,xc as Oi,xd as bb,y as Pg,ya as mS,yb as mA,yc as Ni,yd as Rb,z as Tg,za as fS,zb as fA,zc as ki,zd as Pb}from"./chunk-y3tbcxb7.js";import{$d as Gi,Td as Fi,Ud as Mi,Vd as _i,Wd as Bi,Xd as Vi,Yd as Wi,Zd as Hi,_d as zi}from"./chunk-jxrs1219.js";import{he as ji}from"./chunk-2k0mt6j5.js";import{Ae as Yr,Be as Xr,Ce as Qr,De as en,Ee as tn,Ff as gn,Jf as hn,Le as rn,Lf as yn,Mf as Cn,Nf as Sn,Of as An,Pf as bn,Qe as nn,Ue as on,Ye as an,af as sn,ef as cn,ie as cr,ke as lr,kf as ln,le as dr,me as ur,ne as pr,nf as dn,oe as mr,of as un,pe as fr,pf as pn,qf as mn,re as hr,se as Wr,te as zr,ue as Gr,ve as Ur,vf as fn,we as jr,xe as Kr,ye as qr,ze as Zr}from"./chunk-gkj1tpsn.js";import{Qf as Gt,Rf as jt,Sf as Kt}from"./chunk-82gezmen.js";import{Uf as We}from"./chunk-7j100g7w.js";import{Vf as Vr}from"./chunk-jphewtbx.js";import{Wf as Jr}from"./chunk-fbwpm0zm.js";import{$f as br,Xf as yr,Yf as Cr,Zf as Sr,_f as Ar,ag as Rr,bg as Pr,cg as Tr,dg as $r,eg as Ir,fg as Dr,gg as wr,hg as Er,ig as vr,jg as Or,kg as Nr,lg as kr,mg as xr,ng as Y,og as Lr,pg as Fr,qg as Mr,rg as _r,sg as Br}from"./chunk-rg7d67xk.js";import{tg as J}from"./chunk-982rye5b.js";import{$g as Wn,$h as pi,Ag as Dn,Bg as wn,Cg as En,Dg as vn,Fh as ei,Gh as ti,Hh as ri,Ih as ni,Kg as ve,Mg as On,Ng as fe,Qh as ii,Rh as oi,Sh as ai,Wh as si,Xh as ci,Yg as _n,Yh as li,Zg as Bn,Zh as di,_g as Vn,_h as ui,ah as Hn,ai as mi,bh as zn,ch as Gn,ci as fi,dh as Un,di as gi,ei as hi,fh as jn,fi as yi,gh as Kn,hh as qn,ih as Zn,jh as Jn,mh as Yn,nh as Xn,oh as Qn,ug as Rn,vg as Pn,wg as Tn,xg as $n,yg as me,zg as In}from"./chunk-3swnmwfc.js";import{ki as Nn,li as kn,mi as xn,ni as Ln,oi as Fn,pi as Mn}from"./chunk-bcffjsnj.js";import{qi as gr,ri as Hr}from"./chunk-557qj7q9.js";import{si as Ve}from"./chunk-c8cadhgc.js";import{ui as Ut}from"./chunk-70v77sqv.js";import{wi as zt}from"./chunk-a368cs92.js";import{$i as eg,Ai as Df,Bi as wf,Ci as Ef,Di as vf,Ei as Of,Fi as Nf,Gi as kf,Hi as xf,Ii as Lf,Ji as Ff,Ki as Mf,Li as _f,Mi as Bf,Ni as Vf,Oi as Wf,Pi as Hf,Qi as zf,Ri as Gf,Si as Uf,Ti as jf,Ui as Kf,Vi as qf,Wi as Zf,Xi as Jf,Yi as Yf,Zi as Xf,_i as Qf,aj as tg,bj as rg,cj as ng,dj as ig,ej as og,fj as ag,gj as sg,hj as cg,ij as lg,jj as dg,kj as ug,lj as pg,mj as mg,nj as fg,oj as gg,pj as hg,qj as yg,zi as If}from"./chunk-qpjcd415.js";import{rj as Mt,tj as _t,uj as Bt,vj as Vt,wj as Wt,xj as Ht}from"./chunk-2qm3rw8b.js";import{Aj as Ot,Bj as Nt,Cj as kt,Dj as xt,Fj as Lt,Gj as Ft,yj as vt}from"./chunk-c1hr34a5.js";import{$j as ch,$k as xy,$l as Xt,Ak as Lh,Al as sC,Am as tS,Bk as Fh,Bl as cC,Bm as rS,Ck as Mh,Cl as lC,Cm as nS,Dk as _h,Dl as dC,Dm as iS,Ek as Bh,El as uC,Em as oS,Fk as Vh,Fl as pC,Gk as Wh,Gl as mC,Hk as Hh,Hl as fC,Ik as gy,Il as gC,Jj as _g,Jk as hy,Jl as hC,Kj as Bg,Kk as yy,Kl as yC,Lj as Vg,Lk as Cy,Ll as CC,Mj as Wg,Mk as Sy,Ml as SC,Nj as Hg,Nk as Ay,Nl as AC,Oj as zg,Ok as by,Ol as bC,Pj as Gg,Pk as Ry,Pl as RC,Qj as Ug,Qk as Py,Ql as PC,Rj as jg,Rk as Ty,Rl as TC,Sj as Kg,Sk as $y,Sl as $C,Tj as qg,Tk as Iy,Tl as IC,Uj as Zg,Uk as Dy,Ul as DC,Vj as Jg,Vk as wy,Vl as wC,Wj as Yg,Wk as Ey,Wl as EC,Xj as Xg,Xk as vy,Xl as qt,Yj as Qg,Yk as Oy,Yl as Zt,Zj as ah,Zk as Ny,Zl as Jt,_j as sh,_k as ky,_l as Yt,ak as lh,al as Ly,am as vC,bk as dh,bl as Fy,bm as OC,ck as uh,cl as My,cm as NC,dk as ph,dl as _y,dm as kC,ek as mh,el as By,em as xC,fk as fh,fl as Vy,fm as LC,gk as gh,gl as Wy,gm as FC,hk as hh,hl as Hy,hm as MC,ik as yh,il as zy,im as _C,jk as Ch,jl as Gy,jm as BC,kk as Sh,kl as Uy,km as VC,lk as Ah,ll as jy,lm as WC,mk as bh,ml as Ky,mm as HC,nk as Rh,nl as qy,nm as Qt,ok as Ph,ol as Zy,om as zC,pk as Th,pl as Jy,pm as GC,qk as $h,ql as Yy,qm as UC,rk as Ih,rl as Xy,rm as jC,sk as Dh,sl as Qy,sm as KC,tk as wh,tl as eC,tm as qC,uk as Eh,ul as tC,um as ZC,vk as vh,vl as rC,vm as JC,wk as Oh,wl as nC,wm as YC,xk as Nh,xl as iC,xm as XC,yk as kh,yl as oC,ym as QC,zk as xh,zl as aC,zm as eS}from"./chunk-5hkq5081.js";import{Fm as er,Gm as tr,Hm as rr,Im as nr,Jm as ir,Km as or,Lm as ar,Mm as sr}from"./chunk-pb47hr0h.js";import{$m as ls,$n as K,$o as Gc,$p as Gl,$q as Gd,$r as Gu,$s as Gp,$t as Rt,An as ks,Ao as yc,Ap as yl,Aq as yd,Ar as yu,As as yp,At as ym,Au as cf,Bn as xs,Bo as Cc,Bp as Cl,Bq as Cd,Br as Cu,Bs as Cp,Bt as Cm,Bu as lf,Cn as Ls,Co as Sc,Cp as Sl,Cq as Sd,Cr as Su,Cs as Sp,Ct as Sm,Cu as df,Dn as Fs,Do as Ac,Dp as Al,Dq as Ad,Dr as Au,Ds as Ap,Dt as Am,Du as uf,En as Ms,Eo as bc,Ep as bl,Eq as bd,Er as bu,Es as bp,Et as bm,Eu as pf,Fn as _s,Fo as Rc,Fp as Rl,Fq as Rd,Fr as Ru,Fs as Rp,Ft as Rm,Fu as mf,Gn as Bs,Go as Pc,Gp as Pl,Gq as Pd,Gr as Pu,Gs as Pp,Gt as Pm,Gu as ff,Hn as Vs,Ho as Tc,Hp as Tl,Hq as Td,Hr as Tu,Hs as Tp,Ht as Tm,Hu as gf,In as Ws,Io as $c,Ip as $l,Iq as $d,Ir as $u,Is as $p,It as $m,Iu as hf,Jn as re,Jo as Ic,Jp as Il,Jq as Id,Jr as Iu,Js as Ip,Jt as Im,Ju as yf,Kn as Hs,Ko as Dc,Kp as Dl,Kq as Dd,Kr as Du,Ks as Dp,Kt as Dm,Ku as Cf,Ln as zs,Lo as wc,Lp as wl,Lq as wd,Lr as wu,Ls as wp,Lt as wm,Lu as Sf,Mn as Gs,Mo as Ec,Mp as El,Mq as Ed,Mr as Eu,Ms as Ep,Mt as Em,Mu as Af,Nm as Za,Nn as ne,No as vc,Np as vl,Nq as vd,Nr as vu,Ns as vp,Nt as vm,Nu as bf,Om as Ja,On as E,Oo as Oc,Op as Ol,Oq as Od,Or as Ou,Os as Op,Ot as Om,Pm as Ya,Pn as Te,Po as Nc,Pp as Nl,Pq as Nd,Pr as Nu,Ps as Np,Pt as Nm,Qm as Xa,Qn as j,Qo as kc,Qp as kl,Qq as kd,Qr as ku,Qs as kp,Qt as km,Rm as Qa,Rn as L,Ro as xc,Rp as xl,Rq as xd,Rr as xu,Rs as xp,Rt as xm,Sm as es,Sn as Us,So as Lc,Sp as Ll,Sq as Ld,Sr as Lu,Ss as Lp,St as Lm,Tm as ts,Tn as js,To as Fc,Tp as Fl,Tq as Fd,Tr as Fu,Ts as Fp,Tt as Fm,Um as rs,Un as ie,Uo as Mc,Up as Ml,Uq as Md,Ur as Mu,Us as Mp,Ut as Mm,Vm as ns,Vn as Ks,Vo as _c,Vp as _l,Vq as _d,Vr as _u,Vs as _p,Vt as _m,Wm as is,Wn as qs,Wo as Bc,Wp as Bl,Wq as Bd,Wr as Bu,Ws as Bp,Wt as Bm,Xm as os,Xn as Zs,Xo as Vc,Xp as Vl,Xq as Vd,Xr as Vu,Xs as Vp,Xt as Vm,Ym as as,Yn as Js,Yo as Wc,Yp as Wl,Yq as Wd,Yr as Wu,Ys as Wp,Yt as Wm,Zm as ss,Zn as $e,Zo as Hc,Zp as Hl,Zq as Hd,Zr as Hu,Zs as Hp,Zt as At,_m as cs,_n as F,_o as zc,_p as zl,_q as zd,_r as zu,_s as zp,_t as bt,an as ds,ao as oe,ap as Uc,aq as Ul,ar as Ud,as as Uu,at as Up,au as Pt,bn as us,bo as Ie,bp as jc,bq as jl,br as jd,bs as ju,bt as jp,bu as Tt,cn as ps,co as De,cp as Kc,cq as Kl,cr as Kd,cs as Ku,ct as Kp,cu as $t,dn as ms,do as Ys,dp as qc,dq as ql,dr as qd,ds as qu,dt as qp,du as It,en as fs,eo as Xs,ep as Zc,eq as Zl,er as Zd,es as Zu,et as Zp,eu as Dt,fn as gs,fo as we,fp as Jc,fq as Jl,fr as Jd,fs as Ju,ft as Jp,fu as wt,gn as hs,go as Qs,gp as Yc,gq as Yl,gr as Yd,gs as Yu,gt as Yp,gu as Et,hn as ys,ho as ec,hp as Xc,hq as Xl,hr as Xd,hs as Xu,ht as Xp,hu as Hm,in as Cs,io as tc,ip as Qc,iq as Ql,ir as Qd,is as Qu,it as Qp,iu as zm,jn as Ss,jo as rc,jp as el,jq as ed,jr as eu,js as ep,jt as em,ju as Gm,kn as As,ko as nc,kp as tl,kq as td,kr as tu,ks as tp,kt as tm,ku as Um,ln as bs,lo as Ee,lp as rl,lq as rd,lr as ru,ls as rp,lt as rm,lu as jm,mn as Rs,mo as q,mp as nl,mq as nd,mr as nu,ms as np,mt as nm,mu as Km,nn as Ps,no as ic,np as il,nq as id,nr as iu,ns as ip,nt as im,nu as qm,on as Ts,oo as oc,op as ol,oq as od,or as ou,os as op,ot as om,ou as Zm,pn as $s,po as ac,pp as al,pq as ad,pr as au,ps as ap,pt as am,pu as Jm,qn as Is,qo as sc,qp as sl,qq as sd,qr as su,qs as sp,qt as sm,qu as Ym,rn as be,ro as cc,rp as cl,rq as cd,rr as cu,rs as cp,rt as cm,ru as Xm,sn as Ds,so as lc,sp as ll,sq as ld,sr as lu,ss as lp,st as lm,su as Qm,tn as Re,to as dc,tp as dl,tq as dd,tr as du,ts as dp,tt as dm,tu as ef,un as Pe,uo as uc,up as ul,uq as ud,ur as uu,us as up,ut as um,uu as tf,vn as ws,vo as pc,vp as pl,vq as pd,vr as pu,vs as pp,vt as pm,vu as rf,wn as Es,wo as mc,wp as ml,wq as md,wr as mu,ws as mp,wt as mm,wu as nf,xn as vs,xo as fc,xp as fl,xq as fd,xr as fu,xs as fp,xt as fm,xu as of,yn as Os,yo as gc,yp as gl,yq as gd,yr as gu,ys as gp,yt as gm,yu as af,zn as Ns,zo as hc,zp as hl,zq as hd,zr as hu,zs as hp,zt as hm,zu as sf}from"./chunk-fsssdd5k.js";import{Ou as gt,Qu as Z}from"./chunk-0hw5wjjg.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 oo(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 ao(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 so(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 co(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 lo(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 uo(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 Pe(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 P of d)t.push(this.createComputeCacheBehavior(P,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 {
|
|
1
|
+
import{a as Ni,b as ki,c as xi,d as Li,e as Fi,f as _i,g as Mi,i as Bi,j as Vi,k as Wi,l as Hi,m as zi,n as Gi}from"./chunk-5hhyyhjt.js";import{$ as py,$a as nA,$b as nb,A as Vg,Aa as vS,Ab as vA,Ac as qi,Ad as Bb,B as Wg,Ba as OS,Bb as OA,Bd as Vb,C as Hg,Ca as NS,Cb as NA,Cd as Wb,D as zg,Da as kS,Db as kA,Dd as Hb,E as Gg,Ea as xS,Eb as xA,Ed as zb,F as Ug,Fa as LS,Fb as LA,Fd as Gb,G as jg,Ga as FS,Gb as FA,Gd as Ub,H as Kg,Ha as _S,Hb as _A,Hd as jb,I as qg,Ia as MS,Ib as MA,Ic as Zi,Id as Kb,J as Zg,Ja as BS,Jb as BA,Jd as qb,K as Jg,Ka as VS,Kb as VA,Kd as Zb,L as Yg,La as WS,Lb as WA,Ld as Jb,M as Xg,Ma as HS,Mb as HA,Md as Yb,N as gh,Na as zS,Nb as zA,Nd as Xb,O as hh,Oa as GS,Ob as GA,Od as Qb,P as yh,Pa as US,Pb as UA,Pd as go,Q as Ch,Qa as jS,Qb as jA,Qc as oo,Qd as ho,R as Sh,Ra as KS,Rb as KA,Rd as yo,S as Ah,Sa as qS,Sb as qA,Sd as Co,T as iy,Ta as ZS,Tb as ZA,U as oy,Ua as JS,Ub as JA,V as ay,Va as YS,Vb as YA,W as sy,Wa as XS,Wb as XA,X as cy,Xa as QS,Xb as QA,Y as ly,Ya as eA,Yb as eb,Z as dy,Za as tA,Zb as tb,_ as uy,_a as rA,_b as rb,aa as my,ab as iA,ac as ib,ad as so,ba as fy,bb as oA,bc as ob,bd as co,ca as gy,cb as aA,cc as ab,cd as lo,da as hy,db as sA,dc as sb,dd as uo,ea as yy,eb as cA,ec as cb,ed as po,fa as Cy,fb as lA,fc as lb,fd as mo,ga as Sy,gb as dA,gc as db,gd as fo,ha as Ay,hb as uA,hc as ub,ia as by,ib as pA,ic as pb,ja as Ry,jb as mA,jc as mb,ka as Py,kb as fA,kc as fb,la as Ty,lb as gA,lc as gb,ma as $y,mb as hA,mc as hb,na as Iy,nb as yA,nc as yb,oa as Dy,ob as CA,oc as Cb,od as Db,p as _f,pa as wy,pb as SA,pc as Sb,pd as wb,q as Mf,qa as Ey,qb as AA,qc as Ab,qd as Eb,r as Bf,ra as bS,rb as bA,rc as bb,rd as vb,s as Vf,sa as RS,sb as RA,sc as Rb,sd as Ob,t as kg,ta as PS,tb as PA,tc as Pb,td as Nb,u as xg,ua as TS,ub as TA,uc as Tb,ud as kb,v as Lg,va as $S,vb as $A,vc as $b,vd as xb,w as Fg,wa as IS,wb as IA,wc as Ib,wd as Lb,x as _g,xa as DS,xb as DA,xc as Ui,xd as Fb,y as Mg,ya as wS,yb as wA,yc as ji,yd as _b,z as Bg,za as ES,zb as EA,zc as Ki,zd as Mb}from"./chunk-ea7tn8nn.js";import{$d as io,Td as Ji,Ud as Yi,Vd as Xi,Wd as Qi,Xd as eo,Yd as to,Zd as ro,_d as no}from"./chunk-zh0apedk.js";import{he as ao}from"./chunk-whyttetx.js";import{Ae as Yr,Be as Xr,Ce as Qr,De as en,Ee as tn,Ff as gn,Jf as hn,Le as rn,Lf as yn,Mf as Cn,Nf as Sn,Of as An,Pf as bn,Qe as nn,Ue as on,Ye as an,af as sn,ef as cn,ie as cr,ke as lr,kf as ln,le as dr,me as ur,ne as pr,nf as dn,oe as mr,of as un,pe as fr,pf as pn,qf as mn,re as hr,se as Wr,te as zr,ue as Gr,ve as Ur,vf as fn,we as jr,xe as Kr,ye as qr,ze as Zr}from"./chunk-yf8stygs.js";import{Qf as Gt,Rf as jt,Sf as Kt}from"./chunk-mnmz8t7q.js";import{Uf as We}from"./chunk-n1fyryha.js";import{Vf as Vr}from"./chunk-ze5x2bpm.js";import{Wf as Jr}from"./chunk-k8x8mrkr.js";import{$f as br,Xf as yr,Yf as Cr,Zf as Sr,_f as Ar,ag as Rr,bg as Pr,cg as Tr,dg as $r,eg as Ir,fg as Dr,gg as wr,hg as Er,ig as vr,jg as Or,kg as Nr,lg as kr,mg as xr,ng as Y,og as Lr,pg as Fr,qg as _r,rg as Mr,sg as Br}from"./chunk-j06r5rwv.js";import{tg as J}from"./chunk-2ybcnrte.js";import{$h as ai,$i as wi,Ag as Dn,Ci as fi,Di as gi,Ei as hi,Fg as wn,Fi as yi,Gg as En,Hg as vn,Hh as ei,Ih as ti,Nh as ri,Ni as Ci,Og as ve,Oi as Si,Pi as Ai,Qg as On,Rg as fe,Ti as bi,Ui as Ri,Vi as Pi,Wi as Ti,Xi as $i,Yh as ni,Yi as Ii,Zh as ii,Zi as Di,_h as oi,ah as Mn,ai as si,aj as Ei,bh as Bn,bi as ci,bj as vi,ch as Vn,cj as Oi,dh as Wn,eh as Hn,fh as zn,fi as li,gh as Gn,gi as di,hh as Un,hi as ui,ii as pi,lh as jn,li as mi,mh as Kn,nh as qn,oh as Zn,rh as Jn,sh as Yn,th as Xn,ug as Rn,uh as Qn,vg as Pn,wg as Tn,xg as $n,yg as me,zg as In}from"./chunk-t8hzekmk.js";import{hj as Nn,ij as kn,jj as xn,kj as Ln,lj as Fn,mj as _n}from"./chunk-n5xmh0ma.js";import{nj as gr,oj as Hr}from"./chunk-6cxb8d6y.js";import{pj as Ve}from"./chunk-ess6vxfj.js";import{rj as Ut}from"./chunk-j1g67djb.js";import{tj as zt}from"./chunk-ac87ds1k.js";import{$j as Cg,Aj as Uf,Bj as jf,Cj as Kf,Dj as qf,Ej as Zf,Fj as Jf,Gj as Yf,Hj as Xf,Ij as Qf,Jj as eg,Kj as tg,Lj as rg,Mj as ng,Nj as ig,Oj as og,Pj as ag,Qj as sg,Rj as cg,Sj as lg,Tj as dg,Uj as ug,Vj as pg,Wj as mg,Xj as fg,Yj as gg,Zj as hg,_j as yg,ak as Sg,bk as Ag,ck as bg,dk as Rg,ek as Pg,fk as Tg,gk as $g,hk as Ig,ik as Dg,jk as wg,kk as Eg,lk as vg,mk as Og,nk as Ng,wj as Wf,xj as Hf,yj as zf,zj as Gf}from"./chunk-q22qfwsc.js";import{ok as _t,qk as Mt,rk as Bt,sk as Vt,tk as Wt,uk as Ht}from"./chunk-7z50g5xz.js";import{Ak as xt,Ck as Lt,Dk as Ft,vk as vt,xk as Ot,yk as Nt,zk as kt}from"./chunk-n1hg0jxs.js";import{$k as Ih,$l as Xy,$m as KC,Al as Qh,Am as $C,An as SS,Bl as ey,Bm as IC,Bn as AS,Cl as ty,Cm as DC,Dl as ry,Dm as wC,El as ny,Em as EC,Fl as vy,Fm as vC,Gk as Qg,Gl as Oy,Gm as OC,Hk as eh,Hl as Ny,Hm as NC,Ik as th,Il as ky,Im as kC,Jk as rh,Jl as xy,Jm as xC,Kk as nh,Kl as Ly,Km as LC,Lk as ih,Ll as Fy,Lm as FC,Mk as oh,Ml as _y,Mm as _C,Nk as ah,Nl as My,Nm as MC,Ok as sh,Ol as By,Om as BC,Pk as ch,Pl as Vy,Pm as VC,Qk as lh,Ql as Wy,Qm as WC,Rk as dh,Rl as Hy,Rm as HC,Sk as uh,Sl as zy,Sm as zC,Tk as ph,Tl as Gy,Tm as GC,Uk as mh,Ul as Uy,Um as qt,Vk as fh,Vl as jy,Vm as Zt,Wk as bh,Wl as Ky,Wm as Jt,Xk as Rh,Xl as qy,Xm as Yt,Yk as Ph,Yl as Zy,Ym as Xt,Zk as Th,Zl as Jy,Zm as UC,_k as $h,_l as Yy,_m as jC,al as Dh,am as Qy,an as qC,bl as wh,bm as eC,bn as ZC,cl as Eh,cm as tC,cn as JC,dl as vh,dm as rC,dn as YC,el as Oh,em as nC,en as XC,fl as Nh,fm as iC,fn as QC,gl as kh,gm as oC,gn as eS,hl as xh,hm as aC,hn as tS,il as Lh,im as sC,in as rS,jl as Fh,jm as cC,jn as nS,kl as _h,km as lC,kn as Qt,ll as Mh,lm as dC,ln as iS,ml as Bh,mm as uC,mn as oS,nl as Vh,nm as pC,nn as aS,ol as Wh,om as mC,on as sS,pl as Hh,pm as fC,pn as cS,ql as zh,qm as gC,qn as lS,rl as Gh,rm as hC,rn as dS,sl as Uh,sm as yC,sn as uS,tl as jh,tm as CC,tn as pS,ul as Kh,um as SC,un as mS,vl as qh,vm as AC,vn as fS,wl as Zh,wm as bC,wn as gS,xl as Jh,xm as RC,xn as hS,yl as Yh,ym as PC,yn as yS,zl as Xh,zm as TC,zn as CS}from"./chunk-q9a1z53k.js";import{Cn as er,Dn as tr,En as rr,Fn as nr,Gn as ir,Hn as or,In as ar,Jn as sr}from"./chunk-4wdxsnn2.js";import{$n as Is,$o as Ie,$p as sl,$q as sd,$r as su,$s as sp,$t as sm,$u as Tt,Ao as Js,Ap as xc,Aq as xl,Ar as xd,As as xu,At as xp,Au as xm,Av as $f,Bo as Ys,Bp as Lc,Bq as Ll,Br as Ld,Bs as Lu,Bt as Lp,Bu as Lm,Bv as If,Co as Xs,Cp as Fc,Cq as Fl,Cr as Fd,Cs as Fu,Ct as Fp,Cu as Fm,Cv as Df,Do as Qs,Dp as _c,Dq as _l,Dr as _d,Ds as _u,Dt as _p,Du as _m,Dv as wf,Eo as ec,Ep as Mc,Eq as Ml,Er as Md,Es as Mu,Et as Mp,Eu as Mm,Ev as Ef,Fo as tc,Fp as Bc,Fq as Bl,Fr as Bd,Fs as Bu,Ft as Bp,Fu as Bm,Fv as vf,Go as rc,Gp as Vc,Gq as Vl,Gr as Vd,Gs as Vu,Gt as Vp,Gu as Vm,Gv as Of,Ho as re,Hp as Wc,Hq as Wl,Hr as Wd,Hs as Wu,Ht as Wp,Hu as Wm,Hv as Nf,Io as nc,Ip as Hc,Iq as Hl,Ir as Hd,Is as Hu,It as Hp,Iu as Hm,Iv as kf,Jo as ic,Jp as zc,Jq as zl,Jr as zd,Js as zu,Jt as zp,Ju as zm,Jv as xf,Kn as ls,Ko as oc,Kp as Gc,Kq as Gl,Kr as Gd,Ks as Gu,Kt as Gp,Ku as Gm,Kv as Lf,Ln as ds,Lo as ne,Lp as Uc,Lq as Ul,Lr as Ud,Ls as Uu,Lt as Up,Lu as Um,Lv as Ff,Mn as us,Mo as E,Mp as jc,Mq as jl,Mr as jd,Ms as ju,Mt as jp,Mu as jm,Nn as ps,No as Te,Np as Kc,Nq as Kl,Nr as Kd,Ns as Ku,Nt as Kp,Nu as Km,On as ms,Oo as j,Op as qc,Oq as ql,Or as qd,Os as qu,Ot as qp,Ou as qm,Pn as fs,Po as L,Pp as Zc,Pq as Zl,Pr as Zd,Ps as Zu,Pt as Zp,Pu as Zm,Qn as gs,Qo as ac,Qp as Jc,Qq as Jl,Qr as Jd,Qs as Ju,Qt as Jp,Qu as Jm,Rn as hs,Ro as sc,Rp as Yc,Rq as Yl,Rr as Yd,Rs as Yu,Rt as Yp,Ru as Ym,Sn as ys,So as ie,Sp as Xc,Sq as Xl,Sr as Xd,Ss as Xu,St as Xp,Su as Xm,Tn as Cs,To as cc,Tp as Qc,Tq as Ql,Tr as Qd,Ts as Qu,Tt as Qp,Tu as Qm,Un as Ss,Uo as lc,Up as el,Uq as ed,Ur as eu,Us as ep,Ut as em,Uu as ef,Vn as As,Vo as dc,Vp as tl,Vq as td,Vr as tu,Vs as tp,Vt as tm,Vu as tf,Wn as bs,Wo as uc,Wp as rl,Wq as rd,Wr as ru,Ws as rp,Wt as rm,Wu as rf,Xn as Rs,Xo as $e,Xp as nl,Xq as nd,Xr as nu,Xs as np,Xt as nm,Xu as At,Yn as Ps,Yo as F,Yp as il,Yq as id,Yr as iu,Ys as ip,Yt as im,Yu as bt,Zn as Ts,Zo as K,Zp as ol,Zq as od,Zr as ou,Zs as op,Zt as om,Zu as Rt,_n as $s,_o as oe,_p as al,_q as ad,_r as au,_s as ap,_t as am,_u as Pt,ao as Ds,ap as De,aq as cl,ar as cd,as as cu,at as cp,au as cm,av as $t,bo as ws,bp as pc,bq as ll,br as ld,bs as lu,bt as lp,bu as lm,bv as It,co as Es,cp as mc,cq as dl,cr as dd,cs as du,ct as dp,cu as dm,cv as Dt,do as vs,dp as we,dq as ul,dr as ud,ds as uu,dt as up,du as um,dv as wt,eo as Os,ep as fc,eq as pl,er as pd,es as pu,et as pp,eu as pm,ev as Et,fo as Ns,fp as gc,fq as ml,fr as md,fs as mu,ft as mp,fu as mm,fv as nf,go as ks,gp as hc,gq as fl,gr as fd,gs as fu,gt as fp,gu as fm,gv as of,ho as xs,hp as yc,hq as gl,hr as gd,hs as gu,ht as gp,hu as gm,hv as af,io as Ls,ip as Cc,iq as hl,ir as hd,is as hu,it as hp,iu as hm,iv as sf,jo as Fs,jp as Ee,jq as yl,jr as yd,js as yu,jt as yp,ju as ym,jv as cf,ko as _s,kp as q,kq as Cl,kr as Cd,ks as Cu,kt as Cp,ku as Cm,kv as lf,lo as Ms,lp as Sc,lq as Sl,lr as Sd,ls as Su,lt as Sp,lu as Sm,lv as df,mo as Bs,mp as Ac,mq as Al,mr as Ad,ms as Au,mt as Ap,mu as Am,mv as uf,no as Vs,np as bc,nq as bl,nr as bd,ns as bu,nt as bp,nu as bm,nv as pf,oo as Ws,op as Rc,oq as Rl,or as Rd,os as Ru,ot as Rp,ou as Rm,ov as mf,po as be,pp as Pc,pq as Pl,pr as Pd,ps as Pu,pt as Pp,pu as Pm,pv as ff,qo as Hs,qp as Tc,qq as Tl,qr as Td,qs as Tu,qt as Tp,qu as Tm,qv as gf,ro as Re,rp as $c,rq as $l,rr as $d,rs as $u,rt as $p,ru as $m,rv as hf,so as Pe,sp as Ic,sq as Il,sr as Id,ss as Iu,st as Ip,su as Im,sv as yf,to as zs,tp as Dc,tq as Dl,tr as Dd,ts as Du,tt as Dp,tu as Dm,tv as Cf,uo as Gs,up as wc,uq as wl,ur as wd,us as wu,ut as wp,uu as wm,uv as Sf,vo as Us,vp as Ec,vq as El,vr as Ed,vs as Eu,vt as Ep,vu as Em,vv as Af,wo as js,wp as vc,wq as vl,wr as vd,ws as vu,wt as vp,wu as vm,wv as bf,xo as Ks,xp as Oc,xq as Ol,xr as Od,xs as Ou,xt as Op,xu as Om,xv as Rf,yo as qs,yp as Nc,yq as Nl,yr as Nd,ys as Nu,yt as Np,yu as Nm,yv as Pf,zo as Zs,zp as kc,zq as kl,zr as kd,zs as ku,zt as kp,zu as km,zv as Tf}from"./chunk-r8t25tbm.js";import{Mv as gt,Ov as Z}from"./chunk-zjyz926j.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 Ao(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 bo(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 Ro(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 Po(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 To(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 $o(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 Pe(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 P of d)t.push(this.createComputeCacheBehavior(P,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
2
|
${u}
|
|
3
3
|
}`:` handle ${l.path} {
|
|
4
4
|
${u}
|
|
@@ -10,8 +10,8 @@ ${a.join(`
|
|
|
10
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}=Te.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:P}=ne.createCertificate({domain:u,subdomains:b,slug:e,environment:t,validationMethod:"DNS",hostedZoneId:d?.hostedZoneId});s=P,this.builder.addResource(P,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 P=`${e}${t}TaskExecRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(P,{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":[P,"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:[P,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 I=`${e}${t}${u}Service`.replace(/[^a-zA-Z0-9]/g,""),D=b.desiredCount||1;this.builder.addResource(I,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${e}-${t}-${u}`,Cluster:{Ref:a},TaskDefinition:{Ref:y},DesiredCount:D,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 T=b.autoScaling;if(T){let v=`${e}${t}${u}ScalableTarget`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(v,{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{MaxCapacity:T.max||10,MinCapacity:T.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:I}),T.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:T.targetCpuUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}});if(T.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:T.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}=Ie.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}=De.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 P=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:P,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}),P=ve(r.appUpdates),g=P.length>0?`${C}
|
|
11
11
|
${P.join(`
|
|
12
12
|
`)}
|
|
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}=ne.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}=re.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 D=typeof f.website==="object"?f.website:{},T=re.enableWebsiteHosting(A,D.indexDocument||"index.html",D.errorDocument);this.builder.addResource(R,T)}let I=this.normalizeMountPath(f);if(h&&c&&i&&!(I&&o!=="public")){let D=`${e}${t}${o}CDN`.replace(/[^a-zA-Z0-9]/g,""),T=[];if(f.aliases&&f.aliases.length>0)T.push(...f.aliases);else if(o==="public"){if(T.push(i),r?.domains?.includes(`www.${i}`))T.push(`www.${i}`)}else if(o==="docs")T.push(`docs.${i}`);else if(o==="blog")T.push(`blog.${i}`);let v=typeof f.website==="object"?f.website:{},O=f.spa===!0,
|
|
14
|
-
else if (!uri.includes('.')) { request.uri += '.html'; } return request; }`}});let Q=[{Id:B,DomainName:{"Fn::Sub":`\${${R}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:c}}],G=[],ee=[];if(this.shouldRouteStorageBucketToCompute(o,f)){this.appendComputeAppOrigin(Q,G,ee,e,t,this.resolveComputeCachePathPatterns(f.computeRoutes));for(let w of y){let U=`S3-${e}-${t}-${w.name}`,te=`${e}${t}${w.name}PathMountRewrite`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(te,{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)}}),Q.push({Id:U,DomainName:{"Fn::Sub":`\${${w.logicalId}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:c}}),ee.push(w.logicalId,te);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":[te,"FunctionARN"]}}]})}}let ge={Type:"AWS::CloudFront::Distribution",DependsOn:[R,c,...x?[x]:[],...ee],Properties:{DistributionConfig:{Enabled:!0,Comment:`${e} ${t} ${o} site`,DefaultRootObject:"index.html",Origins:Q,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}:{},...T.length>0?{Aliases:T}:{},ViewerCertificate:z,PriceClass:"PriceClass_100",HttpVersion:"http2and3",IPV6Enabled:!0,CustomErrorResponses:_}}};if(a)ge.DependsOn.push(a);this.builder.addResource(D,ge);let He=`${R}CloudFrontPolicy`;if(this.builder.addResource(He,{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(o,f))for(let w of y){let U=`${w.logicalId}CloudFrontPolicy`;this.builder.addResource(U,{Type:"AWS::S3::BucketPolicy",DependsOn:[w.logicalId,D],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/\${${D}}`}}}}]}}})}if(T.length>0)s.push({name:o,bucketLogicalId:R,distLogicalId:D,oacLogicalId:c,aliases:T});this.builder.addOutput(`${o}CloudFrontDomain`,{Value:{"Fn::GetAtt":[D,"DomainName"]},Description:`CloudFront domain for ${o}`}),this.builder.addOutput(`${o}CloudFrontDistributionId`,{Value:{Ref:D},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=[],I=[];if(c.routeCompute)this.appendComputeAppOrigin(A,R,I,e,t,this.resolveComputeCachePathPatterns(c.computeRoutes));let D=f&&y?{AcmCertificateArn:a&&!o?{Ref:a}:f,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},T=[...I];if(a&&!o&&y)T.push(a);let v={Type:"AWS::CloudFront::Distribution",...T.length>0?{DependsOn:T}:{},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:D,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}=ie.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}=ie.createDeadLetterQueue(o,{slug:e,environment:t,maxReceiveCount:c.maxReceiveCount});f=A,this.builder.addResource(A,h);let I=this.builder.getResources()[o];if(I?.Properties)I.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 I=`${o}AlarmTopic`;this.builder.addResource(I,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-${m}-alarms`,DisplayName:`${m} Queue Alarms`}}),h.notificationEmails.forEach((D,T)=>{this.builder.addResource(`${I}Sub${T}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:I},Protocol:"email",Endpoint:D}})}),S={Ref:I}}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}=oe.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}=oe.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 I=1;I<=3;I++){let D=`DkimRecord${I}${m.replace(/\./g,"")}`;this.builder.addResource(D,{Type:"AWS::Route53::RecordSet",DependsOn:[y],Properties:{HostedZoneId:o,Name:{"Fn::GetAtt":[y,`DkimDNSTokenName${I}`]},Type:"CNAME",TTL:1800,ResourceRecords:[{"Fn::GetAtt":[y,`DkimDNSTokenValue${I}`]}]}})}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:I,policyLogicalId:D}=L.createEmailLambdaRole({slug:e,environment:t,s3BucketArn:`arn:aws:s3:::${S}`,sesIdentityArn:`arn:aws:ses:${h}:*:identity/${m}`});this.builder.addResource(I,A),this.builder.addResource(D,R);let{function:T,permission:v,logicalId:O,permissionLogicalId:M}=L.createInboundEmailLambda({slug:e,environment:t,roleArn:{"Fn::GetAtt":[I,"Arn"]},s3BucketName:S,organizedPrefix:"mailboxes/"});this.builder.addResource(O,T),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 P=this.mergedConfig.infrastructure?.fileSystem;if(P&&Object.keys(P).length>0){this.generateNetworkInfrastructure(e,t);for(let[m,c]of Object.entries(P)){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,""),P=`${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(P,{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=`${P}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:P},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/\${${P}.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 I=`${g}AlarmTopic`;this.builder.addResource(I,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-realtime-alarms`,DisplayName:"Realtime WebSocket Alarms"}}),A.notificationEmails.forEach((D,T)=>{this.builder.addResource(`${I}Sub${T}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:I},Protocol:"email",Endpoint:D}})}),R={Ref:I}}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`
|
|
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}=ne.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}=re.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 D=typeof f.website==="object"?f.website:{},T=re.enableWebsiteHosting(A,D.indexDocument||"index.html",D.errorDocument);this.builder.addResource(R,T)}let I=this.normalizeMountPath(f);if(h&&c&&i&&!(I&&o!=="public")){let D=`${e}${t}${o}CDN`.replace(/[^a-zA-Z0-9]/g,""),T=[];if(f.aliases&&f.aliases.length>0)T.push(...f.aliases);else if(o==="public"){if(T.push(i),r?.domains?.includes(`www.${i}`))T.push(`www.${i}`)}else if(o==="docs")T.push(`docs.${i}`);else if(o==="blog")T.push(`blog.${i}`);let v=typeof f.website==="object"?f.website:{},O=f.spa===!0,_=v.errorDocument||(O?"index.html":"404.html"),M=[];if(O)M.push({ErrorCode:403,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300});else M.push({ErrorCode:403,ResponseCode:404,ResponsePagePath:`/${_}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${_}`,ErrorCachingMinTTL:300});let z=l&&T.length>0?{AcmCertificateArn:l,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:a&&T.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 Q=[{Id:B,DomainName:{"Fn::Sub":`\${${R}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:c}}],G=[],ee=[];if(this.shouldRouteStorageBucketToCompute(o,f)){this.appendComputeAppOrigin(Q,G,ee,e,t,this.resolveComputeCachePathPatterns(f.computeRoutes));for(let w of y){let U=`S3-${e}-${t}-${w.name}`,te=`${e}${t}${w.name}PathMountRewrite`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(te,{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)}}),Q.push({Id:U,DomainName:{"Fn::Sub":`\${${w.logicalId}}.s3.${k}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:c}}),ee.push(w.logicalId,te);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":[te,"FunctionARN"]}}]})}}let ge={Type:"AWS::CloudFront::Distribution",DependsOn:[R,c,...x?[x]:[],...ee],Properties:{DistributionConfig:{Enabled:!0,Comment:`${e} ${t} ${o} site`,DefaultRootObject:"index.html",Origins:Q,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}:{},...T.length>0?{Aliases:T}:{},ViewerCertificate:z,PriceClass:"PriceClass_100",HttpVersion:"http2and3",IPV6Enabled:!0,CustomErrorResponses:M}}};if(a)ge.DependsOn.push(a);this.builder.addResource(D,ge);let He=`${R}CloudFrontPolicy`;if(this.builder.addResource(He,{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(o,f))for(let w of y){let U=`${w.logicalId}CloudFrontPolicy`;this.builder.addResource(U,{Type:"AWS::S3::BucketPolicy",DependsOn:[w.logicalId,D],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/\${${D}}`}}}}]}}})}if(T.length>0)s.push({name:o,bucketLogicalId:R,distLogicalId:D,oacLogicalId:c,aliases:T});this.builder.addOutput(`${o}CloudFrontDomain`,{Value:{"Fn::GetAtt":[D,"DomainName"]},Description:`CloudFront domain for ${o}`}),this.builder.addOutput(`${o}CloudFrontDistributionId`,{Value:{Ref:D},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=[],I=[];if(c.routeCompute)this.appendComputeAppOrigin(A,R,I,e,t,this.resolveComputeCachePathPatterns(c.computeRoutes));let D=f&&y?{AcmCertificateArn:a&&!o?{Ref:a}:f,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},T=[...I];if(a&&!o&&y)T.push(a);let v={Type:"AWS::CloudFront::Distribution",...T.length>0?{DependsOn:T}:{},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:D,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}=ie.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}=ie.createDeadLetterQueue(o,{slug:e,environment:t,maxReceiveCount:c.maxReceiveCount});f=A,this.builder.addResource(A,h);let I=this.builder.getResources()[o];if(I?.Properties)I.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 I=`${o}AlarmTopic`;this.builder.addResource(I,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-${m}-alarms`,DisplayName:`${m} Queue Alarms`}}),h.notificationEmails.forEach((D,T)=>{this.builder.addResource(`${I}Sub${T}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:I},Protocol:"email",Endpoint:D}})}),S={Ref:I}}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}=oe.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}=oe.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 I=1;I<=3;I++){let D=`DkimRecord${I}${m.replace(/\./g,"")}`;this.builder.addResource(D,{Type:"AWS::Route53::RecordSet",DependsOn:[y],Properties:{HostedZoneId:o,Name:{"Fn::GetAtt":[y,`DkimDNSTokenName${I}`]},Type:"CNAME",TTL:1800,ResourceRecords:[{"Fn::GetAtt":[y,`DkimDNSTokenValue${I}`]}]}})}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:I,policyLogicalId:D}=L.createEmailLambdaRole({slug:e,environment:t,s3BucketArn:`arn:aws:s3:::${S}`,sesIdentityArn:`arn:aws:ses:${h}:*:identity/${m}`});this.builder.addResource(I,A),this.builder.addResource(D,R);let{function:T,permission:v,logicalId:O,permissionLogicalId:_}=L.createInboundEmailLambda({slug:e,environment:t,roleArn:{"Fn::GetAtt":[I,"Arn"]},s3BucketName:S,organizedPrefix:"mailboxes/"});this.builder.addResource(O,T),this.builder.addResource(_,v);let M=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(M.resources)){if(k.Type==="AWS::SES::ReceiptRule")k.DependsOn=[_,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 P=this.mergedConfig.infrastructure?.fileSystem;if(P&&Object.keys(P).length>0){this.generateNetworkInfrastructure(e,t);for(let[m,c]of Object.entries(P)){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,""),P=`${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(P,{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=`${P}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:P},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/\${${P}.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 I=`${g}AlarmTopic`;this.builder.addResource(I,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${e}-${t}-realtime-alarms`,DisplayName:"Realtime WebSocket Alarms"}}),A.notificationEmails.forEach((D,T)=>{this.builder.addResource(`${I}Sub${T}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:I},Protocol:"email",Endpoint:D}})}),R={Ref:I}}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
|
|
|
@@ -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 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=ae(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 ae(e,t=[]){if(typeof e!=="object"||e===null)return t;if(Array.isArray(e)){for(let r of e)ae(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))ae(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
|
|
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=ae(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 ae(e,t=[]){if(typeof e!=="object"||e===null)return t;if(Array.isArray(e)){for(let r of e)ae(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))ae(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 Bo(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
|
# ==========================================
|
|
@@ -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
|
|
509
|
+
`}function Vo(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
|
|
|
@@ -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
|
|
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]),P=Buffer.alloc(32),g=Buffer.alloc(32);u.copy(P,32-u.length),C.copy(g,32-C.length);let m=Buffer.concat([P,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 ce(e){if(e.length===1)return`http.host eq ${W(e[0])}`;return`http.host in ${Le(e)}`}function le(e,t={}){if(t.enabled===!1||e.length===0)return[];let r=ce(e),n=[],d=(t.bypassPaths??[]).map((P)=>`starts_with(http.request.uri.path, ${W(P)})`),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 de(e,t,r){if(e.length===0||!t||!r)return[];return[{action:"rewrite",description:"origin guard header",expression:`(${ce(e)})`,enabled:!0,action_parameters:{headers:{[t]:{operation:"set",value:r}}}}]}var N=(e)=>e===void 0?void 0:e?"on":"off";function ue(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 pe(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:P=!1}=e,g={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(n.length===0)return g;let m=[],c=s&&!P?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 pe({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&&me(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=ue(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=le(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=de(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()))]:fe(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 X(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 X("POST","/pages/assets/check-missing",`Bearer ${e}`,{hashes:t});return new Set(r)}async upsertHashes(e,t){await X("POST","/pages/assets/upsert-hashes",`Bearer ${e}`,{hashes:t})}async uploadBatch(e,t){let r=t.map((n)=>({key:n.hash,value:n.base64,metadata:{contentType:St(n.extension)},base64:!0}));await X("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 await this.upsertHashes(r,t.map((l)=>l.hash)),{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-qrte4gy2.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 P=Buffer.from(C).toString("base64"),g=p.name.lastIndexOf("."),m=g>0?p.name.slice(g+1):"";d.push({path:b,hash:await _e(P,m),base64:P,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 X(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{np as ABTestManager,_r as ACMClient,Br as ACMDnsValidator,ke as ACME_DIRECTORIES,F as AI,rh as API_IDEMPOTENCY_TTL_MS,eh as API_TOKEN_DEFAULT_TTL_MS,th as API_TOKEN_MAX_TTL_MS,aS as API_VERSION,Vg as AUTHORIZATION_CAPABILITIES,Dg as AUTH_ACTION_TOKEN_TTL_MS,wg as AUTH_MFA_CHALLENGE_TTL_MS,Eg as AUTH_OIDC_TRANSACTION_TTL_MS,Ig as AUTH_SESSION_ABSOLUTE_TTL_MS,$g as AUTH_SESSION_IDLE_TTL_MS,ml as AWSAPIError,zt as AWSClient,Ve as AWSCloudFormationClient,We as AWSCloudFrontClient,Uu as AWSConfigManager,sc as AWS_PSEUDO_PARAMETERS,ru as AWS_REGIONS,st as AcmeClient,Zt as AlertEvaluator,qt as AlertStore,pC as AnomalyConfigStore,De as ApiGateway,tS as ApiServiceError,mn as ApplicationAutoScalingClient,ac as Arn,tc as AssetHasher,Qs as Auth,vg as AuthenticationStore,nS as AutomationApiService,nh as AutomationIdentityStore,PA as AwsAuroraDataAdapter,wA as AwsAuroraTransport,Ab as AwsDatabaseBackupSource,Bn as AwsDriver,TA as AwsElastiCacheDataAdapter,EA as AwsElastiCacheTransport,yS as AwsIamCapabilityScanner,Eb as AwsInfrastructureBackupSource,RA as AwsRdsDataAdapter,DA as AwsRdsTransport,YA as AwsRegionalDriver,xb as AwsSecretsManagerConfigurationBackend,XC as AwsSpendTransport,Lb as AwsSsmConfigurationBackend,Cb as BackupCoordinator,Wu as BackupManager,mb as BackupStore,Sm as BatchProcessingManager,tn as BedrockClient,en as BedrockRuntimeClient,ry as BitbucketSourceAdapter,Qu as BlueGreenManager,nm as BounceComplaintHandler,kp as BuildOptimizationManager,vA as BunDockerRuntime,Ib as BunDockerVolumeRuntime,Pb as BunFilesystemArchiveRuntime,zs as CDN,bt as CHAIN_HEADER,Ar as CLOUDFLARE_MANAGED_RULE_PREFIX,bu as COMMON_CROSS_ACCOUNT_ROLES,_g as CONTROL_PLANE_SCHEMA_VERSION,oe as Cache,tp as CanaryManager,Dp as CertificateManager,_h as CloudBlockVolumeDriver,Xn as CloudDriverFactory,cl as CloudError,cc as CloudFormationBuilder,Ve as CloudFormationClient,We as CloudFrontClient,Ku as CloudTrailManager,Kr as CloudWatchLogsClient,Me as CloudflarePagesProvider,br as CloudflareProvider,zd as CommandHistory,ic as Communication,Hh as ComposeApplicationService,Wh as ComposeApplicationStore,rn as ComprehendClient,E as Compute,QC as ComputeSpendTransport,ll as ConfigurationError,Mb as ConfigurationService,vb as ConfigurationStore,qr as ConnectClient,IA as ContainerDataAdapter,Lp as ContainerRegistryManager,wb as ControlPlaneBackupSource,db as ControlPlaneCleanupDriver,Xg as ControlPlaneStore,_y as CounterTracker,dl as CredentialError,qd as CrossRegionReferenceManager,wc as DASHBOARD_ENTRY,Ec as DASHBOARD_PORT_BASE,vc as DASHBOARD_PORT_SPAN,Dc as DASHBOARD_STATE_DIR,Ii as DEFAULT_ATTACK_MODE_HOURS,er as DEFAULT_DDOS_THRESHOLDS,Ly as DEFAULT_METER_MAPPINGS,Iy as DEFAULT_PRICE_BOOK,Tt as DEFAULT_RECURSION_LIMITS,Tl as DEFAULT_SERVICE_LIMITS,us as DEFAULT_STATE_DIR,xe as DEFAULT_STATIC_ASSET_EXTENSIONS,vC as DEFAULT_TELEMETRY_POLICY,Hy as DEFAULT_THRESHOLDS,Ih as DEPLOYMENT_QUEUE_KINDS,At as DEPTH_HEADER,mC as DETECTABLE_SIGNALS,QS as DIAGNOSTIC_PRESETS,ym as DLQMonitoringManager,Gs as DNS,Qp as DNSSECManager,AA as DataServiceLifecycle,CA as DataServiceStore,K as Database,bp as DatabaseUserManager,yl as DebugLogger,Bs as DependencyGraph,ec as Deployment,ul as DeploymentError,zu as DisasterRecoveryManager,Fr as DnsProviderFactory,OA as DockerDataTransport,GS as DockerDiscoveryAdapter,Fh as DockerNamedVolumeDriver,Db as DockerVolumeBackupSource,Rh as DurableOperationQueue,Ph as DurableQueueWorker,Yr as DynamoDBClient,gr as EC2Client,Vr as ECRClient,Wr as ECSClient,bn as EFSClient,Zr as ELBv2Client,yy as ENFORCEMENT_ACTIONS,Yy as ENFORCEMENT_DESCRIPTIONS,Cy as ENFORCEMENT_SEVERITY,vf as ENVIRONMENT_LABEL,qS as EcsRuntimeAdapter,Ri as EdgeRateLimiter,un as ElastiCacheClient,L as Email,um as EmailAdvanced,om as EmailAnalyticsManager,Kt as EmailClient,pm as EmailHandlers,lm as EmailTemplateManager,NA as EncryptedDataSecretStore,fl as ErrorCodes,dn as EventBridgeClient,pA as EventBridgeJobAdapter,Fb as ExternalConfigurationBackend,gm as FIFOQueueManager,CC as FOCUS_VERSION,wl as FileCache,j as FileSystem,Tb as FilesystemBackupSource,MA as FleetService,FA as FleetStore,oc as Fn,ny as GiteaSourceAdapter,ey as GithubSourceAdapter,ty as GitlabSourceAdapter,Zd as GlobalResourceManager,Sr as GoDaddyProvider,Zu as GuardDutyManager,Mt as HOST_SITES_DIR,_l as HashCache,hf as HealthCheckManager,Xt as HealthCheckRunner,jn as HetznerClient,Jn as HetznerDriver,Gt as IAMClient,$n as IPV6_EXCLUDED_HOST_LABELS,Op as ImageScanningManager,Ke as InfrastructureGenerator,jg as InvalidOperationTransitionError,Ks as JobLoader,mA as JobProviderReconciler,gA as JobService,lA as JobStore,ln as KendraClient,af as LARAVEL_SERVERLESS_BUILD_STEPS,jr as LambdaClient,zp as LambdaConcurrencyManager,Zp as LambdaDLQManager,Up as LambdaDestinationsManager,Bp as LambdaLayersManager,ZS as LambdaRuntimeAdapter,Kp as LambdaVPCManager,Wp as LambdaVersionsManager,kb as LocalEncryptedConfigurationBackend,$b as LogicalDatabaseBackupSource,up as LogsManager,Em as MANAGED_NODE_VERSIONS,ci as MANAGEMENT_DASHBOARD_SITE,Lc as MANAGEMENT_DASHBOARD_SITE_PREFIX,$i as MAX_CONTROL_HOURS,Jg as MAX_CONTROL_PLANE_ERROR_BYTES,Zg as MAX_CONTROL_PLANE_JSON_BYTES,hy as METERS,gy as METER_KEYS,Sy as MICRO_CENTS,Ky as MIN_PROJECTION_CONFIDENCE,En as MTA_STS_PORT,sb as MaintenanceService,ob as MaintenanceStore,Ys as Messaging,lp as MetricsManager,gp as MigrationManager,cd as MockCloudFormation,dd as MockDynamoDB,ld as MockS3,we as Monitoring,gu as MultiAccountManager,jd as MultiRegionManager,Dd as MultiStepProgress,Te as Network,Cf as NetworkSecurityManager,Yt as NotificationRouter,Xr as OpenSearchClient,Ug as OptimisticConcurrencyError,hu as OrganizationManager,ht as PAGES_MAX_FILE_BYTES,cf as PHP_DEFAULT_EXCLUDES,xm as PHP_LAYER_EXTENSIONS,Ef as PROJECT_LABEL,yr as PROXIABLE_RECORD_TYPES,nc as ParameterStore,Sp as PerformanceManager,Ie as Permissions,cn as PersonalizeClient,js as Phone,mm as PhoneAdvanced,Us as PhoneHandlers,WA as PlacementService,VA as PlacementStore,an as PollyClient,Cr as PorkbunProvider,uS as PreDeployScanner,pd as PreviewEnvironmentManager,$h as PreviewEnvironmentService,Th as PreviewEnvironmentStore,yd as PreviewNotificationService,Id as ProgressBar,op as ProgressiveDeploymentManager,Di as ProtectionControlStore,Ds as Pseudo,ie as Queue,Sh as QueueCancellationError,bm as QueueManagementManager,ls as QueuePresets,Ah as QueueTimeoutError,Ci as RATE_LIMIT_KEY_SEPARATOR,Jr as RDSClient,Su as RECOMMENDED_ACCOUNT_STRUCTURES,Au as RECOMMENDED_SCPS,Jh as RELEASE_QUEUE_KINDS,Vd as REPL,Hd as REPLCommandBuilder,Wd as REPLContext,Of as ROLE_LABEL,Ul as RateLimiter,ds as RealtimePresets,EC as RecordingSpendTransport,Dt as RecursionGuard,q as Redirects,Jd as RegionPairManager,ZA as RegionService,qA as RegionStore,Hs as Registry,nn as RekognitionClient,jh as ReleaseService,Uh as ReleaseStore,HA as RemoteBuildService,yp as ReplicaManager,Af as ResourceManagementManager,bh as RetryableOperationError,J as Route53Client,hr as Route53DomainsClient,Ir as Route53Provider,tm as Route53ResolverManager,Yp as Route53RoutingManager,eA as RuntimeOperationService,tA as RuntimeStreamRegistry,yb as S3BackupDestinationAdapter,Ut as S3Client,al as S3Error,dS as SECRET_PATTERNS,dC as SENSITIVITY_THRESHOLDS,jt as SESClient,Js as SMS,Gr as SNSClient,JC as SPEND_CYCLE_SECONDS,TC as SPEND_GATE_SETTING,KC as SPEND_LEASE_SETTING,Ur as SQSClient,Hr as SSMClient,ps as STATE_DIR_ENV_VAR,H as STATIC_SITE_ZONE_SETTINGS,cr as STSClient,pn as SchedulerClient,Ee as Search,gS as SecretFindingScanner,rc as Secrets,$p as SecretsManager,zr as SecretsManagerClient,Pp as SecretsRotationManager,ne as Security,Yu as SecurityHubManager,lS as SecurityPostureStore,fS as SecurityScannerRunner,Ep as SecurityScanningManager,sm as SenderReputationManager,uA as ServerCronJobAdapter,$A as ServerDataAdapter,Mh as ServerPathVolumeDriver,Mp as ServiceMeshManager,$e as Sftp,gC as SignalSource,fm as SmsAdvanced,fn as SmsClient,Zs as SmsHandlers,An as SmsVoiceClient,Xh as SourceConnectionStore,Qh as SourceProviderError,IC as SpendCapError,$C as SpendGate,qC as SpendLoopLease,jC as SpendNotificationRouter,ZC as SpendRunner,RC as SpendService,zy as SpendStore,wd as Spinner,xA as SshFleetDriver,Yd as StackDependencyManager,qs as StacksIntegration,pf as StaticSiteManager,re as Storage,ff as StorageAdvancedManager,hn as SupportClient,mp as SyntheticsManager,kA as SystemFleetSshTransport,KS as SystemdDiscoveryAdapter,Rt as TRACE_HEADER,Ed as TaskList,HC as TelemetryStore,be as TemplateBuilder,El as TemplateCache,on as TextractClient,Qr as TranscribeClient,sn as TranslateClient,ub as TransportDisasterRecoveryDriver,lb as TransportPlatformMaintenanceDriver,GA as TransportRemoteBuildDriver,hS as TrivyImageScanner,ih as TsCloudApiError,oh as TsCloudClient,zC as URGENT_SPEND_EVENTS,Xy as USER_VISIBLE_ACTIONS,XA as UnavailableRegionalDriver,Or as UnifiedDnsValidator,Kg as UnsupportedSchemaVersionError,pl as ValidationError,gn as VoiceClient,xh as VolumeService,Eh as VolumeStore,Xs as Workflow,sp as XRayManager,ip as abTestManager,qh as activateImmutableRelease,Oi as addSiteToCloudConfig,MS as ageSeconds,Vy as aggregateDeltas,Ht as allocateSitePorts,Vs as analyzeStackDiff,lC as anomalyOptionsForSignal,vi as applyControlsToDdos,Ei as applyControlsToRateLimits,sr as applyMitigationFactor,zf as applyPlan,Er as applyZoneMigration,Dm as artifactKey,Gh as assertReleaseStrategy,DC as assertSpendAllows,Zf as attachConflicts,Jf as attachIsViable,qf as attachPreconditions,PS as attachProvenanceToRelease,AS as attachSbomToRelease,bS as attachVulnerabilitySummary,Ng as authEncryptionKeyFile,zg as authorizeOrganization,XS as authorizeRuntimePath,Ld as autocomplete,ju as awsConfigManager,hb as backupCredentialStatus,Hu as backupManager,Vl as batch,Am as batchProcessingManager,Fg as beginOidcAuthorization,ep as blueGreenManager,im as bounceComplaintHandler,Oy as budgetWindow,ji as buildAndPushServerlessImage,Wm as buildBunRuntimeLayerZip,gg as buildCertificatePackScript,pg as buildCertificateStateScript,hg as buildCertificateUnpackScript,lc as buildCloudFormationTemplate,yh as buildComposeLogsCommand,gh as buildComposeRuntimeCommand,hh as buildComposeScaleCommand,Ch as buildComposeShellCommand,cg as buildDrainSourceScript,If as buildDrainedSiteScanScript,qi as buildFunctionEnv,sg as buildHealthGateScript,si as buildHostCleanupScript,Vt as buildHostSitePortsScript,$s as buildMailEnv,mi as buildManagementDashboardArtifact,uo as buildMediaCdnPlan,wn as buildMtaStsPolicy,vn as buildMtaStsServer,Vm as buildNodeRuntimeLayerZip,xp as buildOptimizationManager,de as buildOriginGuardRule,eg as buildPauseWorkersScript,sf as buildPhpRuntimeLayerZip,ig as buildRestoreScript,jf as buildSetHostnameScript,oi as buildSiteDeployScript,ng as buildSnapshotScript,lg as buildSourceStateScript,Vn as buildSshArgs,le as buildStaticSiteCacheRules,ai as buildStaticSiteDeployScript,og as buildTargetStateScript,tg as buildWorkersStateScript,_S as bytes,rp as canaryManager,QA as canonicalJson,xS as capabilities,BA as capacity,Yl as categorizeChanges,wp as certificateManager,fg as certificatesMatch,bl as checkIAMPermissions,Km as checkInvocation,$l as checkServiceQuotas,jl as chunk,wo as cleanupDns01Challenge,os as clearSigningKeyCache,ly as cloneSourceBinding,ed as cloudConfigSchema,Qn as cloudDrivers,qu as cloudTrailManager,Be as collectAssets,df as collectPhpAppEntries,Rn as collectServerDnsDomains,Vh as completeComposeVolumeDeletion,Mg as completeOidcAuthorization,Wc as composePresets,fh as composeProjectName,km as composeServerlessAppTemplate,eS as compositeSpendTransport,bb as compressBackup,$f as config,SA as connectionGuidance,Fp as containerRegistryManager,qg as controlPlaneDatabaseFile,Bg as controlPlaneMigrations,hc as createApiBackendPreset,cS as createApiV1Handler,KA as createAsgBuildDriver,Sb as createBackupQueueHandlers,ef as createCliHandler,Yn as createCloudDriver,Ae as createCloudFrontPolicy,rl as createCredentialProvider,Ic as createDashboardSite,bc as createDataPipelinePreset,bA as createDataServiceQueueHandlers,wh as createDeploymentQueueHandlers,Y as createDnsProvider,jA as createEcsBuildDriver,wC as createEnforcementHandlers,hl as createError,fc as createExistingStaticFullStackPreset,LA as createFleetQueueHandlers,gc as createFullStackAppPreset,kr as createGoDaddyValidator,tf as createHandlers,Xm as createHttpHandler,Cc as createJamstackPreset,hA as createJobQueueHandlers,Tc as createLaravelPreset,Rc as createMLApiPreset,cb as createMaintenanceQueueHandlers,so as createMediaAccessToken,Sc as createMicroservicesPreset,ud as createMockAWS,uc as createNodeJsServerPreset,pc as createNodeJsServerlessPreset,fr as createObjectStorageClient,Nr as createPorkbunValidator,Hc as createPreset,Xa as createPresignedUrl,Qa as createPresignedUrlAsync,Qm as createQueueHandler,Ac as createRealtimeAppPreset,JA as createRegionQueueHandlers,RS as createReleaseProvenance,Yh as createReleaseQueueHandlers,zA as createRemoteBuildQueueHandlers,xr as createRoute53Validator,JS as createRuntimeAdapters,sl as createS3Client,UA as createServerBuildDriver,$c as createServerlessLaravelPreset,mc as createServerlessNodePreset,Sn as createSmsInfrastructure,iy as createSourceAdapter,dc as createStaticSitePreset,Pc as createTraditionalWebAppPreset,Lh as createVolumeQueueHandlers,yc as createWordPressPreset,Pm as createZip,Xd as crossRegionReferenceManager,to as dashboardActions,li as dashboardCredentialsFile,yA as dataServiceCapabilities,Rp as databaseUserManager,Sg as decodeBase32,Rb as decompressBackup,gb as decryptBackup,Rf as defaultConfig,rd as defaultLocalConfig,Ti as defaultRateLimitRules,zi as deleteStaticSite,gi as deployAllComputeSites,Zi as deployServerlessApp,Ui as deploySite,fi as deploySiteRelease,Vi as deployStaticSite,Gi as deployStaticSiteFull,Mi as deployStaticSiteWithExternalDns,_i as deployStaticSiteWithExternalDnsFull,As as deploymentCoexistenceError,Oc as deriveManagementDashboardPort,wi as describePosture,dA as desiredJobProviderState,sC as detectAnomalies,Cs as detectDeploymentTargets,Lr as detectDnsProvider,cC as detectLatestAnomaly,Sl as detectMisconfigurations,Za as detectServiceRegion,ch as diffCompose,ql as diffTemplates,cy as discoverGitRefs,Lg as discoverOidcProvider,BS as discoverRuntimeInventory,Cm as dlqMonitoringManager,Mr as dnsProviders,em as dnssecManager,zS as dockerWorkloads,tb as documentDigest,Gu as drManager,VS as ecsWorkloads,Gg as effectiveCapabilities,am as emailAnalyticsManager,dm as emailTemplateManager,Cg as encodeBase32,fb as encryptBackup,IS as ensureDefaultSecurityPolicies,ti as ensureFirewall,pi as ensureManagementDashboard,ri as ensureServer,ei as ensureSshKey,Nn as escapeSecLang,Zy as evaluateBudget,Qt as evaluateTelemetryAlertRules,sA as eventBridgeScheduleInput,Jm as eventToRequest,aC as ewma,sh as exportCompose,Dr as exportRoute53Zone,Vc as extendPreset,hm as fifoQueueManager,Ml as findChangedFiles,Fy as findMapping,by as findPriceEntry,$u as formatAccountStructure,Yf as formatAttachPlan,Rd as formatBytes,GC as formatCents,Ws as formatDiff,wf as formatDrainedSiteRefusal,Pd as formatDuration,Md as formatFlagSuggestions,Gd as formatHistory,Ud as formatHistoryStats,_f as formatInventory,$d as formatKeyValue,Td as formatList,Hf as formatPlan,bd as formatProgressBar,pu as formatRegion,mu as formatRegionList,mS as formatScanResults,Od as formatSuggestion,Sd as formatTable,jy as formatTimeToExhaustion,Ad as formatTree,Xc as fromEC2Metadata,Qc as fromECSMetadata,Jc as fromEnvironment,Yc as fromSharedCredentials,el as fromWebIdentity,Pt as functionFingerprint,fe as gatewayHostnames,_m as generateAppImageDockerfile,Bu as generateApprovalConfig,Tm as generateBootstrap,gd as generateCleanupWorkflow,hd as generateCostReportWorkflow,Pu as generateCrossAccountRoleCF,CS as generateCycloneDxSbom,Fu as generateDeploymentConfig,Ou as generateDeploymentPipeline,Iu as generateDeploymentWorkflow,Fi as generateExternalDnsStaticSiteTemplate,Io as generateHttpsServerCode,SS as generateImageSbom,$o as generateLetsEncryptUserData,Pe as generateLogicalId,Lu as generateManualPipeline,vu as generateMatrixWorkflow,Mu as generateMultiEnvConfig,Nu as generateMultiEnvPipeline,Du as generateMultiEnvWorkflow,wu as generatePRPreviewWorkflow,Vu as generateParallelConfig,rf as generatePhpFpmConfig,Mm as generatePhpLayerDockerfile,ku as generatePreviewPipeline,fd as generatePreviewWorkflow,Re as generateResourceName,_u as generateScheduledConfig,xu as generateScheduledPipeline,Eu as generateScheduledWorkflow,Bi as generateStaticSiteTemplate,_n as generateUbuntuAppCloudInit,ol as getAccountId,iu as getAllRegions,lu as getClosestRegion,_d as getCommandUsage,dh as getComposeTemplate,Pf as getConfig,kd as getContextualHelp,tl as getCredentials,Xl as getDeploymentStrategy,Ql as getDiffStats,Zl as getDiffSummary,gl as getErrorDetails,nd as getLocalConfig,ad as getLocalCredentials,od as getLocalEndpoint,sd as getLocalEnvVars,Il as getQuotaUsageSummary,Ru as getRecommendedStructure,nu as getRegion,fu as getRegionStats,au as getRegionsByCompliance,ou as getRegionsByLocation,su as getRegionsByPricingTier,Rl as getRequiredPermissions,as as getSigningKeyCacheSize,Cn as getSmsInfrastructureStatus,ws as getTimestamp,Si as globMatches,xn as globToRegex,Qd as globalResourceManager,qy as governingLimitCents,Ju as guardDutyManager,iS as handleSpendRequest,On as hasAutoWwwVariant,xc as hasManagementDashboardSite,Nt as hasProxyUpstream,kl as hashBuffer,xl as hashDirectory,Ol as hashFile,Ll as hashManifest,Nl as hashString,yf as healthCheckManager,me as hostAcceptsIpv6,ce as hostCondition,Ag as hotp,ky as hourBucket,xy as hourBucketsBetween,Np as imageScanningManager,Ki as infraEnvFromOutputs,It as inspectInvocation,Gm as installRecursionFetch,Hi as invalidateCache,Hm as invocationContext,Nd as isLikelyTypo,id as isLocalDevelopment,Mc as isManagementDashboardSiteName,ss as isNodeCryptoAvailable,rC as isOperationAllowed,Jt as isQuietHours,kn as isSafePattern,ys as isStatePath,tr as isValidCidr,cu as isValidRegion,Dy as isValidTimeZone,cs as isWebCryptoAvailable,oA as jobProviderCapability,dr as keyMatchesFilters,Gp as lambdaConcurrencyManager,Jp as lambdaDLQManager,jp as lambdaDestinationsManager,Vp as lambdaLayersManager,qp as lambdaVPCManager,Hp as lambdaVersionsManager,WS as lambdaWorkloads,of as laravelServerlessEnvDefaults,lh as listComposeTemplates,py as listSourceReferences,Tf as loadCloudConfig,kC as loadTelemetryPolicy,pp as logsManager,yC as lookbackHoursForSignal,Rs as mailEnabled,Ts as mailFirewallPorts,ab as maintenanceWindowOpen,es as makeAWSRequest,rs as makeAWSRequestAsync,ts as makeAWSRequestOnce,Fc as managementDashboardSiteName,eb as manifestDigest,Pg as matchTotpCounter,lo as mediaObjectHeaders,nC as median,iC as medianAbsoluteDeviation,Jy as mergeDecisions,zc as mergeInfrastructure,$y as mergePriceBooks,By as meterTelemetry,dp as metricsManager,ur as migrateObjectStorage,hp as migrationManager,yu as multiAccountManager,Kd as multiRegionManager,Eo as needsRenewal,Sf as networkSecurityManager,nA as nextScheduleRuns,Tn as normalizePublicIpv6,LS as normalizeRuntimeStatus,rA as normalizeScheduleExpression,oy as normalizeSourceEvent,qn as normalizeSshPublicKey,OC as normalizeTelemetryPolicy,Bt as occupiedHostPorts,sS as openApiDocument,hC as optionsForSignal,Cu as organizationManager,uf as packagePhpApp,wm as packageServerlessApp,_e as pagesAssetHash,Ct as pagesDnsRecord,Bl as parallel,Wl as parallelMap,Hl as parallelWithRetry,mg as parseCertificateState,$t as parseChain,ah as parseCompose,ph as parseComposeCatalog,HS as parseDockerInspect,Ob as parseDotenv,Df as parseDrainedSites,Wt as parseHostSiteFragments,is as parseJSONResponse,dg as parseSourceDrained,US as parseSystemdRecords,ag as parseTargetReady,_t as parseUpstreamPort,rg as parseWorkersPaused,ns as parseXMLResponse,_C as pathTemplate,Vf as pendingSteps,Uy as percentOfLimit,Ap as performanceManager,Fm as phpLayerBuildStage,Lm as phpLayerPackages,nf as phpRuntimeLayerAssets,mh as planComposeTemplateUpgrade,Qy as planEnforcement,Wf as planIsDestructive,ar as planMitigation,Uf as planServerRename,yg as planSiteMove,wr as planZoneMigration,Rr as policyTag,md as previewManager,Cd as previewNotifications,iA as previewSchedule,Ny as previousBudgetWindow,Ry as priceUsage,Py as priceUsageLines,Lf as probeHostRoutes,pe as probeOriginTls,Kl as processInChunks,ay as processSourceWebhook,vS as productionChangeReview,ap as progressiveDeploymentManager,Gy as projectSpend,wt as propagationHeaders,pr as providerEndpoint,rb as publicKeyFingerprint,Pr as qualifyName,Rm as queueManagementManager,Fl as quickHash,Pi as rateLimitHeaders,bi as rateLimitKey,Ff as reconcile,In as reconcileAddressRecords,pt as reconcileCloudflareCdn,$r as reconcileDeclaredRecords,cA as reconcileJobObservation,my as reconcileSourceWebhook,ES as recordDashboardHostPosture,DS as recordPreDeploySecretScan,wS as recordSkippedSecretScan,Et as recursionBlockedResponse,FS as redactRuntimeConfig,FC as redactTelemetryText,MC as redactTelemetryValue,Ji as redeployServerlessApp,eu as regionPairManager,zh as releaseStrategyCapabilities,Kh as releaseTrafficPlan,hi as reloadRpxGateway,lr as remapKey,Ni as removeSiteFromCloudConfig,fy as removeSourceWebhook,Pn as removeStaleServerAddressRecords,uh as renderComposeTemplate,or as renderDdosInstallScript,ir as renderNftablesRuleset,aA as renderServerCron,nr as renderSysctlFile,Ln as renderWafConfig,Fn as renderWafInstallScript,yi as renewRpxCertificates,Cp as replicaManager,rS as requestHash,Jl as requiresReplacement,jm as resetRecursionRuntime,Zm as resolveApp,bs as resolveAppDatabase,Kf as resolveAttachTarget,kg as resolveAuthEncryptionKey,Is as resolveCloudProvider,ft as resolveCloudflareCdnPlan,nl as resolveCredentials,ro as resolveDashboardAction,di as resolveDashboardAuth,Nc as resolveDashboardDomain,kc as resolveDashboardDomains,Tr as resolveDeclaredRecords,Ls as resolveDeployBucketName,Ss as resolveDeploymentMode,ii as resolveExecStart,Kn as resolveHetznerApiToken,Ps as resolveMailService,Bc as resolveManagementDashboardSite,_c as resolveManagementDashboardSites,mr as resolveObjectStorage,Bf as resolvePlan,vs as resolveProjectStackName,Ot as resolveProxyUpstreams,Nm as resolveQueueNames,Dh as resolveQueuedDeploymentCommand,Om as resolveQueues,zm as resolveRecursionConfig,il as resolveRegion,YS as resolveRuntimeInventory,Fs as resolveServerlessAppStackName,Ms as resolveServerlessArtifactBucketName,_s as resolveServerlessAssetBucketName,vm as resolveServerlessRuntime,ks as resolveSiteBucketName,kt as resolveSiteDeployTarget,xt as resolveSiteKind,Ns as resolveSiteResourceName,Os as resolveSiteStackName,hs as resolveStatePath,xs as resolveStorageBucketName,ui as resolveUiSource,Fe as resolveZoneApex,bf as resourceManagementManager,Ym as responseToResult,oC as robustZScore,Wg as roleCapabilities,Zh as rollbackImmutableRelease,Yi as rollbackServerlessApp,Ty as roundCents,rm as route53ResolverManager,Xp as route53RoutingManager,uC as routeMatches,kf as routesFromFragments,Ai as ruleMatches,$m as runBuildHooks,eC as runEnforcement,lf as runPhpBuildHooks,Qi as runRemoteCommand,NS as runtimeId,eo as sanitizeCloudConfig,Yg as sanitizeControlPlaneValue,Es as sanitizeName,xg as sanitizeOidcReturnPath,xC as saveTelemetryPolicy,pS as scanForSecrets,Hg as scopeContains,Wy as scopeKey,zn as scpUpload,xd as searchCommands,Qg as searchControlPlane,Ip as secretsManager,Tp as secretsRotationManager,OS as secureContainerRelease,Xu as securityHubManager,vp as securityScanningManager,$S as securityScope,Og as sendAuthenticationEmail,cm as senderReputationManager,zl as sequence,Nb as serializeDotenv,ni as serverPublicIpv4,_p as serviceMeshManager,Li as setAttachToInCloudConfig,Xi as setMaintenance,xi as setSitePropertyInCloudConfig,ms as setStateDir,Do as setupDns01Challenge,yn as setupSmsInfrastructure,Im as sha256,Um as sharedRecursionGuard,Bm as sharedRuntimeLoop,Ft as shipsARelease,ao as signCloudFrontCookies,oo as signCloudFrontUrl,Ja as signRequest,Ya as signRequestAsync,fC as signalDefinition,vt as siteInstallBase,Xf as siteMoveArchivePath,ug as siteMoveCertArchivePath,Qf as siteUnitGlob,UC as spendNotificationText,oS as spendOpenApiPaths,Wn as sshExec,Hn as sshExecOrThrow,tu as stackDependencyManager,no as startLocalDashboardServer,YC as startSpendLoop,fs as stateDir,gs as statePath,mf as staticSiteManager,gf as storageAdvancedManager,bC as streamFocusJsonl,tC as strongestActiveAction,vd as suggestCommand,Fd as suggestFlags,Pl as suggestIAMPolicy,Dl as suggestQuotaIncrease,uu as suggestRegionPairs,du as suggestRegions,uy as syncSourceRepositories,Bh as synchronizeComposeVolumes,_b as synchronizeConfiguredConfiguration,fA as synchronizeConfiguredJobs,fp as syntheticsManager,rr as sysctlHardening,jS as systemdWorkloads,WC as telemetryBucketLabel,BC as telemetryCursor,LC as telemetryEstimatedMonthlyCost,VC as telemetryPercentile,NC as telemetryPolicyKey,vl as templateCache,xf as tenantsOf,dy as testSourceConnection,Ay as tieredMicroCents,ue as toCloudflareZoneSettings,AC as toFocusJsonl,SC as toFocusRecords,Nf as toInventoryServer,bg as totp,Tg as totpUri,Mf as unaccountedSites,kS as unsupportedCapabilities,vh as unsupportedVolumeCapabilities,ib as updateCompatibility,ki as updateSiteInCloudConfig,Wi as uploadStaticFiles,My as usageDeltaKey,vy as utcInstantOfLocal,Tu as validateAccountStructure,td as validateAgainstSchema,kh as validateAttachment,pb as validateBackupDestination,Bd as validateCommand,Cl as validateConfiguration,Al as validateCredentials,Lt as validateDeploymentConfig,Nh as validateMountPath,et as validateResourceLimits,Gf as validateServerName,qe as validateTemplate,Qe as validateTemplateSize,Dn as verifyAddressRecord,TS as verifyArtifactSignature,co as verifyMediaAccessToken,Rg as verifyTotp,nb as verifyUpdateSignature,vr as verifyZoneParity,Oh as volumeCapabilities,Mn as wafEventTelemetry,Un as waitForCloudInit,Gn as waitForSsh,sy as webhookEndpoint,qc as withCDN,Kc as withCache,jc as withDatabase,qm as withInvocation,Gc as withMonitoring,Zc as withQueue,Uc as withSecurity,Gl as withTimeout,Zn as wrapCloudInitUserData,cp as xrayManager,_A as zeroCapacity,PC as zeroFill,Ey as zoneOffsetMs,wy as zonedParts};
|
|
595
|
+
`}async function Wo(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 Ho(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 zo(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]),P=Buffer.alloc(32),g=Buffer.alloc(32);u.copy(P,32-u.length),C.copy(g,32-C.length);let m=Buffer.concat([P,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 ce(e){if(e.length===1)return`http.host eq ${W(e[0])}`;return`http.host in ${Le(e)}`}function le(e,t={}){if(t.enabled===!1||e.length===0)return[];let r=ce(e),n=[],d=(t.bypassPaths??[]).map((P)=>`starts_with(http.request.uri.path, ${W(P)})`),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 de(e,t,r){if(e.length===0||!t||!r)return[];return[{action:"rewrite",description:"origin guard header",expression:`(${ce(e)})`,enabled:!0,action_parameters:{headers:{[t]:{operation:"set",value:r}}}}]}var N=(e)=>e===void 0?void 0:e?"on":"off";function ue(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 pe(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:P=!1}=e,g={records:[],settingsChanged:[],cacheRules:0,originGuard:!1,purged:!1,deferredProxy:[],warnings:[]};if(n.length===0)return g;let m=[],c=s&&!P?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 pe({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&&me(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=ue(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=le(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=de(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()))]:fe(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 _e{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 X(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 X("POST","/pages/assets/check-missing",`Bearer ${e}`,{hashes:t});return new Set(r)}async upsertHashes(e,t){await X("POST","/pages/assets/upsert-hashes",`Bearer ${e}`,{hashes:t})}async uploadBatch(e,t){let r=t.map((n)=>({key:n.hash,value:n.base64,metadata:{contentType:St(n.extension)},base64:!0}));await X("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 await this.upsertHashes(r,t.map((l)=>l.hash)),{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 Me(e,t){let{blake3:r}=await import("./chunk-dndxwssj.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 P=Buffer.from(C).toString("base64"),g=p.name.lastIndexOf("."),m=g>0?p.name.slice(g+1):"";d.push({path:b,hash:await Me(P,m),base64:P,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 X(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{Cp as ABTestManager,Mr as ACMClient,Br as ACMDnsValidator,ke as ACME_DIRECTORIES,F as AI,yh as API_IDEMPOTENCY_TTL_MS,gh as API_TOKEN_DEFAULT_TTL_MS,hh as API_TOKEN_MAX_TTL_MS,bS as API_VERSION,th as AUTHORIZATION_CAPABILITIES,Hg as AUTH_ACTION_TOKEN_TTL_MS,zg as AUTH_MFA_CHALLENGE_TTL_MS,Gg as AUTH_OIDC_TRANSACTION_TTL_MS,Wg as AUTH_SESSION_ABSOLUTE_TTL_MS,Vg as AUTH_SESSION_IDLE_TTL_MS,wl as AWSAPIError,zt as AWSClient,Ve as AWSCloudFormationClient,We as AWSCloudFrontClient,ap as AWSConfigManager,Rc as AWS_PSEUDO_PARAMETERS,yu as AWS_REGIONS,st as AcmeClient,Zt as AlertEvaluator,qt as AlertStore,DC as AnomalyConfigStore,De as ApiGateway,hS as ApiServiceError,mn as ApplicationAutoScalingClient,bc as Arn,hc as AssetHasher,fc as Auth,Ug as AuthenticationStore,CS as AutomationApiService,Ch as AutomationIdentityStore,MA as AwsAuroraDataAdapter,zA as AwsAuroraTransport,Lb as AwsDatabaseBackupSource,Bn as AwsDriver,BA as AwsElastiCacheDataAdapter,GA as AwsElastiCacheTransport,NS as AwsIamCapabilityScanner,Gb as AwsInfrastructureBackupSource,_A as AwsRdsDataAdapter,HA as AwsRdsTransport,pb as AwsRegionalDriver,Zb as AwsSecretsManagerConfigurationBackend,mS as AwsSpendTransport,Jb as AwsSsmConfigurationBackend,kb as BackupCoordinator,rp as BackupManager,wb as BackupStore,xm as BatchProcessingManager,tn as BedrockClient,en as BedrockRuntimeClient,yy as BitbucketSourceAdapter,fp as BlueGreenManager,Cm as BounceComplaintHandler,qp as BuildOptimizationManager,UA as BunDockerRuntime,Wb as BunDockerVolumeRuntime,Mb as BunFilesystemArchiveRuntime,ic as CDN,bt as CHAIN_HEADER,Ar as CLOUDFLARE_MANAGED_RULE_PREFIX,Fu as COMMON_CROSS_ACCOUNT_ROLES,Qg as CONTROL_PLANE_SCHEMA_VERSION,oe as Cache,hp as CanaryManager,Hp as CertificateManager,Qh as CloudBlockVolumeDriver,ui as CloudDriverFactory,Pl as CloudError,Pc as CloudFormationBuilder,Ve as CloudFormationClient,We as CloudFrontClient,cp as CloudTrailManager,Kr as CloudWatchLogsClient,_e as CloudflarePagesProvider,br as CloudflareProvider,iu as CommandHistory,Sc as Communication,ny as ComposeApplicationService,ry as ComposeApplicationStore,rn as ComprehendClient,E as Compute,fS as ComputeSpendTransport,Tl as ConfigurationError,Xb as ConfigurationService,Ub as ConfigurationStore,qr as ConnectClient,WA as ContainerDataAdapter,Jp as ContainerRegistryManager,zb as ControlPlaneBackupSource,$b as ControlPlaneCleanupDriver,mh as ControlPlaneStore,Qy as CounterTracker,$l as CredentialError,lu as CrossRegionReferenceManager,zc as DASHBOARD_ENTRY,Gc as DASHBOARD_PORT_BASE,Uc as DASHBOARD_PORT_SPAN,Hc as DASHBOARD_STATE_DIR,Vi as DEFAULT_ATTACK_MODE_HOURS,er as DEFAULT_DDOS_THRESHOLDS,Jy as DEFAULT_METER_MAPPINGS,Wy as DEFAULT_PRICE_BOOK,Tt as DEFAULT_RECURSION_LIMITS,Bl as DEFAULT_SERVICE_LIMITS,$s as DEFAULT_STATE_DIR,xe as DEFAULT_STATIC_ASSET_EXTENSIONS,UC as DEFAULT_TELEMETRY_POLICY,nC as DEFAULT_THRESHOLDS,Wh as DEPLOYMENT_QUEUE_KINDS,At as DEPTH_HEADER,wC as DETECTABLE_SIGNALS,fA as DIAGNOSTIC_PRESETS,Nm as DLQMonitoringManager,oc as DNS,fm as DNSSECManager,LA as DataServiceLifecycle,kA as DataServiceStore,K as Database,Fp as DatabaseUserManager,Nl as DebugLogger,ec as DependencyGraph,gc as Deployment,Il as DeploymentError,ip as DisasterRecoveryManager,Fr as DnsProviderFactory,jA as DockerDataTransport,oA as DockerDiscoveryAdapter,Yh as DockerNamedVolumeDriver,Hb as DockerVolumeBackupSource,_h as DurableOperationQueue,Mh as DurableQueueWorker,Yr as DynamoDBClient,gr as EC2Client,Vr as ECRClient,Wr as ECSClient,bn as EFSClient,Zr as ELBv2Client,Ny as ENFORCEMENT_ACTIONS,pC as ENFORCEMENT_DESCRIPTIONS,ky as ENFORCEMENT_SEVERITY,Uf as ENVIRONMENT_LABEL,lA as EcsRuntimeAdapter,Fi as EdgeRateLimiter,un as ElastiCacheClient,L as Email,Im as EmailAdvanced,Am as EmailAnalyticsManager,Kt as EmailClient,Dm as EmailHandlers,Tm as EmailTemplateManager,KA as EncryptedDataSecretStore,El as ErrorCodes,dn as EventBridgeClient,DA as EventBridgeJobAdapter,Yb as ExternalConfigurationBackend,vm as FIFOQueueManager,kC as FOCUS_VERSION,zl as FileCache,j as FileSystem,Bb as FilesystemBackupSource,XA as FleetService,YA as FleetStore,Ac as Fn,Cy as GiteaSourceAdapter,gy as GithubSourceAdapter,hy as GitlabSourceAdapter,du as GlobalResourceManager,Sr as GoDaddyProvider,dp as GuardDutyManager,_t as HOST_SITES_DIR,Ql as HashCache,Of as HealthCheckManager,Xt as HealthCheckRunner,jn as HetznerClient,Qn as HetznerDriver,Gt as IAMClient,$n as IPV6_EXCLUDED_HOST_LABELS,jp as ImageScanningManager,Ke as InfrastructureGenerator,sh as InvalidOperationTransitionError,cc as JobLoader,wA as JobProviderReconciler,vA as JobService,TA as JobStore,ln as KendraClient,bf as LARAVEL_SERVERLESS_BUILD_STEPS,jr as LambdaClient,im as LambdaConcurrencyManager,dm as LambdaDLQManager,am as LambdaDestinationsManager,em as LambdaLayersManager,dA as LambdaRuntimeAdapter,cm as LambdaVPCManager,rm as LambdaVersionsManager,qb as LocalEncryptedConfigurationBackend,Vb as LogicalDatabaseBackupSource,Ip as LogsManager,Gm as MANAGED_NODE_VERSIONS,Ri as MANAGEMENT_DASHBOARD_SITE,Jc as MANAGEMENT_DASHBOARD_SITE_PREFIX,Bi as MAX_CONTROL_HOURS,uh as MAX_CONTROL_PLANE_ERROR_BYTES,dh as MAX_CONTROL_PLANE_JSON_BYTES,Oy as METERS,vy as METER_KEYS,xy as MICRO_CENTS,cC as MIN_PROJECTION_CONFIDENCE,En as MTA_STS_PORT,Rb as MaintenanceService,Ab as MaintenanceStore,pc as Messaging,Tp as MetricsManager,vp as MigrationManager,Pd as MockCloudFormation,$d as MockDynamoDB,Td as MockS3,we as Monitoring,vu as MultiAccountManager,su as MultiRegionManager,Hd as MultiStepProgress,Te as Network,kf as NetworkSecurityManager,Yt as NotificationRouter,Xr as OpenSearchClient,ah as OptimisticConcurrencyError,Ou as OrganizationManager,ht as PAGES_MAX_FILE_BYTES,Pf as PHP_DEFAULT_EXCLUDES,Zm as PHP_LAYER_EXTENSIONS,Gf as PROJECT_LABEL,yr as PROXIABLE_RECORD_TYPES,Cc as ParameterStore,xp as PerformanceManager,Ie as Permissions,cn as PersonalizeClient,sc as Phone,wm as PhoneAdvanced,ac as PhoneHandlers,rb as PlacementService,tb as PlacementStore,an as PollyClient,Cr as PorkbunProvider,IS as PreDeployScanner,Dd as PreviewEnvironmentManager,Vh as PreviewEnvironmentService,Bh as PreviewEnvironmentStore,Nd as PreviewNotificationService,Wd as ProgressBar,Ap as ProgressiveDeploymentManager,Wi as ProtectionControlStore,Hs as Pseudo,ie as Queue,xh as QueueCancellationError,Fm as QueueManagementManager,Ps as QueuePresets,Lh as QueueTimeoutError,Ni as RATE_LIMIT_KEY_SEPARATOR,Jr as RDSClient,xu as RECOMMENDED_ACCOUNT_STRUCTURES,Lu as RECOMMENDED_SCPS,uy as RELEASE_QUEUE_KINDS,tu as REPL,nu as REPLCommandBuilder,ru as REPLContext,jf as ROLE_LABEL,ad as RateLimiter,Ts as RealtimePresets,GC as RecordingSpendTransport,Dt as RecursionGuard,q as Redirects,uu as RegionPairManager,db as RegionService,lb as RegionStore,nc as Registry,nn as RekognitionClient,sy as ReleaseService,ay as ReleaseStore,nb as RemoteBuildService,Np as ReplicaManager,Lf as ResourceManagementManager,Fh as RetryableOperationError,J as Route53Client,hr as Route53DomainsClient,Ir as Route53Provider,hm as Route53ResolverManager,pm as Route53RoutingManager,gA as RuntimeOperationService,hA as RuntimeStreamRegistry,Nb as S3BackupDestinationAdapter,Ut as S3Client,bl as S3Error,$S as SECRET_PATTERNS,$C as SENSITIVITY_THRESHOLDS,jt as SESClient,uc as SMS,Gr as SNSClient,uS as SPEND_CYCLE_SECONDS,BC as SPEND_GATE_SETTING,cS as SPEND_LEASE_SETTING,Ur as SQSClient,ti as SSH_BOOTSTRAP_VERSION,ii as SSH_PREFLIGHT_SCRIPT,Hr as SSMClient,Is as STATE_DIR_ENV_VAR,H as STATIC_SITE_ZONE_SETTINGS,cr as STSClient,pn as SchedulerClient,Ee as Search,vS as SecretFindingScanner,yc as Secrets,Vp as SecretsManager,zr as SecretsManagerClient,Mp as SecretsRotationManager,ne as Security,pp as SecurityHubManager,TS as SecurityPostureStore,ES as SecurityScannerRunner,Gp as SecurityScanningManager,Rm as SenderReputationManager,IA as ServerCronJobAdapter,VA as ServerDataAdapter,Xh as ServerPathVolumeDriver,Xp as ServiceMeshManager,$e as Sftp,vC as SignalSource,Em as SmsAdvanced,fn as SmsClient,dc as SmsHandlers,An as SmsVoiceClient,my as SourceConnectionStore,fy as SourceProviderError,WC as SpendCapError,VC as SpendGate,lS as SpendLoopLease,sS as SpendNotificationRouter,dS as SpendRunner,_C as SpendService,iC as SpendStore,zd as Spinner,li as SshDriver,ZA as SshFleetDriver,pu as StackDependencyManager,lc as StacksIntegration,Df as StaticSiteManager,re as Storage,Ef as StorageAdvancedManager,hn as SupportClient,wp as SyntheticsManager,qA as SystemFleetSshTransport,ei as SystemSshTransport,cA as SystemdDiscoveryAdapter,Rt as TRACE_HEADER,Gd as TaskList,nS as TelemetryStore,be as TemplateBuilder,Gl as TemplateCache,on as TextractClient,Qr as TranscribeClient,sn as TranslateClient,Ib as TransportDisasterRecoveryDriver,Tb as TransportPlatformMaintenanceDriver,ob as TransportRemoteBuildDriver,OS as TrivyImageScanner,Sh as TsCloudApiError,Ah as TsCloudClient,iS as URGENT_SPEND_EVENTS,mC as USER_VISIBLE_ACTIONS,mb as UnavailableRegionalDriver,Or as UnifiedDnsValidator,ch as UnsupportedSchemaVersionError,Dl as ValidationError,gn as VoiceClient,Zh as VolumeService,Gh as VolumeStore,mc as Workflow,Rp as XRayManager,Sp as abTestManager,ly as activateImmutableRelease,Ui as addSiteToCloudConfig,XS as ageSeconds,tC as aggregateDeltas,Ht as allocateSitePorts,tc as analyzeStackDiff,TC as anomalyOptionsForSignal,Gi as applyControlsToDdos,zi as applyControlsToRateLimits,sr as applyMitigationFactor,ig as applyPlan,Er as applyZoneMigration,Hm as artifactKey,oy as assertReleaseStrategy,HC as assertSpendAllows,dg as attachConflicts,ug as attachIsViable,lg as attachPreconditions,MS as attachProvenanceToRelease,LS as attachSbomToRelease,FS as attachVulnerabilitySummary,Kg as authEncryptionKeyFile,ih as authorizeOrganization,mA as authorizeRuntimePath,Jd as autocomplete,sp as awsConfigManager,Ob as backupCredentialStatus,np as backupManager,td as batch,Lm as batchProcessingManager,Yg as beginOidcAuthorization,gp as blueGreenManager,Sm as bounceComplaintHandler,jy as budgetWindow,ao as buildAndPushServerlessImage,rf as buildBunRuntimeLayerZip,vg as buildCertificatePackScript,Dg as buildCertificateStateScript,Og as buildCertificateUnpackScript,Tc as buildCloudFormationTemplate,mi as buildCloudInitFirstBoot,Nh as buildComposeLogsCommand,vh as buildComposeRuntimeCommand,Oh as buildComposeScaleCommand,kh as buildComposeShellCommand,Pg as buildDrainSourceScript,Wf as buildDrainedSiteScanScript,co as buildFunctionEnv,Rg as buildHealthGateScript,bi as buildHostCleanupScript,Vt as buildHostSitePortsScript,Vs as buildMailEnv,Di as buildManagementDashboardArtifact,$o as buildMediaCdnPlan,wn as buildMtaStsPolicy,vn as buildMtaStsServer,tf as buildNodeRuntimeLayerZip,Zp as buildOptimizationManager,de as buildOriginGuardRule,gg as buildPauseWorkersScript,Rf as buildPhpRuntimeLayerZip,Sg as buildRestoreScript,sg as buildSetHostnameScript,Si as buildSiteDeployScript,Cg as buildSnapshotScript,Tg as buildSourceStateScript,Vn as buildSshArgs,ri as buildSshBootstrapScript,le as buildStaticSiteCacheRules,Ai as buildStaticSiteDeployScript,Ag as buildTargetStateScript,hg as buildWorkersStateScript,QS as bytes,yp as canaryManager,fb as canonicalJson,ZS as capabilities,eb as capacity,pd as categorizeChanges,zp as certificateManager,Eg as certificatesMatch,Fl as checkIAMPermissions,lf as checkInvocation,Vl as checkServiceQuotas,sd as chunk,Ho as cleanupDns01Challenge,Ss as clearSigningKeyCache,Ty as cloneSourceBinding,gd as cloudConfigSchema,pi as cloudDrivers,lp as cloudTrailManager,Be as collectAssets,$f as collectPhpAppEntries,Rn as collectServerDnsDomains,ty as completeComposeVolumeDeletion,Xg as completeOidcAuthorization,rl as composePresets,Eh as composeProjectName,qm as composeServerlessAppTemplate,gS as compositeSpendTransport,Fb as compressBackup,Vf as config,xA as connectionGuidance,Yp as containerRegistryManager,lh as controlPlaneDatabaseFile,eh as controlPlaneMigrations,Oc as createApiBackendPreset,PS as createApiV1Handler,cb as createAsgBuildDriver,xb as createBackupQueueHandlers,hf as createCliHandler,di as createCloudDriver,Ae as createCloudFrontPolicy,yl as createCredentialProvider,Wc as createDashboardSite,Fc as createDataPipelinePreset,FA as createDataServiceQueueHandlers,zh as createDeploymentQueueHandlers,Y as createDnsProvider,sb as createEcsBuildDriver,zC as createEnforcementHandlers,Ol as createError,Ec as createExistingStaticFullStackPreset,JA as createFleetQueueHandlers,vc as createFullStackAppPreset,kr as createGoDaddyValidator,yf as createHandlers,ff as createHttpHandler,kc as createJamstackPreset,OA as createJobQueueHandlers,Bc as createLaravelPreset,_c as createMLApiPreset,Pb as createMaintenanceQueueHandlers,Ro as createMediaAccessToken,xc as createMicroservicesPreset,Id as createMockAWS,Ic as createNodeJsServerPreset,Dc as createNodeJsServerlessPreset,fr as createObjectStorageClient,Nr as createPorkbunValidator,nl as createPreset,ps as createPresignedUrl,ms as createPresignedUrlAsync,gf as createQueueHandler,Lc as createRealtimeAppPreset,ub as createRegionQueueHandlers,_S as createReleaseProvenance,py as createReleaseQueueHandlers,ib as createRemoteBuildQueueHandlers,xr as createRoute53Validator,uA as createRuntimeAdapters,Rl as createS3Client,ab as createServerBuildDriver,Vc as createServerlessLaravelPreset,wc as createServerlessNodePreset,Sn as createSmsInfrastructure,Sy as createSourceAdapter,$c as createStaticSitePreset,Mc as createTraditionalWebAppPreset,Jh as createVolumeQueueHandlers,Nc as createWordPressPreset,Mm as createZip,mu as crossRegionReferenceManager,ho as dashboardActions,Pi as dashboardCredentialsFile,NA as dataServiceCapabilities,_p as databaseUserManager,xg as decodeBase32,_b as decompressBackup,vb as decryptBackup,_f as defaultConfig,yd as defaultLocalConfig,Mi as defaultRateLimitRules,no as deleteStaticSite,Ei as deployAllComputeSites,lo as deployServerlessApp,oo as deploySite,wi as deploySiteRelease,eo as deployStaticSite,io as deployStaticSiteFull,Yi as deployStaticSiteWithExternalDns,Xi as deployStaticSiteWithExternalDnsFull,Ls as deploymentCoexistenceError,jc as deriveManagementDashboardPort,Hi as describePosture,$A as desiredJobProviderState,RC as detectAnomalies,ks as detectDeploymentTargets,Lr as detectDnsProvider,PC as detectLatestAnomaly,xl as detectMisconfigurations,ls as detectServiceRegion,Ph as diffCompose,ld as diffTemplates,Py as discoverGitRefs,Jg as discoverOidcProvider,eA as discoverRuntimeInventory,km as dlqMonitoringManager,_r as dnsProviders,gm as dnssecManager,iA as dockerWorkloads,hb as documentDigest,op as drManager,Jn as driverStatePath,tA as ecsWorkloads,oh as effectiveCapabilities,bm as emailAnalyticsManager,$m as emailTemplateManager,kg as encodeBase32,Eb as encryptBackup,WS as ensureDefaultSecurityPolicies,gi as ensureFirewall,Ii as ensureManagementDashboard,hi as ensureServer,fi as ensureSshKey,Nn as escapeSecLang,dC as evaluateBudget,ai as evaluatePreflight,Qt as evaluateTelemetryAlertRules,RA as eventBridgeScheduleInput,pf as eventToRequest,bC as ewma,Rh as exportCompose,Dr as exportRoute53Zone,tl as extendPreset,Om as fifoQueueManager,Xl as findChangedFiles,Yy as findMapping,Fy as findPriceEntry,Vu as formatAccountStructure,pg as formatAttachPlan,_d as formatBytes,oS as formatCents,rc as formatDiff,zf as formatDrainedSiteRefusal,Md as formatDuration,Xd as formatFlagSuggestions,ou as formatHistory,au as formatHistoryStats,Qf as formatInventory,Vd as formatKeyValue,Bd as formatList,ng as formatPlan,ci as formatPreflightFindings,Fd as formatProgressBar,Du as formatRegion,wu as formatRegionList,wS as formatScanResults,jd as formatSuggestion,xd as formatTable,sC as formatTimeToExhaustion,Ld as formatTree,ml as fromEC2Metadata,fl as fromECSMetadata,ul as fromEnvironment,pl as fromSharedCredentials,gl as fromWebIdentity,Pt as functionFingerprint,fe as gatewayHostnames,Qm as generateAppImageDockerfile,ep as generateApprovalConfig,Bm as generateBootstrap,vd as generateCleanupWorkflow,Od as generateCostReportWorkflow,Mu as generateCrossAccountRoleCF,kS as generateCycloneDxSbom,Yu as generateDeploymentConfig,ju as generateDeploymentPipeline,Wu as generateDeploymentWorkflow,Ji as generateExternalDnsStaticSiteTemplate,Vo as generateHttpsServerCode,xS as generateImageSbom,Bo as generateLetsEncryptUserData,Pe as generateLogicalId,Ju as generateManualPipeline,Uu as generateMatrixWorkflow,Xu as generateMultiEnvConfig,Ku as generateMultiEnvPipeline,Hu as generateMultiEnvWorkflow,zu as generatePRPreviewWorkflow,tp as generateParallelConfig,Cf as generatePhpFpmConfig,Xm as generatePhpLayerDockerfile,qu as generatePreviewPipeline,Ed as generatePreviewWorkflow,Re as generateResourceName,Qu as generateScheduledConfig,Zu as generateScheduledPipeline,Gu as generateScheduledWorkflow,Qi as generateStaticSiteTemplate,Mn as generateUbuntuAppCloudInit,Al as getAccountId,Su as getAllRegions,Tu as getClosestRegion,Qd as getCommandUsage,$h as getComposeTemplate,Mf as getConfig,qd as getContextualHelp,hl as getCredentials,md as getDeploymentStrategy,fd as getDiffStats,dd as getDiffSummary,vl as getErrorDetails,Cd as getLocalConfig,bd as getLocalCredentials,Ad as getLocalEndpoint,Rd as getLocalEnvVars,Wl as getQuotaUsageSummary,_u as getRecommendedStructure,Cu as getRegion,Eu as getRegionStats,bu as getRegionsByCompliance,Au as getRegionsByLocation,Ru as getRegionsByPricingTier,_l as getRequiredPermissions,As as getSigningKeyCacheSize,Cn as getSmsInfrastructureStatus,zs as getTimestamp,ki as globMatches,xn as globToRegex,fu as globalResourceManager,lC as governingLimitCents,up as guardDutyManager,SS as handleSpendRequest,On as hasAutoWwwVariant,Zc as hasManagementDashboardSite,Nt as hasProxyUpstream,ql as hashBuffer,Zl as hashDirectory,jl as hashFile,Jl as hashManifest,Kl as hashString,Nf as healthCheckManager,me as hostAcceptsIpv6,ce as hostCondition,Lg as hotp,qy as hourBucket,Zy as hourBucketsBetween,Kp as imageScanningManager,so as infraEnvFromOutputs,It as inspectInvocation,af as installRecursionFetch,ro as invalidateCache,nf as invocationContext,Kd as isLikelyTypo,Sd as isLocalDevelopment,Xc as isManagementDashboardSiteName,bs as isNodeCryptoAvailable,yC as isOperationAllowed,Jt as isQuietHours,kn as isSafePattern,ws as isStateDirConfigured,Ns as isStatePath,tr as isValidCidr,Pu as isValidRegion,Hy as isValidTimeZone,Rs as isWebCryptoAvailable,AA as jobProviderCapability,dr as keyMatchesFilters,om as lambdaConcurrencyManager,um as lambdaDLQManager,sm as lambdaDestinationsManager,tm as lambdaLayersManager,lm as lambdaVPCManager,nm as lambdaVersionsManager,rA as lambdaWorkloads,Af as laravelServerlessEnvDefaults,Th as listComposeTemplates,Dy as listSourceReferences,Bf as loadCloudConfig,qC as loadTelemetryPolicy,Dp as logsManager,NC as lookbackHoursForSignal,_s as mailEnabled,Bs as mailFirewallPorts,bb as maintenanceWindowOpen,fs as makeAWSRequest,hs as makeAWSRequestAsync,gs as makeAWSRequestOnce,Yc as managementDashboardSiteName,gb as manifestDigest,Mg as matchTotpCounter,To as mediaObjectHeaders,CC as median,SC as medianAbsoluteDeviation,uC as mergeDecisions,il as mergeInfrastructure,Vy as mergePriceBooks,eC as meterTelemetry,$p as metricsManager,ur as migrateObjectStorage,Op as migrationManager,Nu as multiAccountManager,cu as multiRegionManager,zo as needsRenewal,xf as networkSecurityManager,CA as nextScheduleRuns,Tn as normalizePublicIpv6,JS as normalizeRuntimeStatus,yA as normalizeScheduleExpression,Ay as normalizeSourceEvent,qn as normalizeSshPublicKey,jC as normalizeTelemetryPolicy,Bt as occupiedHostPorts,RS as openApiDocument,OC as optionsForSignal,ku as organizationManager,If as packagePhpApp,zm as packageServerlessApp,Me as pagesAssetHash,Ct as pagesDnsRecord,ed as parallel,rd as parallelMap,nd as parallelWithRetry,wg as parseCertificateState,$t as parseChain,bh as parseCompose,Dh as parseComposeCatalog,nA as parseDockerInspect,jb as parseDotenv,Hf as parseDrainedSites,Wt as parseHostSiteFragments,Cs as parseJSONResponse,oi as parsePreflightFacts,$g as parseSourceDrained,aA as parseSystemdRecords,bg as parseTargetReady,Mt as parseUpstreamPort,yg as parseWorkersPaused,ys as parseXMLResponse,QC as pathTemplate,tg as pendingSteps,aC as percentOfLimit,Lp as performanceManager,Ym as phpLayerBuildStage,Jm as phpLayerPackages,Sf as phpRuntimeLayerAssets,wh as planComposeTemplateUpgrade,fC as planEnforcement,rg as planIsDestructive,ar as planMitigation,ag as planServerRename,Ng as planSiteMove,wr as planZoneMigration,Rr as policyTag,si as preflightFailed,wd as previewManager,kd as previewNotifications,SA as previewSchedule,Ky as previousBudgetWindow,_y as priceUsage,My as priceUsageLines,Jf as probeHostRoutes,pe as probeOriginTls,cd as processInChunks,by as processSourceWebhook,US as productionChangeReview,bp as progressiveDeploymentManager,oC as projectSpend,wt as propagationHeaders,pr as providerEndpoint,yb as publicKeyFingerprint,Pr as qualifyName,_m as queueManagementManager,Yl as quickHash,_i as rateLimitHeaders,Li as rateLimitKey,Yn as readDriverState,Yf as reconcile,In as reconcileAddressRecords,pt as reconcileCloudflareCdn,$r as reconcileDeclaredRecords,PA as reconcileJobObservation,wy as reconcileSourceWebhook,GS as recordDashboardHostPosture,HS as recordPreDeploySecretScan,zS as recordSkippedSecretScan,Et as recursionBlockedResponse,YS as redactRuntimeConfig,YC as redactTelemetryText,XC as redactTelemetryValue,uo as redeployServerlessApp,gu as regionPairManager,iy as releaseStrategyCapabilities,cy as releaseTrafficPlan,vi as reloadRpxGateway,lr as remapKey,ji as removeSiteFromCloudConfig,Ey as removeSourceWebhook,Pn as removeStaleServerAddressRecords,Ih as renderComposeTemplate,or as renderDdosInstallScript,ir as renderNftablesRuleset,bA as renderServerCron,nr as renderSysctlFile,Ln as renderWafConfig,Fn as renderWafInstallScript,Oi as renewRpxCertificates,kp as replicaManager,yS as requestHash,ud as requiresReplacement,cf as resetRecursionRuntime,uf as resolveApp,Fs as resolveAppDatabase,cg as resolveAttachTarget,qg as resolveAuthEncryptionKey,Ws as resolveCloudProvider,ft as resolveCloudflareCdnPlan,Cl as resolveCredentials,yo as resolveDashboardAction,Ti as resolveDashboardAuth,Kc as resolveDashboardDomain,qc as resolveDashboardDomains,Tr as resolveDeclaredRecords,Js as resolveDeployBucketName,xs as resolveDeploymentMode,Ci as resolveExecStart,Kn as resolveHetznerApiToken,Ms as resolveMailService,el as resolveManagementDashboardSite,Qc as resolveManagementDashboardSites,mr as resolveObjectStorage,eg as resolvePlan,Us as resolveProjectStackName,Ot as resolveProxyUpstreams,Km as resolveQueueNames,Hh as resolveQueuedDeploymentCommand,jm as resolveQueues,of as resolveRecursionConfig,Sl as resolveRegion,pA as resolveRuntimeInventory,Ys as resolveServerlessAppStackName,Xs as resolveServerlessArtifactBucketName,Qs as resolveServerlessAssetBucketName,Um as resolveServerlessRuntime,qs as resolveSiteBucketName,kt as resolveSiteDeployTarget,xt as resolveSiteKind,Ks as resolveSiteResourceName,js as resolveSiteStackName,ni as resolveSshSettings,Os as resolveStatePath,Zs as resolveStorageBucketName,$i as resolveUiSource,Fe as resolveZoneApex,Ff as resourceManagementManager,mf as responseToResult,AC as robustZScore,rh as roleCapabilities,dy as rollbackImmutableRelease,po as rollbackServerlessApp,By as roundCents,ym as route53ResolverManager,mm as route53RoutingManager,IC as routeMatches,qf as routesFromFragments,xi as ruleMatches,Vm as runBuildHooks,gC as runEnforcement,Tf as runPhpBuildHooks,fo as runRemoteCommand,KS as runtimeId,go as sanitizeCloudConfig,ph as sanitizeControlPlaneValue,Gs as sanitizeName,Zg as sanitizeOidcReturnPath,ZC as saveTelemetryPolicy,DS as scanForSecrets,nh as scopeContains,rC as scopeKey,zn as scpUpload,Zd as searchCommands,fh as searchControlPlane,Wp as secretsManager,Bp as secretsRotationManager,jS as secureContainerRelease,mp as securityHubManager,Up as securityScanningManager,VS as securityScope,jg as sendAuthenticationEmail,Pm as senderReputationManager,id as sequence,Kb as serializeDotenv,yi as serverPublicIpv4,Qp as serviceMeshManager,Zi as setAttachToInCloudConfig,mo as setMaintenance,qi as setSitePropertyInCloudConfig,Ds as setStateDir,Wo as setupDns01Challenge,yn as setupSmsInfrastructure,Wm as sha256,sf as sharedRecursionGuard,ef as sharedRuntimeLoop,Ft as shipsARelease,bo as signCloudFrontCookies,Ao as signCloudFrontUrl,ds as signRequest,us as signRequestAsync,EC as signalDefinition,vt as siteInstallBase,mg as siteMoveArchivePath,Ig as siteMoveCertArchivePath,fg as siteUnitGlob,aS as spendNotificationText,AS as spendOpenApiPaths,Wn as sshExec,Hn as sshExecOrThrow,hu as stackDependencyManager,Co as startLocalDashboardServer,pS as startSpendLoop,Es as stateDir,vs as statePath,wf as staticSiteManager,vf as storageAdvancedManager,FC as streamFocusJsonl,hC as strongestActiveAction,Ud as suggestCommand,Yd as suggestFlags,Ml as suggestIAMPolicy,Hl as suggestQuotaIncrease,Iu as suggestRegionPairs,$u as suggestRegions,Iy as syncSourceRepositories,ey as synchronizeComposeVolumes,Qb as synchronizeConfiguredConfiguration,EA as synchronizeConfiguredJobs,Ep as syntheticsManager,rr as sysctlHardening,sA as systemdWorkloads,rS as telemetryBucketLabel,eS as telemetryCursor,JC as telemetryEstimatedMonthlyCost,tS as telemetryPercentile,KC as telemetryPolicyKey,Ul as templateCache,Zf as tenantsOf,$y as testSourceConnection,Ly as tieredMicroCents,ue as toCloudflareZoneSettings,LC as toFocusJsonl,xC as toFocusRecords,Kf as toInventoryServer,Fg as totp,Bg as totpUri,Xf as unaccountedSites,qS as unsupportedCapabilities,Uh as unsupportedVolumeCapabilities,Sb as updateCompatibility,Ki as updateSiteInCloudConfig,to as uploadStaticFiles,Xy as usageDeltaKey,Uy as utcInstantOfLocal,Bu as validateAccountStructure,hd as validateAgainstSchema,qh as validateAttachment,Db as validateBackupDestination,eu as validateCommand,kl as validateConfiguration,Ll as validateCredentials,Lt as validateDeploymentConfig,Kh as validateMountPath,et as validateResourceLimits,og as validateServerName,qe as validateTemplate,Qe as validateTemplateSize,Dn as verifyAddressRecord,BS as verifyArtifactSignature,Po as verifyMediaAccessToken,_g as verifyTotp,Cb as verifyUpdateSignature,vr as verifyZoneParity,jh as volumeCapabilities,_n as wafEventTelemetry,Un as waitForCloudInit,Gn as waitForSsh,Ry as webhookEndpoint,ll as withCDN,cl as withCache,sl as withDatabase,df as withInvocation,ol as withMonitoring,dl as withQueue,al as withSecurity,od as withTimeout,Zn as wrapCloudInitUserData,Xn as writeDriverState,Pp as xrayManager,QA as zeroCapacity,MC as zeroFill,Gy as zoneOffsetMs,zy as zonedParts};
|