@stacksjs/ts-cloud 0.16.49 → 0.16.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/dist/aws/index.js +1 -1
  2. package/dist/bin/{chunk-z8k9mcn5.js → chunk-0wtshht7.js} +2 -2
  3. package/dist/bin/chunk-20dp8658.js +1 -0
  4. package/dist/bin/chunk-2wh45zhk.js +2 -0
  5. package/dist/bin/chunk-334jngt2.js +1 -0
  6. package/dist/bin/{chunk-4yym8xm4.js → chunk-33ntxz01.js} +5 -5
  7. package/dist/bin/chunk-3k7y1h18.js +1 -0
  8. package/dist/bin/{chunk-dj03v81n.js → chunk-45thdtvf.js} +200 -200
  9. package/dist/bin/chunk-5c4xh61a.js +111 -0
  10. package/dist/bin/{chunk-vhyp4xj0.js → chunk-5ny7rggt.js} +1 -1
  11. package/dist/bin/chunk-626npmtj.js +1 -0
  12. package/dist/bin/chunk-67vf8myy.js +1 -0
  13. package/dist/bin/{chunk-zvbc92pc.js → chunk-734n0gkw.js} +1 -1
  14. package/dist/bin/chunk-74wppexz.js +1 -0
  15. package/dist/bin/{chunk-q4dywv80.js → chunk-7czb1kgg.js} +2 -2
  16. package/dist/bin/{chunk-kbwm0sqv.js → chunk-811k54jq.js} +2 -2
  17. package/dist/bin/chunk-83brtkvn.js +1 -0
  18. package/dist/bin/chunk-87g6jcfm.js +1 -0
  19. package/dist/bin/chunk-8ya34jz7.js +1 -0
  20. package/dist/bin/{chunk-v7t6f8aw.js → chunk-93yw46n7.js} +2 -2
  21. package/dist/bin/chunk-964xmgb6.js +1 -0
  22. package/dist/bin/chunk-9qdrv6zp.js +1 -0
  23. package/dist/bin/{chunk-4mecfcjk.js → chunk-a7hhzbvm.js} +3 -3
  24. package/dist/bin/chunk-azarn24c.js +1 -0
  25. package/dist/bin/{chunk-3pazrfsf.js → chunk-cjagqdk3.js} +7 -7
  26. package/dist/bin/{chunk-03gqra5e.js → chunk-d24ztt54.js} +83 -83
  27. package/dist/bin/chunk-d2fq60kd.js +1 -0
  28. package/dist/bin/{chunk-01w4zbex.js → chunk-da6dmacg.js} +2 -2
  29. package/dist/bin/{chunk-cf3jn2ey.js → chunk-ddyd6f14.js} +3 -3
  30. package/dist/bin/chunk-dpk5r544.js +1 -0
  31. package/dist/bin/{chunk-12x968en.js → chunk-dv2he3vc.js} +3 -3
  32. package/dist/bin/{chunk-w29z877b.js → chunk-f0vedy45.js} +2 -2
  33. package/dist/bin/chunk-f578z20t.js +1 -0
  34. package/dist/bin/{chunk-psmpw0ap.js → chunk-f78wmcvb.js} +3 -3
  35. package/dist/bin/chunk-f9469h6q.js +1 -0
  36. package/dist/bin/{chunk-rdkr74y2.js → chunk-fhe0mdjg.js} +1 -1
  37. package/dist/bin/chunk-fjbhvhqb.js +1 -0
  38. package/dist/bin/chunk-g6ph425d.js +1 -0
  39. package/dist/bin/{chunk-ynwbzsz8.js → chunk-gc199s7a.js} +158 -158
  40. package/dist/bin/{chunk-nj9x0tb8.js → chunk-gr1ra9nj.js} +2 -2
  41. package/dist/bin/{chunk-xdk0gmxt.js → chunk-hhmqsrfc.js} +1 -1
  42. package/dist/bin/{chunk-n7yefy09.js → chunk-m3xap663.js} +5 -5
  43. package/dist/bin/chunk-m5jvp6ph.js +1 -0
  44. package/dist/bin/chunk-m7pbssep.js +1 -0
  45. package/dist/{chunk-6rcj3km0.js → bin/chunk-mcg4wg4j.js} +7 -7
  46. package/dist/bin/{chunk-gyvkravq.js → chunk-n5kdne4p.js} +5 -5
  47. package/dist/bin/chunk-n7xadeqe.js +1 -0
  48. package/dist/bin/{chunk-cz2wq0tf.js → chunk-ngmewar1.js} +5 -5
  49. package/dist/bin/chunk-p6wxv8yq.js +1 -0
  50. package/dist/bin/{chunk-xe527q1k.js → chunk-ppd463ev.js} +2 -2
  51. package/dist/bin/{chunk-23m8kbwh.js → chunk-q2rqmc2x.js} +3 -3
  52. package/dist/bin/{chunk-7qbxq0be.js → chunk-rwbdtxte.js} +1 -1
  53. package/dist/bin/{chunk-v09tfezh.js → chunk-sa9c8vb5.js} +5 -5
  54. package/dist/bin/{chunk-6y6g726g.js → chunk-t970yjvz.js} +5 -5
  55. package/dist/bin/{chunk-q8b77zgw.js → chunk-te52z1wk.js} +1 -1
  56. package/dist/bin/chunk-vpt43nwa.js +1 -0
  57. package/dist/bin/{chunk-frzpqsbj.js → chunk-we2raqk3.js} +2 -2
  58. package/dist/bin/chunk-wgh66c5r.js +1 -0
  59. package/dist/bin/{chunk-znd507q9.js → chunk-wv8060cw.js} +8 -8
  60. package/dist/bin/{chunk-xx9mrcfs.js → chunk-yfa84s0c.js} +1 -1
  61. package/dist/bin/{chunk-5nmt4s5w.js → chunk-ytzcsskk.js} +2 -2
  62. package/dist/bin/{chunk-psvqpztv.js → chunk-z06jkvvr.js} +5 -5
  63. package/dist/bin/chunk-zywk12mp.js +1 -0
  64. package/dist/bin/cli.js +203 -203
  65. package/dist/bin/dashboard-server.js +1 -1
  66. package/dist/chunk-09d6pdgx.js +1 -0
  67. package/dist/{chunk-yme6q7k4.js → chunk-0cz2s19h.js} +2 -2
  68. package/dist/{chunk-nryh43p1.js → chunk-0qgfe5ff.js} +3 -3
  69. package/dist/chunk-21mmcmm7.js +1 -0
  70. package/dist/chunk-2gqm2h84.js +1 -0
  71. package/dist/{bin/chunk-k343q24p.js → chunk-3ncnrrvm.js} +7 -7
  72. package/dist/chunk-4abbccq7.js +2 -0
  73. package/dist/{chunk-rpng90t9.js → chunk-4yqd62rd.js} +1 -1
  74. package/dist/chunk-53kyxata.js +709 -0
  75. package/dist/{chunk-da62knsv.js → chunk-6gnmrtp9.js} +83 -83
  76. package/dist/{chunk-x0ep5ybv.js → chunk-6m8p1n88.js} +13 -13
  77. package/dist/{chunk-fpkpwbv3.js → chunk-8b2mxhcm.js} +5 -5
  78. package/dist/{chunk-r3m1fjd4.js → chunk-9ggg2ktx.js} +2 -2
  79. package/dist/chunk-ca191b00.js +6 -0
  80. package/dist/chunk-dw0cvqdr.js +448 -0
  81. package/dist/{chunk-ynprwawa.js → chunk-erfh93dq.js} +2 -2
  82. package/dist/{chunk-22hfejjs.js → chunk-ffyx50xx.js} +1 -1
  83. package/dist/{chunk-jpdpr7k6.js → chunk-j99nkav5.js} +3 -3
  84. package/dist/chunk-jgsey18z.js +1 -0
  85. package/dist/{chunk-vb4t2r4r.js → chunk-jtvw9d4x.js} +1 -1
  86. package/dist/chunk-jytama4e.js +111 -0
  87. package/dist/chunk-m9r0a1v9.js +2 -0
  88. package/dist/chunk-p101nhg2.js +5 -0
  89. package/dist/{chunk-kr8aeva1.js → chunk-prtvb2fh.js} +549 -549
  90. package/dist/{chunk-jhtp3m31.js → chunk-pz33w7gv.js} +2 -2
  91. package/dist/chunk-qbsrs1gp.js +1 -0
  92. package/dist/{chunk-xzcpzxtj.js → chunk-qcj3hkba.js} +2 -2
  93. package/dist/{chunk-e8k29wen.js → chunk-qcv4twc6.js} +19 -19
  94. package/dist/{chunk-p7myt05d.js → chunk-r5mk071y.js} +5 -5
  95. package/dist/{chunk-xxq1ygp9.js → chunk-thdfk76k.js} +3 -3
  96. package/dist/chunk-tnqj2en4.js +1 -0
  97. package/dist/{chunk-6mp1fyxe.js → chunk-x4qye2rc.js} +4 -4
  98. package/dist/chunk-xgc6hskd.js +138 -0
  99. package/dist/{chunk-vjph4eh0.js → chunk-zf5wdx6v.js} +1 -1
  100. package/dist/deploy/index.js +1 -1
  101. package/dist/dns/index.js +1 -1
  102. package/dist/drivers/aws/provision.d.ts +2 -2
  103. package/dist/drivers/index.js +1 -1
  104. package/dist/drivers/shared/mail-provision.d.ts +2 -18
  105. package/dist/drivers/shared/rpx-gateway.d.ts +3 -1
  106. package/dist/index.js +60 -60
  107. package/dist/mail/index.d.ts +5 -0
  108. package/dist/mail/index.js +3 -0
  109. package/dist/mail/webmail.d.ts +35 -0
  110. package/dist/mail/webmail.test.d.ts +1 -0
  111. package/dist/operations/index.js +1 -1
  112. package/dist/protection/index.js +1 -1
  113. package/dist/spend/index.js +1 -1
  114. package/dist/ui/404.html +1 -1
  115. package/dist/ui/accept-invitation.html +1 -1
  116. package/dist/ui/access-denied.html +1 -1
  117. package/dist/ui/account/automation.html +6 -6
  118. package/dist/ui/account/security.html +2 -2
  119. package/dist/ui/applications/compose.html +6 -6
  120. package/dist/ui/applications/new.html +2 -2
  121. package/dist/ui/data/backups.html +6 -6
  122. package/dist/ui/data/services.html +6 -6
  123. package/dist/ui/data/volumes.html +6 -6
  124. package/dist/ui/index.html +6 -6
  125. package/dist/ui/infrastructure/topology.html +6 -6
  126. package/dist/ui/integrations.html +2 -2
  127. package/dist/ui/operations/alerts.html +6 -6
  128. package/dist/ui/operations/configuration.html +5 -5
  129. package/dist/ui/operations/jobs.html +6 -6
  130. package/dist/ui/operations/maintenance.html +6 -6
  131. package/dist/ui/operations/observability.html +6 -6
  132. package/dist/ui/operations/previews.html +6 -6
  133. package/dist/ui/operations/queue.html +6 -6
  134. package/dist/ui/operations/regions.html +5 -5
  135. package/dist/ui/operations/releases.html +6 -6
  136. package/dist/ui/operations/spend.html +6 -6
  137. package/dist/ui/operations/workloads.html +6 -6
  138. package/dist/ui/security.html +1 -1
  139. package/dist/ui/server/actions.html +5 -5
  140. package/dist/ui/server/activity.html +1 -1
  141. package/dist/ui/server/capacity.html +5 -5
  142. package/dist/ui/server/database.html +6 -6
  143. package/dist/ui/server/deployments.html +6 -6
  144. package/dist/ui/server/diagnostics.html +1 -1
  145. package/dist/ui/server/firewall.html +6 -6
  146. package/dist/ui/server/fleet.html +6 -6
  147. package/dist/ui/server/logs.html +5 -5
  148. package/dist/ui/server/metrics.html +6 -6
  149. package/dist/ui/server/security.html +2 -2
  150. package/dist/ui/server/services.html +1 -1
  151. package/dist/ui/server/sites.html +5 -5
  152. package/dist/ui/server/ssh-keys.html +6 -6
  153. package/dist/ui/server/team.html +6 -6
  154. package/dist/ui/server/terminal.html +1 -1
  155. package/dist/ui/serverless/alarms.html +5 -5
  156. package/dist/ui/serverless/assets.html +2 -2
  157. package/dist/ui/serverless/cost.html +2 -2
  158. package/dist/ui/serverless/data.html +5 -5
  159. package/dist/ui/serverless/deployments.html +2 -2
  160. package/dist/ui/serverless/firewall.html +2 -2
  161. package/dist/ui/serverless/functions.html +6 -6
  162. package/dist/ui/serverless/logs.html +5 -5
  163. package/dist/ui/serverless/metrics.html +2 -2
  164. package/dist/ui/serverless/queues.html +6 -6
  165. package/dist/ui/serverless/secrets.html +6 -6
  166. package/dist/ui/serverless/traces.html +6 -6
  167. package/dist/ui/serverless.html +6 -6
  168. package/package.json +7 -3
  169. package/dist/bin/chunk-1fj03993.js +0 -1
  170. package/dist/bin/chunk-1xxmyx0r.js +0 -1
  171. package/dist/bin/chunk-2pzh0wxc.js +0 -1
  172. package/dist/bin/chunk-45qr2bd3.js +0 -1
  173. package/dist/bin/chunk-4nn00brw.js +0 -1
  174. package/dist/bin/chunk-52w33yma.js +0 -1
  175. package/dist/bin/chunk-5f1n5d80.js +0 -1
  176. package/dist/bin/chunk-5mm6qn6m.js +0 -1
  177. package/dist/bin/chunk-5xr76cms.js +0 -1
  178. package/dist/bin/chunk-65yvjecx.js +0 -2
  179. package/dist/bin/chunk-d0tmmzy5.js +0 -1
  180. package/dist/bin/chunk-fqghdpvr.js +0 -1
  181. package/dist/bin/chunk-gkdr09xx.js +0 -1
  182. package/dist/bin/chunk-hhhrze6m.js +0 -1
  183. package/dist/bin/chunk-jrztbsnb.js +0 -1
  184. package/dist/bin/chunk-kqxk1pds.js +0 -1
  185. package/dist/bin/chunk-m8p7mw67.js +0 -1
  186. package/dist/bin/chunk-n2c6y0k1.js +0 -1
  187. package/dist/bin/chunk-pr1dg1km.js +0 -1
  188. package/dist/bin/chunk-pzj1ac7x.js +0 -1
  189. package/dist/bin/chunk-rgcrsd5m.js +0 -1
  190. package/dist/bin/chunk-thph4z3k.js +0 -1
  191. package/dist/bin/chunk-txykq6f1.js +0 -1
  192. package/dist/bin/chunk-vjg2fymw.js +0 -1
  193. package/dist/bin/chunk-ym9h629y.js +0 -111
  194. package/dist/bin/chunk-z8scg2vy.js +0 -1
  195. package/dist/bin/chunk-zjvg5pg8.js +0 -1
  196. package/dist/chunk-25sw2s70.js +0 -1
  197. package/dist/chunk-2pns2rkf.js +0 -111
  198. package/dist/chunk-2sc0s7pc.js +0 -6
  199. package/dist/chunk-7v7dwev4.js +0 -584
  200. package/dist/chunk-bdv3gpzb.js +0 -709
  201. package/dist/chunk-fh7apa5n.js +0 -2
  202. package/dist/chunk-gh0ghb21.js +0 -2
  203. package/dist/chunk-gqadvddh.js +0 -1
  204. package/dist/chunk-kpmxvpcv.js +0 -1
  205. package/dist/chunk-ksqhsz52.js +0 -1
  206. package/dist/chunk-p588apka.js +0 -1
  207. package/dist/chunk-vnarc5gc.js +0 -5
  208. package/dist/chunk-x7d93rxb.js +0 -1
@@ -0,0 +1,138 @@
1
+ import{on,dr}from"./chunk-prtvb2fh.js";import{Vr,d}from"./chunk-pz33w7gv.js";import{isIP as L}from"node:net";var to="/etc/rpx/certs",A="/etc/rpx/local-ca",M="rpx-root-ca.crt";function ro(e=A){return`${e.replace(/\/+$/,"")}/${M}`}function no(e){if(e.toLowerCase().endsWith(".local"))return!1;return e.split(".").length===2}function io(e,t={}){let r=new Set;for(let o of Object.values(e)){if(!o?.domain)continue;if(d(o)==="bucket")continue;r.add(o.domain)}let n=new Set;for(let o of Object.values(e)){if(!o?.domain||d(o)==="bucket")continue;for(let u of o.aliases??[]){let i=String(u).trim().toLowerCase();if(i&&i!==o.domain)n.add(i)}}if(t.autoWww!==!1)for(let o of[...r]){if(!no(o))continue;r.add(`www.${o}`)}for(let o of n)r.add(o);return[...r]}var k=["1.1.1.1","8.8.8.8"],I="/var/www/acme-challenge";function W(e){if(typeof e==="string")return{to:e};let t={to:e.to};if(e.status!=null)t.status=e.status;if(e.preservePath!=null)t.preservePath=e.preservePath;return t}function U(e){let t=e.auth;if(!t||t.enabled===!1||!t.password)return;return{username:t.username||"admin",password:t.password,...t.realm?{realm:t.realm}:{}}}function Yc(e){if(!e)return;return e.tls??"local-ca"}function op(e,t){if(e.cloud?.provider!=="ssh")return;let r=e.ssh?.lan;if(!r)return;return{...r.hostname?{hostname:r.hostname}:{},tls:r.tls??"local-ca",...t?{ip:t}:{}}}function ap(e){if(e.cloud?.provider!=="ssh")return;return e.ssh?.profile}function X(e){let t=e.trim().toLowerCase();if(!t||t.startsWith("*")||t.includes(":")||t.includes("/")||t.includes(" "))return!1;if(L(t)!==0)return!1;return t.endsWith(".local")||!t.includes(".")}function F(e,t,r){let n=[],o=new Set,u=(g,a)=>{let p=g.trim().toLowerCase();if(!p||o.has(p))return;o.add(p),n.push({host:p,source:a})},i=t.hostname?.trim(),c=(i||`${r}.local`).toLowerCase();if(u(c,i?"ssh.lan.hostname":`the ssh provider's default LAN name for project "${r}"`),Object.entries(e).some(([g,a])=>!!a&&dr(g)))u(`dashboard.${c}`,"the management dashboard site");for(let[g,a]of Object.entries(e)){if(!a?.domain)continue;if(d(a)==="bucket")continue;if(!X(a.domain))continue;u(a.domain,`site "${g}"`)}return n}function H(e,t){if(!t?.length)return;return t.find((r)=>{let n=(r.startsWith(".")?r.slice(1):r).toLowerCase();return e===n||e.endsWith(`.${n}`)})}function K(e,t){if(!t?.enabled)return;for(let{host:r,source:n}of e){let o=H(r,t.allowedSuffixes);if(!o)continue;throw Error(`The LAN certificate authority and public on-demand TLS both claim "${r}". LAN source: ${n}. Public source: the on-demand TLS allowed suffix "${o}", which is derived from the site domains. A host is either LAN-only, with a certificate signed by the box's own CA, or public, with one issued by Let's Encrypt, never both. Give the LAN a name no site domain covers (ssh.lan.hostname), or take that domain out of the sites this deploy routes.`)}}function V(e){let t=e.split(".");return t.length>=3&&t[0]==="*"&&t.slice(1).every((r)=>/^[a-z0-9-]+$/i.test(r))}function D(e,t={}){let{wildcardCerts:r,...n}=e;return JSON.stringify({...t,...n},null,2)}function Uh(e){if(!e||e==="/")return;let t=`/${e}`.replace(/\/+/g,"/").replace(/\/+$/,"");if(!t.startsWith("/"))t=`/${t}`;return t===""||t==="/"?void 0:t}function Zc(e,t){let n=(t?`${e}${t}`:e).replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,128);return n.length>0?n:"rpx"}function Y(e,t){if(!t||t.length===0)return`localhost:${e}`;return t.map((r)=>`${r.privateIp??r.publicIp}:${e}`)}function N(e,t,r){let n=(t.wwwRoot??"/var/www").replace(/\/+$/,""),o=t.slug??"app",u=t.proxy.certsDir??to,i=t.proxy.loadBalancer,c=[],f=new Set,g=new Map;for(let[l,s]of Object.entries(e)){if(!s||!s.domain)continue;let w=d(s);if(w==="bucket")continue;let v=c.length,E=[...new Set((s.aliases??[]).map((m)=>String(m).trim().toLowerCase()).filter((m)=>m&&m!==s.domain))],b=()=>{let m=c.slice(v).filter((h)=>h.to===s.domain);for(let h of E){for(let O of m)c.push({...O,to:h,id:Zc(h,O.path)});if(V(h)){if(!g.has(h))g.set(h,{domain:h,dnsEnvFile:`${n}/${o}-${l}/shared/.env`})}else f.add(h)}},C=Uh(s.path),S=Zc(s.domain,C),y=U(s);if(w==="redirect"){c.push({to:s.domain,path:C,redirect:W(s.redirect),id:S,...y?{auth:y}:{}}),f.add(s.domain),b();continue}if(w==="proxy"){let m=Vr(s);if(m.length===0)continue;let h=m.length===1?m[0]:m;c.push({to:s.domain,path:C,from:h,id:S,...y?{auth:y}:{},...Array.isArray(h)&&i?{loadBalancer:i}:{}}),f.add(s.domain),b();continue}if(w==="server-app"){if(typeof s.port!=="number")continue;let m=Y(s.port,r);c.push({to:s.domain,path:C,from:m,id:S,...y?{auth:y}:{},...Array.isArray(m)&&i?{loadBalancer:i}:{}})}else c.push({to:s.domain,path:C,static:{dir:`${n}/${o}-${l}/current`,spa:s.spa??!1,pathRewriteStyle:s.pathRewriteStyle??"directory"},cleanUrls:s.pathRewriteStyle!=="flat",...y?{auth:y}:{},id:S});f.add(s.domain),b()}if(t.proxy.autoWww!==!1)for(let l of[...f]){if(!no(l))continue;let s=`www.${l}`;if(f.has(s))continue;c.push({to:s,redirect:{to:`https://${l}`},id:Zc(s)}),f.add(s)}c.sort((l,s)=>{if(l.to!==s.to)return l.to.localeCompare(s.to);return(s.path?.length??0)-(l.path?.length??0)});let a={proxies:c,productionCerts:{certsDir:u,certsDirServerNames:[...f,...g.keys()]},https:!0,hostsManagement:!1,cleanup:{hosts:!1,certs:!1},...g.size>0?{wildcardCerts:[...g.values()]}:{}};if(t.proxy.onDemandTls&&f.size>0)a.onDemandTls={enabled:!0,allowedSuffixes:[...f],email:t.proxy.onDemandTlsEmail,certsDir:u,staging:t.proxy.onDemandTlsStaging??!1};if(t.proxy.onDemandTls)a.acmeChallengeWebroot=t.proxy.acmeWebroot??I;let p=t.proxy.cdn,x=p?.frontedHosts?.length?p.frontedHosts:[...f];if(p?.secret&&x.length>0)a.originGuard={header:p.secretHeader??"X-Origin-Verify",value:p.secret,hosts:x};if(t.lan)if(Yc(t.lan)==="off")a.https=!1;else{let l=F(e,t.lan,o);K(l,a.onDemandTls);let s=t.lan.ip&&L(t.lan.ip)!==0?[t.lan.ip]:[];a.localCa={dir:A,hosts:l.map((w)=>w.host),...s.length>0?{ips:s}:{},installTrust:!0}}return a}function B(e,t){return N({...e,...t.mail?on(t.mail):{}},t)}function Xt(e,t,r){return N({...e,...r.mail?on(r.mail):{}},r,t)}function fI(e){return`// Generated by ts-cloud — rpx reverse-proxy gateway.
2
+ // Routes are derived from the \`sites\` model on every \`buddy deploy\`.
3
+ import { startProxies } from '@stacksjs/rpx'
4
+
5
+ const config = ${D(e)} as const
6
+
7
+ // Verbose is the hard default for ts-cloud-installed gateways (RPX_VERBOSE=false
8
+ // opts out) — without it rpx's TLS/routing diagnostics never reach the journal.
9
+ await startProxies({ verbose: process.env.RPX_VERBOSE !== 'false', ...config } as any)
10
+ `}function j(e){return e?.webServer==="rpx"||e?.proxy?.engine==="rpx"}var so="/etc/rpx",R="/opt/rpx-gateway",cp="/etc/rpx/gateway.ts",yt="/etc/rpx/gateway",ze="rpx-gateway.service",z="/etc/rpx/sites.d";function J(e=z,t=to){return`// Generated by ts-cloud — rpx gateway assembler.
11
+ // Merges every app's fragment in ${e} so independent deploys compose
12
+ // without clobbering each other. Each deploy writes only its own <slug>.json.
13
+ import { startProxies } from '@stacksjs/rpx'
14
+ import { readdirSync, readFileSync } from 'node:fs'
15
+
16
+ const dir = ${JSON.stringify(e)}
17
+ const proxies = []
18
+ const seen = new Set()
19
+ const owners = new Map()
20
+ const suffixes = new Set()
21
+ const guardHosts = new Set()
22
+ let email
23
+ let certsDir = ${JSON.stringify(t)}
24
+ let acmeChallengeWebroot
25
+ let guard
26
+ let anyProduction = false
27
+ // LAN certificate authority, unioned across fragments. It is gateway-wide, but
28
+ // it is carried per fragment because THIS file is rewritten wholesale by every
29
+ // deploy on the box: a co-tenant's deploy would erase a CA baked in here, while
30
+ // a fragment belongs to the project that configured it.
31
+ let localCa
32
+ const localCaHosts = new Set()
33
+ const localCaIps = new Set()
34
+ // TLS stays on unless every fragment asks for plain HTTP.
35
+ let fragmentCount = 0
36
+ let anyTls = false
37
+ let files = []
38
+ try { files = readdirSync(dir).filter(n => n.endsWith('.json')).sort() } catch {}
39
+ for (const f of files) {
40
+ let frag
41
+ // Fragments are written atomically (temp + rename by ts-cloud), so a parse
42
+ // failure here means a genuinely corrupt fragment, not a mid-write read. Log
43
+ // it LOUD — a silent skip drops that app's whole host from the routing table,
44
+ // which then answers 404 until someone notices. We still continue so one bad
45
+ // fragment can't take every other app down, but the drop is now visible.
46
+ try { frag = JSON.parse(readFileSync(dir + '/' + f, 'utf8')) }
47
+ catch (err) { console.error('[rpx-assembler] SKIPPING malformed fragment ' + f + ' — its host(s) will 404 until fixed: ' + err); continue }
48
+ fragmentCount++
49
+ if (frag.https !== false) anyTls = true
50
+ if (frag.localCa) {
51
+ if (!localCa) localCa = { dir: frag.localCa.dir }
52
+ else if (frag.localCa.dir !== localCa.dir) console.warn('[rpx-assembler] ' + f + ' asks for a local CA in ' + frag.localCa.dir + '; the box already uses ' + localCa.dir + ', so its hosts join that CA instead')
53
+ for (const h of frag.localCa.hosts ?? []) localCaHosts.add(h)
54
+ for (const ip of frag.localCa.ips ?? []) localCaIps.add(ip)
55
+ if (frag.localCa.installTrust) localCa.installTrust = true
56
+ if (localCa.validityDays === undefined) localCa.validityDays = frag.localCa.validityDays
57
+ if (localCa.renewBeforeDays === undefined) localCa.renewBeforeDays = frag.localCa.renewBeforeDays
58
+ }
59
+ for (const p of frag.proxies ?? []) {
60
+ const key = p.id || (p.to + (p.path ?? ''))
61
+ if (seen.has(key)) {
62
+ console.warn('[rpx-assembler] duplicate route ' + key + ' in ' + f + ' ignored; first declared by ' + owners.get(key))
63
+ continue
64
+ }
65
+ seen.add(key)
66
+ owners.set(key, f)
67
+ proxies.push(p)
68
+ }
69
+ for (const s of frag.onDemandTls?.allowedSuffixes ?? []) suffixes.add(s)
70
+ email ??= frag.onDemandTls?.email
71
+ // One gateway, one ACME directory: production wins any disagreement between
72
+ // co-tenants, and a fragment predating the flag counts as production. A
73
+ // staging cert chains to an untrusted root, so defaulting the other way
74
+ // breaks every client of every tenant that wanted a real cert.
75
+ if (frag.onDemandTls && frag.onDemandTls.staging !== true) anyProduction = true
76
+ if (frag.productionCerts?.certsDir) certsDir = frag.productionCerts.certsDir
77
+ acmeChallengeWebroot ??= frag.acmeChallengeWebroot
78
+ if (frag.originGuard) {
79
+ // One gateway means one origin-guard secret (rpx takes a single
80
+ // header/value). A tenant whose secret disagrees with the adopted one must
81
+ // NOT have its hosts guarded: its CDN would send a different value, the
82
+ // gateway would reject every request, and a working host would go dark.
83
+ // Unguarded is weaker but serving, and the mismatch is logged.
84
+ guard ??= { header: frag.originGuard.header, value: frag.originGuard.value }
85
+ if (frag.originGuard.header === guard.header && frag.originGuard.value === guard.value) {
86
+ for (const h of frag.originGuard.hosts ?? []) guardHosts.add(h)
87
+ }
88
+ else {
89
+ console.warn('[rpx-assembler] origin-guard secret in ' + f + ' differs from the one already in force; its hosts stay unguarded rather than rejecting all traffic')
90
+ }
91
+ }
92
+ }
93
+ if (localCa) {
94
+ localCa.hosts = [...localCaHosts]
95
+ if (localCaIps.size > 0) localCa.ips = [...localCaIps]
96
+ }
97
+ const config = {
98
+ proxies,
99
+ productionCerts: {
100
+ certsDir,
101
+ // A shared host's cert directory also contains mail and retired-site PEMs.
102
+ // Keep those files on disk for their owners, but do not turn them into live
103
+ // OpenSSL SNI contexts when no current route can select them.
104
+ certsDirServerNames: [...new Set(proxies.map(p => p.to).filter(Boolean))],
105
+ },
106
+ https: fragmentCount === 0 ? true : anyTls,
107
+ hostsManagement: false,
108
+ cleanup: { hosts: false, certs: false },
109
+ // Verbose is the hard default for ts-cloud-installed gateways: without it,
110
+ // rpx's TLS/routing diagnostics (tlsx on-demand 'refused issuance',
111
+ // 'issuance failed', 'adopted existing on-disk cert') never reach the systemd
112
+ // journal and a production TLS failure looks like "nothing happens". Silence
113
+ // it by setting RPX_VERBOSE=false on the systemd unit.
114
+ verbose: process.env.RPX_VERBOSE !== 'false',
115
+ ...(suffixes.size > 0 ? { onDemandTls: { enabled: true, allowedSuffixes: [...suffixes], email, certsDir, staging: !anyProduction } } : {}),
116
+ ...(acmeChallengeWebroot ? { acmeChallengeWebroot } : {}),
117
+ ...(guard ? { originGuard: { header: guard.header, value: guard.value, hosts: [...guardHosts] } } : {}),
118
+ ...(localCa && localCa.hosts.length > 0 ? { localCa } : {}),
119
+ }
120
+
121
+ await startProxies(config)
122
+ `}function _(e,t,r,n="0644"){return[`__tsc_tmp="$(mktemp "${e}.XXXXXX")"`,`cat > "$__tsc_tmp" <<'${r}'`,t,r,`mv -f "$__tsc_tmp" ${e}`,`chmod ${n} ${e}`]}function q(e){return`'${e.replaceAll("'","'\\''")}'`}function T(e,t,r,n){if(!n.preserveManagementDashboardRoutes)return _(e,t,r,"0600");let o=`
123
+ const { readFileSync, writeFileSync } = require('node:fs')
124
+ const currentPath = process.env.TS_CLOUD_RPX_CURRENT_FRAGMENT
125
+ const candidatePath = process.env.TS_CLOUD_RPX_CANDIDATE_FRAGMENT
126
+ const isDashboard = route => /^(?:dashboard|cloud)\\./i.test(String(route?.to || ''))
127
+ const current = JSON.parse(readFileSync(currentPath, 'utf8'))
128
+ const candidate = JSON.parse(readFileSync(candidatePath, 'utf8'))
129
+ const retained = Array.isArray(current.proxies) ? current.proxies.filter(isDashboard) : []
130
+ const next = Array.isArray(candidate.proxies) ? candidate.proxies.filter(route => !isDashboard(route)) : []
131
+ candidate.proxies = [...next, ...retained]
132
+ writeFileSync(candidatePath, JSON.stringify(candidate, null, 2) + '\\n', { mode: 0o600 })
133
+ `.trim();return[`__tsc_fragment_candidate="$(mktemp "${e}.candidate.XXXXXX")"`,`cat > "$__tsc_fragment_candidate" <<'${r}'`,t,r,'chmod 0600 "$__tsc_fragment_candidate"',`if [ -f ${e} ]; then TS_CLOUD_RPX_CURRENT_FRAGMENT=${e} TS_CLOUD_RPX_CANDIDATE_FRAGMENT="$__tsc_fragment_candidate" ${n.bunBin} -e ${q(o)}; fi`,`mv -f "$__tsc_fragment_candidate" ${e}`,`chmod 0600 ${e}`]}var Q={high:"256M",max:"384M"},Z={high:"512M",max:"768M"};function ed(e){return`rpx-cert-renew-${(e||"app").replace(/[^a-z0-9._-]+/gi,"-")}.service`}function td(e){let t=new Set;for(let r of e.proxies){let n=r.to;if(!n||n.startsWith("*")||n.includes(":")||!n.includes("."))continue;t.add(n)}return[...t]}function ee(e){if(e.length===0)return[];let t=["# Wildcards: dns-01 (Porkbun), keys read from the site's env file for tlsx alone.","dns_env() {",' [ -r "$1" ] || return 0',` sed -n "s/^$2=//p" "$1" | tail -n 1 | sed -e 's/^"\\(.*\\)"$/\\1/' -e "s/^'\\(.*\\)'$/\\1/"`,"}","wildcard() {",' apex="$1"',' envfile="$2"',' name="*.$apex"',' key=$(dns_env "$envfile" PORKBUN_API_KEY)',' secret=$(dns_env "$envfile" PORKBUN_SECRET_KEY)',' if [ -z "$key" ] || [ -z "$secret" ]; then',' echo "wildcard $name skipped: no PORKBUN_API_KEY / PORKBUN_SECRET_KEY in $envfile (non-fatal)"'," return 0"," fi",' if [ ! -s "$CERTS/_wildcard.$apex.crt" ]; then',' PORKBUN_API_KEY="$key" PORKBUN_SECRET_KEY="$secret" $TLSX acme:issue -d "$name" --method dns-01 --dns-provider porkbun --dir "$CERTS" --prod --email "$EMAIL" || echo "issue $name failed (non-fatal)"'," else",' PORKBUN_API_KEY="$key" PORKBUN_SECRET_KEY="$secret" $TLSX acme:renew --domains "$name" --method dns-01 --dir "$CERTS" --days 30 --prod --email "$EMAIL" || echo "renew $name failed (non-fatal)"'," fi","}"];for(let r of e){let n=r.domain.replace(/^\*\./,"");t.push(`wildcard '${n}' '${r.dnsEnvFile.replace(/'/g,"")}'`)}return t}function P(e){let{config:t,proxy:r}=e,n=t.acmeChallengeWebroot,o=td(t);if(!r.onDemandTls||!n||o.length===0)return[];let u=e.bunBin??"/usr/local/bin/bun",i=r.tlsxVersion??"latest",c=t.productionCerts.certsDir,f=r.onDemandTlsEmail??`webmaster@${o[0]}`,g=`${u} ${R}/node_modules/@stacksjs/tlsx/dist/bin/cli.js`,a=o.join(","),p=o.join(" "),x=(e.slug||"app").replace(/[^a-z0-9._-]+/gi,"-"),l=`${so}/renew-certs-${x}.sh`,s=ed(x),w=`rpx-cert-renew-${x}.timer`,v=t.wildcardCerts??[],E=v.length>0?"tlsx http-01 + dns-01 wildcard":"tlsx http-01",b=["#!/bin/sh",`# Generated by ts-cloud — issue/renew rpx gateway TLS certs via ${E}.`,"# The running gateway serves the challenge from $WEBROOT on :80, so this needs","# no downtime and no DNS credentials. Reloads the gateway only if a cert changed.","set -u",`CERTS='${c}'`,`WEBROOT='${n}'`,`EMAIL='${f}'`,`TLSX="${g}"`,`BUN='${u}'`,`DOMAINS='${a}'`,"DNS_ATTEMPTS='24'","DNS_DELAY_SECONDS='5'",`DNS_RESOLVERS='${k.join(" ")}'`,"dns_resolves() {",' d="$1"'," for ns in $DNS_RESOLVERS; do",` if $BUN --eval "const{Resolver}=require('node:dns');const r=new Resolver();r.setServers([process.argv[1]]);r.resolve4(process.argv[2],e=>process.exit(e?1:0))" "$ns" "$d" >/dev/null 2>&1; then`," return 0"," fi"," done",' getent ahosts "$d" >/dev/null 2>&1',"}","wait_for_dns() {",' d="$1"'," attempt=1",' while ! dns_resolves "$d"; do',' if [ "$attempt" -ge "$DNS_ATTEMPTS" ]; then',' echo "DNS for $d did not become resolvable after $DNS_ATTEMPTS attempts" >&2'," return 1"," fi",' echo "Waiting for public DNS before ACME: $d (attempt $attempt/$DNS_ATTEMPTS)"',' sleep "$DNS_DELAY_SECONDS"'," attempt=$((attempt + 1))"," done","}",'before=$(cat "$CERTS"/*.crt 2>/dev/null | sha256sum)',`for d in ${p}; do`,' if [ ! -s "$CERTS/$d.crt" ]; then',' if wait_for_dns "$d"; then',' $TLSX acme:issue -d "$d" --method http-01 --webroot "$WEBROOT" --dir "$CERTS" --prod --email "$EMAIL" || echo "issue $d failed (non-fatal)"'," else",' echo "issue $d skipped until DNS resolves (non-fatal)"'," fi"," # rpx reloads its SNI set when a PEM appears. Complete that reload"," # before the next hostname starts http-01, or :80 can disappear in"," # the middle of the following challenge on a multi-domain deploy.",` [ -s "$CERTS/$d.crt" ] && systemctl restart ${ze}`," fi","done",'$TLSX acme:renew --domains "$DOMAINS" --method http-01 --webroot "$WEBROOT" --dir "$CERTS" --days 30 --prod --email "$EMAIL" || echo "renew: some domains failed (non-fatal)"',...ee(v),'rm -f "$CERTS"/*.chain.crt','after=$(cat "$CERTS"/*.crt 2>/dev/null | sha256sum)',`[ "$before" = "$after" ] || systemctl restart ${ze}`].join(`
134
+ `),C=["[Unit]",`Description=Issue/renew rpx gateway TLS certs for ${x} (${E})`,`After=network-online.target ${ze}`,"Wants=network-online.target","","[Service]","Type=oneshot",`ExecStart=${l}`].join(`
135
+ `),S=["[Unit]",`Description=Daily rpx gateway TLS cert issuance/renewal for ${x}`,"","[Timer]","OnCalendar=*-*-* 03:30:00","RandomizedDelaySec=1h","Persistent=true","","[Install]","WantedBy=timers.target"].join(`
136
+ `);return[`mkdir -p ${n}`,...e.tenant?[]:[`(cd ${R} && ${u} add @stacksjs/tlsx@${i}) || true`],..._(l,b,"TS_CLOUD_RENEW_EOF"),`chmod +x ${l}`,..._(`/etc/systemd/system/${s}`,C,"TS_CLOUD_RENEW_SVC_EOF"),..._(`/etc/systemd/system/${w}`,S,"TS_CLOUD_RENEW_TIMER_EOF"),"systemctl daemon-reload",`systemctl enable --now ${w} || true`,`${l} || true`]}function G(e){let{config:t,proxy:r}=e,n=e.bunBin??"/usr/local/bin/bun",o=r.version??"latest",u=t.productionCerts.certsDir,i=(e.slug||"app").replace(/[^a-z0-9._-]+/gi,"-"),c=D(t,{slug:i}),f=J(z,u);if(e.tenant)return["set -euo pipefail",`if [ ! -x ${yt} ] || [ ! -d ${R}/node_modules/@stacksjs/rpx ]; then`,` echo "ts-cloud: no rpx gateway on this box. This project attaches to another project's compute, so it does not provision one - deploy the owning project first." >&2`," exit 1","fi",`mkdir -p ${z} ${u}`,`__tsc_rpx_before="$(sha256sum ${z}/${i}.json 2>/dev/null | cut -d' ' -f1 || true)"`,...T(`${z}/${i}.json`,c,"TS_CLOUD_RPX_FRAGMENT_EOF",{bunBin:n,preserveManagementDashboardRoutes:e.preserveManagementDashboardRoutes}),`__tsc_rpx_after="$(sha256sum ${z}/${i}.json 2>/dev/null | cut -d' ' -f1 || true)"`,`if [ "$__tsc_rpx_before" != "$__tsc_rpx_after" ] || ! systemctl is-active --quiet ${ze}; then`,` systemctl restart ${ze}`,"else",` echo "[ts-cloud] rpx routes for ${i} unchanged - leaving the shared gateway alone"`,"fi",...P(e)];let a=[`Environment=RPX_UPSTREAM_TIMEOUT=${r.upstreamTimeout??60}`];if(typeof r.maxUpstreamConns==="number")a.push(`Environment=RPX_MAX_UPSTREAM_CONNS=${r.maxUpstreamConns}`);let p=e.profile==="raspberry-pi"?Q:Z,x=r.memoryHigh??p.high,l=r.memoryMax??p.max;return["set -euo pipefail",`mkdir -p ${so} ${z} ${u} ${R}`,`rm -rf ${R}.next ${R}.prev`,`mkdir -p ${R}.next`,`(cd ${R}.next && ${n} add @stacksjs/rpx@${o})`,`mv ${R} ${R}.prev`,`mv ${R}.next ${R}`,`rm -rf ${R}.prev`,`ln -sfn ${R}/node_modules ${so}/node_modules`,...T(`${z}/${i}.json`,c,"TS_CLOUD_RPX_FRAGMENT_EOF",{bunBin:n,preserveManagementDashboardRoutes:e.preserveManagementDashboardRoutes}),..._(cp,f,"TS_CLOUD_RPX_EOF"),`${n} build --production --compile --outfile ${yt}.next ${cp}`,`chmod 0755 ${yt}.next`,`mv -f ${yt}.next ${yt}`,..._(`/etc/systemd/system/${ze}`,["[Unit]","Description=rpx reverse-proxy gateway (managed by ts-cloud)","After=network.target network-online.target","Wants=network-online.target","","[Service]","Type=simple",`ExecStart=${yt}`,`WorkingDirectory=${R}`,"Environment=BUN_INSTALL=/root/.bun","Environment=APP_ENV=production","Environment=NODE_ENV=production",...a,"MemoryAccounting=true",`MemoryHigh=${x}`,`MemoryMax=${l}`,"CPUWeight=500","IOWeight=500","OOMPolicy=stop","Restart=always","RestartSec=5","StartLimitIntervalSec=120","StartLimitBurst=5",`ExecStartPre=/bin/sh -c 'for p in 80 443; do fuser -k -n tcp "$p" 2>/dev/null || true; done; sleep 1'`,"LimitNOFILE=1048576","AmbientCapabilities=CAP_NET_BIND_SERVICE","","[Install]","WantedBy=multi-user.target"].join(`
137
+ `),"TS_CLOUD_RPX_UNIT_EOF"),"systemctl daemon-reload","systemctl disable --now bun-gateway.service 2>/dev/null || true","systemctl disable --now bun-gateway-renew.timer bun-gateway-renew.service 2>/dev/null || true","rm -f /etc/systemd/system/bun-gateway-renew.timer /etc/systemd/system/bun-gateway-renew.service","systemctl disable --now ts-cloud-nginx.service 2>/dev/null || true",`for timer in /etc/systemd/system/rpx-cert-renew-*.timer; do [ -e "$timer" ] || continue; unit="$(basename "$timer")"; tenant="\${unit#rpx-cert-renew-}"; tenant="\${tenant%.timer}"; [ -f "${z}/$tenant.json" ] && continue; systemctl disable --now "$unit" 2>/dev/null || true; rm -f "$timer" "/etc/systemd/system/rpx-cert-renew-$tenant.service" "${so}/renew-certs-$tenant.sh"; done`,`systemctl enable ${ze}`,`systemctl restart ${ze}`,...P(e)]}function ke(e){let t=(e.slug||"app").replace(/[^a-z0-9._-]+/gi,"-"),r=D(e.config,{slug:t});return["set -euo pipefail",`mkdir -p ${z}`,...T(`${z}/${t}.json`,r,"TS_CLOUD_RPX_FRAGMENT_EOF",{bunBin:"/usr/local/bin/bun",preserveManagementDashboardRoutes:e.preserveManagementDashboardRoutes}),`systemctl restart ${ze}`]}
138
+ export{to,ro,no,io,Yc,op,ap,Uh,Zc,B,Xt,fI,j,so,R,cp,yt,ze,z,ed,td,G,ke};
@@ -1,2 +1,2 @@
1
- import{n}from"./chunk-2sc0s7pc.js";import{f}from"./chunk-r3m1fjd4.js";class h{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new n(void 0,{profile:t})}async createStack(e){let t={Action:"CreateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(e.parameters)e.parameters.forEach((a,r)=>{t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});if(e.timeoutInMinutes)t.TimeoutInMinutes=e.timeoutInMinutes;if(e.onFailure)t.OnFailure=e.onFailure;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.CreateStackResult?.StackId}}async updateStack(e){let t={Action:"UpdateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((a,r)=>{if(t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,a.UsePreviousValue)t[`Parameters.member.${r+1}.UsePreviousValue`]="true";else t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.UpdateStackResult?.StackId}}async deleteStack(e,t,s){let a={Action:"DeleteStack",StackName:e,Version:"2010-05-15"};if(t)a.RoleARN=t;if(s&&s.length>0)s.forEach((r,u)=>{a[`RetainResources.member.${u+1}`]=r});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(a).toString()})}async describeStacks(e={}){let t={Action:"DescribeStacks",Version:"2010-05-15"};if(e.stackName)t.StackName=e.stackName;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{Stacks:this.parseStacksResponse(s)}}async describeStackEvents(e){let t={Action:"DescribeStackEvents",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackEvents:this.parseStackEvents(s)}}async listStackResources(e){let t={Action:"ListStackResources",StackName:e,Version:"2010-05-15"},a=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,r=[];if(a)r=Array.isArray(a)?a:[a];return{StackResourceSummaries:r}}async waitForStack(e,t){let s={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},a=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],r=s[t],u=360,i=0;while(i<360)try{let c=await this.describeStacks({stackName:e});if(c.Stacks.length===0){if(t==="stack-delete-complete")return;if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack not visible yet`);await new Promise((m)=>setTimeout(m,2000)),i++;continue}let o=c.Stacks[0];if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Status = ${o.StackStatus}${o.StackStatusReason?` (${o.StackStatusReason})`:""}`);if(r.includes(o.StackStatus))return;if((t==="stack-create-complete"||t==="stack-update-complete")&&(o.StackStatus==="DELETE_IN_PROGRESS"||o.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let m="";try{let S=await this.describeStackEvents(e);console.log("[waitForStack] Stack events (most recent first):");for(let k of S.StackEvents.slice(0,15))if(k.ResourceStatus.includes("FAILED")||k.ResourceStatusReason){if(console.log(` ${k.LogicalResourceId}: ${k.ResourceStatus} - ${k.ResourceStatusReason||"No reason provided"}`),k.ResourceStatus.includes("FAILED")&&k.ResourceStatusReason&&!m)m=k.ResourceStatusReason}}catch{}let l=m||o.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${l}`)}if(o.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let m=Error("Stack deletion failed - may have resources that need to be retained");throw m.code="DELETE_FAILED",m.stackStatus=o.StackStatus,m.statusReason=o.StackStatusReason,m}if(a.includes(o.StackStatus))throw Error(`Stack reached failure status: ${o.StackStatus}`);await new Promise((m)=>setTimeout(m,5000)),i++}catch(c){if(t==="stack-delete-complete"&&c.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&c.message?.includes("does not exist")){if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack does not exist (error), retrying...`);await new Promise((o)=>setTimeout(o,2000)),i++;continue}throw console.log(`[waitForStack] Unexpected error: ${c.message}`),c}throw console.log(`[waitForStack] Timeout after ${i} attempts`),Error(`Timeout waiting for stack to reach ${t}`)}async validateTemplate(e){let t={Action:"ValidateTemplate",TemplateBody:e,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()})}async listStacks(e){let t={Action:"ListStacks",Version:"2010-05-15"};if(e)e.forEach((c,o)=>{t[`StackStatusFilter.member.${o+1}`]=c});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=s.ListStacksResponse||s,r=a.ListStacksResult||a,u=r.StackSummaries?.member||r.StackSummaries||[];return{StackSummaries:(Array.isArray(u)?u:u?[u]:[]).map((c)=>({StackId:c.StackId||"",StackName:c.StackName||"",TemplateDescription:c.TemplateDescription,CreationTime:c.CreationTime||"",LastUpdatedTime:c.LastUpdatedTime,DeletionTime:c.DeletionTime,StackStatus:c.StackStatus||""}))}}async createChangeSet(e){let t={Action:"CreateChangeSet",StackName:e.stackName,ChangeSetName:e.changeSetName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((r,u)=>{t[`Parameters.member.${u+1}.ParameterKey`]=r.ParameterKey,t[`Parameters.member.${u+1}.ParameterValue`]=r.ParameterValue});if(e.capabilities)e.capabilities.forEach((r,u)=>{t[`Capabilities.member.${u+1}`]=r});if(e.changeSetType)t.ChangeSetType=e.changeSetType;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=f(s,"CreateChangeSet");return{Id:a?.Id,StackId:a?.StackId}}async describeChangeSet(e,t){let s={Action:"DescribeChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async executeChangeSet(e,t){let s={Action:"ExecuteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async deleteChangeSet(e,t){let s={Action:"DeleteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async getStackOutputs(e){let t=await this.describeStacks({stackName:e});if(!t.Stacks||t.Stacks.length===0)throw Error(`Stack ${e} not found`);let s=t.Stacks[0],a={};if(s.Outputs)for(let r of s.Outputs)a[r.OutputKey]=r.OutputValue;return a}async getTemplate(e){let t={Action:"GetTemplate",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{TemplateBody:s?.GetTemplateResult?.TemplateBody||s?.TemplateBody||""}}parseStacksResponse(e){let t=[],s=e?.DescribeStacksResult?.Stacks?.member||e?.Stacks?.member||e?.Stacks||e;if(s&&!Array.isArray(s))s=[s];if(Array.isArray(s)){for(let a of s)if(a.StackId||a.StackName){let r;if(a.Outputs?.member)r=(Array.isArray(a.Outputs.member)?a.Outputs.member:[a.Outputs.member]).map((i)=>({OutputKey:i.OutputKey,OutputValue:i.OutputValue,Description:i.Description,ExportName:i.ExportName}));t.push({StackId:a.StackId,StackName:a.StackName,StackStatus:a.StackStatus,CreationTime:a.CreationTime,LastUpdatedTime:a.LastUpdatedTime,StackStatusReason:a.StackStatusReason,Outputs:r})}}else if(e.StackId)t.push({StackId:e.StackId,StackName:e.StackName,StackStatus:e.StackStatus,CreationTime:e.CreationTime,LastUpdatedTime:e.LastUpdatedTime});return t}parseStackEvents(e){let t=[],s=e?.DescribeStackEventsResult?.StackEvents?.member||e?.StackEvents?.member||e?.StackEvents||[];if(s&&!Array.isArray(s))s=[s];for(let a of s)if(a.LogicalResourceId)t.push({Timestamp:a.Timestamp,ResourceType:a.ResourceType,LogicalResourceId:a.LogicalResourceId,ResourceStatus:a.ResourceStatus,ResourceStatusReason:a.ResourceStatusReason});return t}async waitForStackWithProgress(e,t,s){let a={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},r=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],u=a[t],i=360,c=0,o=new Set;while(c<360)try{if(s)try{let k=[...(await this.describeStackEvents(e)).StackEvents||[]].reverse();for(let d of k){let g=`${d.LogicalResourceId}-${d.ResourceStatus}-${d.Timestamp}`;if(!o.has(g))o.add(g),s({resourceId:d.LogicalResourceId,resourceType:d.ResourceType,status:d.ResourceStatus,reason:d.ResourceStatusReason,timestamp:d.Timestamp})}}catch{}let m=await this.describeStacks({stackName:e});if(m.Stacks.length===0){if(t==="stack-delete-complete")return;await new Promise((S)=>setTimeout(S,2000)),c++;continue}let l=m.Stacks[0];if(u.includes(l.StackStatus))return;if(l.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let S=Error("Stack deletion failed - may have resources that need to be retained");throw S.code="DELETE_FAILED",S.stackStatus=l.StackStatus,S.statusReason=l.StackStatusReason,S}if(r.includes(l.StackStatus))throw Error(`Stack reached failure status: ${l.StackStatus}`);await new Promise((S)=>setTimeout(S,3000)),c++}catch(m){if(t==="stack-delete-complete"&&m.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&m.message?.includes("does not exist")){await new Promise((l)=>setTimeout(l,2000)),c++;continue}throw m}throw Error(`Timeout waiting for stack to reach ${t}`)}async waitForStackComplete(e,t=120,s=5000){let a=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],r=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let u=0;u<t;u++)try{let i=await this.describeStacks({stackName:e});if(i.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let c=i.Stacks[0],o=c.StackStatus;if(a.includes(o))return{success:!0,status:o};if(r.includes(o))return{success:!1,status:o,reason:c.StackStatusReason};await new Promise((m)=>setTimeout(m,s))}catch(i){if(i.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw i}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}
1
+ import{n}from"./chunk-ca191b00.js";import{f}from"./chunk-9ggg2ktx.js";class h{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new n(void 0,{profile:t})}async createStack(e){let t={Action:"CreateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(e.parameters)e.parameters.forEach((a,r)=>{t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});if(e.timeoutInMinutes)t.TimeoutInMinutes=e.timeoutInMinutes;if(e.onFailure)t.OnFailure=e.onFailure;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.CreateStackResult?.StackId}}async updateStack(e){let t={Action:"UpdateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((a,r)=>{if(t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,a.UsePreviousValue)t[`Parameters.member.${r+1}.UsePreviousValue`]="true";else t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.UpdateStackResult?.StackId}}async deleteStack(e,t,s){let a={Action:"DeleteStack",StackName:e,Version:"2010-05-15"};if(t)a.RoleARN=t;if(s&&s.length>0)s.forEach((r,u)=>{a[`RetainResources.member.${u+1}`]=r});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(a).toString()})}async describeStacks(e={}){let t={Action:"DescribeStacks",Version:"2010-05-15"};if(e.stackName)t.StackName=e.stackName;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{Stacks:this.parseStacksResponse(s)}}async describeStackEvents(e){let t={Action:"DescribeStackEvents",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackEvents:this.parseStackEvents(s)}}async listStackResources(e){let t={Action:"ListStackResources",StackName:e,Version:"2010-05-15"},a=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,r=[];if(a)r=Array.isArray(a)?a:[a];return{StackResourceSummaries:r}}async waitForStack(e,t){let s={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},a=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],r=s[t],u=360,i=0;while(i<360)try{let c=await this.describeStacks({stackName:e});if(c.Stacks.length===0){if(t==="stack-delete-complete")return;if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack not visible yet`);await new Promise((m)=>setTimeout(m,2000)),i++;continue}let o=c.Stacks[0];if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Status = ${o.StackStatus}${o.StackStatusReason?` (${o.StackStatusReason})`:""}`);if(r.includes(o.StackStatus))return;if((t==="stack-create-complete"||t==="stack-update-complete")&&(o.StackStatus==="DELETE_IN_PROGRESS"||o.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let m="";try{let S=await this.describeStackEvents(e);console.log("[waitForStack] Stack events (most recent first):");for(let k of S.StackEvents.slice(0,15))if(k.ResourceStatus.includes("FAILED")||k.ResourceStatusReason){if(console.log(` ${k.LogicalResourceId}: ${k.ResourceStatus} - ${k.ResourceStatusReason||"No reason provided"}`),k.ResourceStatus.includes("FAILED")&&k.ResourceStatusReason&&!m)m=k.ResourceStatusReason}}catch{}let l=m||o.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${l}`)}if(o.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let m=Error("Stack deletion failed - may have resources that need to be retained");throw m.code="DELETE_FAILED",m.stackStatus=o.StackStatus,m.statusReason=o.StackStatusReason,m}if(a.includes(o.StackStatus))throw Error(`Stack reached failure status: ${o.StackStatus}`);await new Promise((m)=>setTimeout(m,5000)),i++}catch(c){if(t==="stack-delete-complete"&&c.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&c.message?.includes("does not exist")){if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack does not exist (error), retrying...`);await new Promise((o)=>setTimeout(o,2000)),i++;continue}throw console.log(`[waitForStack] Unexpected error: ${c.message}`),c}throw console.log(`[waitForStack] Timeout after ${i} attempts`),Error(`Timeout waiting for stack to reach ${t}`)}async validateTemplate(e){let t={Action:"ValidateTemplate",TemplateBody:e,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()})}async listStacks(e){let t={Action:"ListStacks",Version:"2010-05-15"};if(e)e.forEach((c,o)=>{t[`StackStatusFilter.member.${o+1}`]=c});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=s.ListStacksResponse||s,r=a.ListStacksResult||a,u=r.StackSummaries?.member||r.StackSummaries||[];return{StackSummaries:(Array.isArray(u)?u:u?[u]:[]).map((c)=>({StackId:c.StackId||"",StackName:c.StackName||"",TemplateDescription:c.TemplateDescription,CreationTime:c.CreationTime||"",LastUpdatedTime:c.LastUpdatedTime,DeletionTime:c.DeletionTime,StackStatus:c.StackStatus||""}))}}async createChangeSet(e){let t={Action:"CreateChangeSet",StackName:e.stackName,ChangeSetName:e.changeSetName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((r,u)=>{t[`Parameters.member.${u+1}.ParameterKey`]=r.ParameterKey,t[`Parameters.member.${u+1}.ParameterValue`]=r.ParameterValue});if(e.capabilities)e.capabilities.forEach((r,u)=>{t[`Capabilities.member.${u+1}`]=r});if(e.changeSetType)t.ChangeSetType=e.changeSetType;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=f(s,"CreateChangeSet");return{Id:a?.Id,StackId:a?.StackId}}async describeChangeSet(e,t){let s={Action:"DescribeChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async executeChangeSet(e,t){let s={Action:"ExecuteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async deleteChangeSet(e,t){let s={Action:"DeleteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async getStackOutputs(e){let t=await this.describeStacks({stackName:e});if(!t.Stacks||t.Stacks.length===0)throw Error(`Stack ${e} not found`);let s=t.Stacks[0],a={};if(s.Outputs)for(let r of s.Outputs)a[r.OutputKey]=r.OutputValue;return a}async getTemplate(e){let t={Action:"GetTemplate",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{TemplateBody:s?.GetTemplateResult?.TemplateBody||s?.TemplateBody||""}}parseStacksResponse(e){let t=[],s=e?.DescribeStacksResult?.Stacks?.member||e?.Stacks?.member||e?.Stacks||e;if(s&&!Array.isArray(s))s=[s];if(Array.isArray(s)){for(let a of s)if(a.StackId||a.StackName){let r;if(a.Outputs?.member)r=(Array.isArray(a.Outputs.member)?a.Outputs.member:[a.Outputs.member]).map((i)=>({OutputKey:i.OutputKey,OutputValue:i.OutputValue,Description:i.Description,ExportName:i.ExportName}));t.push({StackId:a.StackId,StackName:a.StackName,StackStatus:a.StackStatus,CreationTime:a.CreationTime,LastUpdatedTime:a.LastUpdatedTime,StackStatusReason:a.StackStatusReason,Outputs:r})}}else if(e.StackId)t.push({StackId:e.StackId,StackName:e.StackName,StackStatus:e.StackStatus,CreationTime:e.CreationTime,LastUpdatedTime:e.LastUpdatedTime});return t}parseStackEvents(e){let t=[],s=e?.DescribeStackEventsResult?.StackEvents?.member||e?.StackEvents?.member||e?.StackEvents||[];if(s&&!Array.isArray(s))s=[s];for(let a of s)if(a.LogicalResourceId)t.push({Timestamp:a.Timestamp,ResourceType:a.ResourceType,LogicalResourceId:a.LogicalResourceId,ResourceStatus:a.ResourceStatus,ResourceStatusReason:a.ResourceStatusReason});return t}async waitForStackWithProgress(e,t,s){let a={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},r=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],u=a[t],i=360,c=0,o=new Set;while(c<360)try{if(s)try{let k=[...(await this.describeStackEvents(e)).StackEvents||[]].reverse();for(let d of k){let g=`${d.LogicalResourceId}-${d.ResourceStatus}-${d.Timestamp}`;if(!o.has(g))o.add(g),s({resourceId:d.LogicalResourceId,resourceType:d.ResourceType,status:d.ResourceStatus,reason:d.ResourceStatusReason,timestamp:d.Timestamp})}}catch{}let m=await this.describeStacks({stackName:e});if(m.Stacks.length===0){if(t==="stack-delete-complete")return;await new Promise((S)=>setTimeout(S,2000)),c++;continue}let l=m.Stacks[0];if(u.includes(l.StackStatus))return;if(l.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let S=Error("Stack deletion failed - may have resources that need to be retained");throw S.code="DELETE_FAILED",S.stackStatus=l.StackStatus,S.statusReason=l.StackStatusReason,S}if(r.includes(l.StackStatus))throw Error(`Stack reached failure status: ${l.StackStatus}`);await new Promise((S)=>setTimeout(S,3000)),c++}catch(m){if(t==="stack-delete-complete"&&m.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&m.message?.includes("does not exist")){await new Promise((l)=>setTimeout(l,2000)),c++;continue}throw m}throw Error(`Timeout waiting for stack to reach ${t}`)}async waitForStackComplete(e,t=120,s=5000){let a=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],r=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let u=0;u<t;u++)try{let i=await this.describeStacks({stackName:e});if(i.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let c=i.Stacks[0],o=c.StackStatus;if(a.includes(o))return{success:!0,status:o};if(r.includes(o))return{success:!1,status:o,reason:c.StackStatusReason};await new Promise((m)=>setTimeout(m,s))}catch(i){if(i.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw i}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}
2
2
  export{h};
@@ -1 +1 @@
1
- import{An,yn,Nu,ds,ku,Bu,xu,xa,Ou,_u,Vf,Lu,C,$u,ls,xe,Mu,Fu,bS,Uu,Qu,Hu,Gu,Vu,qf,CS,ES,vS,jf,zf,TS,wS,Kf,Wf,RS,us,cr,Oa,Sn,In,dr,rt,Pt,gs,Jf,bn,qu,ju,_a,ms,En,fs,Wa}from"../chunk-bdv3gpzb.js";import{Ja,vn,Tn,hs,As,ys,Ss,Xa,Ya}from"../chunk-fpkpwbv3.js";import{Za}from"../chunk-vnarc5gc.js";import"../chunk-2pns2rkf.js";import"../chunk-nryh43p1.js";import"../chunk-yme6q7k4.js";import"../chunk-xzcpzxtj.js";import"../chunk-fh7apa5n.js";import"../chunk-gh0ghb21.js";import"../chunk-vb4t2r4r.js";import{lg,hc,ug,Ce,Ac,Un,gg,yc,Uc,Ks,Qc,Gt,fi,Ws}from"../chunk-7v7dwev4.js";import"../chunk-xxq1ygp9.js";import"../chunk-vjph4eh0.js";import"../chunk-jpdpr7k6.js";import"../chunk-2sc0s7pc.js";import{pt,tA,Kc,bi,Ci,Ei,Sp}from"../chunk-6mp1fyxe.js";import{_,_r,Lr,Wc,Ys,u,rA,Ip,bp,iI,sI}from"../chunk-jhtp3m31.js";import"../chunk-da62knsv.js";import"../chunk-kr8aeva1.js";import"../chunk-x0ep5ybv.js";export{tA as DEFAULT_SITE_PORT_RANGE,pt as HOST_SITES_DIR,Ac as IPV6_EXCLUDED_HOST_LABELS,Uc as MANAGEMENT_DASHBOARD_SITE,An as addSiteToCloudConfig,Sp as allocateSitePorts,RS as buildAndPushContainerImage,Za as buildAndPushServerlessImage,cr as buildFunctionEnv,Ci as buildHostSitePortsScript,Ws as buildManagementDashboardArtifact,Pt as buildServerTopology,gs as buildServerlessTopology,Jf as buildTopology,_a as collectEgressMetrics,lg as collectServerDnsDomains,Wf as createContainerImageDependencies,jf as createExistingStaticFullStackDependencies,qf as createStaticApiOriginDependencies,En as dashboardActions,Ks as dashboardCredentialsFile,Mu as dashboardPageRoutes,Gu as deleteFailoverReplicaBuckets,Xa as deleteStaticSite,TS as deployExistingStaticFullStack,Oa as deployServerlessApp,sI as deployShipsFiles,Vu as deploySite,CS as deployStaticApiOrigin,As as deployStaticSite,Ya as deployStaticSiteFull,vn as deployStaticSiteWithExternalDns,Tn as deployStaticSiteWithExternalDnsFull,qu as egressReportMetrics,C as ensureDashboardActor,Uu as ensureFailoverReplicaBuckets,fi as ensureManagementDashboard,wS as estimateExistingStaticFullStackMonthlyCost,vS as estimateStaticApiOriginMonthlyCost,ju as fetchEgressReport,zf as generateExistingStaticFullStackTemplate,Ja as generateExternalDnsStaticSiteTemplate,hs as generateStaticSiteTemplate,Qu as grantFailoverReplicaAccess,rA as hasComputeConfigured,Wc as hasProxyUpstream,Kf as hashContainerContext,Un as hostAcceptsIpv6,us as infraEnvFromOutputs,$u as initializeDashboardControlPlane,Ss as invalidateCache,_r as isPhpSite,xa as isValidHostname,Ce as normalizePublicIpv6,bi as occupiedHostPorts,Ei as parseHostSiteFragments,Kc as parseUpstreamPort,gg as reconcileAddressRecords,Sn as redeployServerlessApp,ug as removeAddressRecords,yn as removeSiteFromCloudConfig,hc as removeStaleServerAddressRecords,Ou as renderAliasesValue,xu as renderEnvValue,_u as renderRedirectsValue,Vf as renderSiteSnippet,ku as renderSslValue,Bu as renderStringValue,fs as resolveDashboardAction,Qc as resolveDashboardAuth,bn as resolveDashboardData,Fu as resolveLegacyDashboardRoute,Lr as resolveProxyUpstreams,Ys as resolveSiteDeployTarget,u as resolveSiteKind,Gt as resolveUiSource,In as rollbackServerlessApp,bS as routesForDashboard,rt as runRemoteCommand,ms as sanitizeCloudConfig,Hu as seedFailoverReplicas,Lu as setAttachToInCloudConfig,dr as setMaintenance,ds as setSitePropertyInCloudConfig,bp as shipsARelease,iI as shipsToBucket,_ as siteInstallBase,Wa as startLocalDashboardServer,ls as synchronizeDashboardUsers,xe as trackDashboardOperation,Nu as updateSiteInCloudConfig,ys as uploadStaticFiles,Ip as validateDeploymentConfig,yc as verifyAddressRecord,ES as verifyStaticApiOrigin};
1
+ import{Tn,wn,Fu,ps,Uu,Qu,Hu,Qa,Gu,Vu,th,qu,E,ju,ms,Me,zu,Ku,BS,Wu,Ju,Xu,Yu,Zu,rh,xS,OS,_S,nh,ih,LS,$S,sh,oh,MS,fs,Ar,Ha,Rn,Dn,yr,ct,Lt,hs,ah,Pn,eg,tg,Ga,ys,kn,Ss,nc}from"../chunk-53kyxata.js";import{ic,Bn,xn,Is,bs,Cs,Es,sc,oc}from"../chunk-8b2mxhcm.js";import{ac}from"../chunk-p101nhg2.js";import"../chunk-jytama4e.js";import"../chunk-0qgfe5ff.js";import"../chunk-0cz2s19h.js";import"../chunk-qcj3hkba.js";import"../chunk-4abbccq7.js";import"../chunk-m9r0a1v9.js";import"../chunk-jtvw9d4x.js";import{Sg,vc,Ig,De,Tc,Kn,bg,wc,zc,Xs,Kc,Jt,Si,Ys}from"../chunk-dw0cvqdr.js";import"../chunk-xgc6hskd.js";import"../chunk-thdfk76k.js";import"../chunk-zf5wdx6v.js";import"../chunk-j99nkav5.js";import"../chunk-ca191b00.js";import{It,gA,sd,Ti,wi,Ri,Np}from"../chunk-x4qye2rc.js";import{U,Gr,Vr,od,oo,d,pA,kp,Bp,hI,yI}from"../chunk-pz33w7gv.js";import"../chunk-6gnmrtp9.js";import"../chunk-prtvb2fh.js";import"../chunk-6m8p1n88.js";export{gA as DEFAULT_SITE_PORT_RANGE,It as HOST_SITES_DIR,Tc as IPV6_EXCLUDED_HOST_LABELS,zc as MANAGEMENT_DASHBOARD_SITE,Tn as addSiteToCloudConfig,Np as allocateSitePorts,MS as buildAndPushContainerImage,ac as buildAndPushServerlessImage,Ar as buildFunctionEnv,wi as buildHostSitePortsScript,Ys as buildManagementDashboardArtifact,Lt as buildServerTopology,hs as buildServerlessTopology,ah as buildTopology,Ga as collectEgressMetrics,Sg as collectServerDnsDomains,oh as createContainerImageDependencies,nh as createExistingStaticFullStackDependencies,rh as createStaticApiOriginDependencies,kn as dashboardActions,Xs as dashboardCredentialsFile,zu as dashboardPageRoutes,Yu as deleteFailoverReplicaBuckets,sc as deleteStaticSite,LS as deployExistingStaticFullStack,Ha as deployServerlessApp,yI as deployShipsFiles,Zu as deploySite,xS as deployStaticApiOrigin,bs as deployStaticSite,oc as deployStaticSiteFull,Bn as deployStaticSiteWithExternalDns,xn as deployStaticSiteWithExternalDnsFull,eg as egressReportMetrics,E as ensureDashboardActor,Wu as ensureFailoverReplicaBuckets,Si as ensureManagementDashboard,$S as estimateExistingStaticFullStackMonthlyCost,_S as estimateStaticApiOriginMonthlyCost,tg as fetchEgressReport,ih as generateExistingStaticFullStackTemplate,ic as generateExternalDnsStaticSiteTemplate,Is as generateStaticSiteTemplate,Ju as grantFailoverReplicaAccess,pA as hasComputeConfigured,od as hasProxyUpstream,sh as hashContainerContext,Kn as hostAcceptsIpv6,fs as infraEnvFromOutputs,ju as initializeDashboardControlPlane,Es as invalidateCache,Gr as isPhpSite,Qa as isValidHostname,De as normalizePublicIpv6,Ti as occupiedHostPorts,Ri as parseHostSiteFragments,sd as parseUpstreamPort,bg as reconcileAddressRecords,Rn as redeployServerlessApp,Ig as removeAddressRecords,wn as removeSiteFromCloudConfig,vc as removeStaleServerAddressRecords,Gu as renderAliasesValue,Hu as renderEnvValue,Vu as renderRedirectsValue,th as renderSiteSnippet,Uu as renderSslValue,Qu as renderStringValue,Ss as resolveDashboardAction,Kc as resolveDashboardAuth,Pn as resolveDashboardData,Ku as resolveLegacyDashboardRoute,Vr as resolveProxyUpstreams,oo as resolveSiteDeployTarget,d as resolveSiteKind,Jt as resolveUiSource,Dn as rollbackServerlessApp,BS as routesForDashboard,ct as runRemoteCommand,ys as sanitizeCloudConfig,Xu as seedFailoverReplicas,qu as setAttachToInCloudConfig,yr as setMaintenance,ps as setSitePropertyInCloudConfig,Bp as shipsARelease,hI as shipsToBucket,U as siteInstallBase,nc as startLocalDashboardServer,ms as synchronizeDashboardUsers,Me as trackDashboardOperation,Fu as updateSiteInCloudConfig,Cs as uploadStaticFiles,kp as validateDeploymentConfig,wc as verifyAddressRecord,OS as verifyStaticApiOrigin};
package/dist/dns/index.js CHANGED
@@ -1 +1 @@
1
- import{at,le,Me,M,Mt,Ln,Ds,Ps,hr,Ar,$n,yr,Ns,ks,Bs,xs,X,Os,_s,Ls,$s,ue,Ms,Fs,Us,D,mc,Mn,fc}from"../chunk-gh0ghb21.js";import"../chunk-vb4t2r4r.js";import"../chunk-2sc0s7pc.js";export{M as CloudflareProvider,Mn as DnsProviderFactory,Me as GoDaddyProvider,at as PROXIABLE_RECORD_TYPES,le as PorkbunProvider,X as Route53Provider,ue as UnifiedDnsValidator,Bs as applyDeclaredZoneSettings,Ls as applyZoneMigration,D as createDnsProvider,Fs as createGoDaddyValidator,Ms as createPorkbunValidator,Us as createRoute53Validator,yr as delegateZone,Ns as delegateZoneFromConfig,ks as describeDelegation,xs as describeZoneSettings,mc as detectDnsProvider,fc as dnsProviders,Os as exportRoute53Zone,hr as isNameserverRegistrar,Ar as isZoneHost,_s as planZoneMigration,Mt as policyTag,Ln as qualifyName,Ps as reconcileDeclaredRecords,Ds as resolveDeclaredRecords,$n as sameNameservers,$s as verifyZoneParity};
1
+ import{pt,he,Ge,H,qt,qn,Bs,xs,Tr,wr,jn,Rr,Os,_s,Ls,$s,ie,Ms,Fs,Us,Qs,Ae,Hs,Gs,Vs,k,Cc,zn,Ec}from"../chunk-m9r0a1v9.js";import"../chunk-jtvw9d4x.js";import"../chunk-ca191b00.js";export{H as CloudflareProvider,zn as DnsProviderFactory,Ge as GoDaddyProvider,pt as PROXIABLE_RECORD_TYPES,he as PorkbunProvider,ie as Route53Provider,Ae as UnifiedDnsValidator,Ls as applyDeclaredZoneSettings,Us as applyZoneMigration,k as createDnsProvider,Gs as createGoDaddyValidator,Hs as createPorkbunValidator,Vs as createRoute53Validator,Rr as delegateZone,Os as delegateZoneFromConfig,_s as describeDelegation,$s as describeZoneSettings,Cc as detectDnsProvider,Ec as dnsProviders,Ms as exportRoute53Zone,Tr as isNameserverRegistrar,wr as isZoneHost,Fs as planZoneMigration,qt as policyTag,qn as qualifyName,xs as reconcileDeclaredRecords,Bs as resolveDeclaredRecords,jn as sameNameservers,Qs as verifyZoneParity};
@@ -24,13 +24,13 @@ export interface AwsIngressRule {
24
24
  * Ingress rules for a PHP/app box: SSH (deploy fallback), HTTP, HTTPS, and any
25
25
  * extra app ports any site declares. Deploys themselves run over SSM.
26
26
  */
27
- export declare function awsComputeIngressRules(config: CloudConfig): AwsIngressRule[];
27
+ export declare function awsComputeIngressRules(config: CloudConfig, environment?: string): AwsIngressRule[];
28
28
  /**
29
29
  * Build the EC2 UserData (raw bash, not yet base64) from the shared Ubuntu
30
30
  * bootstrap — the exact same recipe Hetzner uses. Honors a baked golden image
31
31
  * (`compute.bakedImage`) by skipping the install-heavy steps.
32
32
  */
33
- export declare function buildAwsUserData(config: CloudConfig): string;
33
+ export declare function buildAwsUserData(config: CloudConfig, environment?: string): string;
34
34
  /** Base64-encode UserData for the EC2 RunInstances API. */
35
35
  export declare function encodeUserData(userData: string): string;
36
36
  /**
@@ -1 +1 @@
1
- import{Qn,Ft,Ir,Ut,Hn,Gn,Vn,qn,hg,Gs,Y,Er,ph,jn,Sc,Ee,ve,Fe,x,vr,zn,Tr,pe,Ic,Kn,bc,Wn,Cc,wr,mh,fh,Sg,Ig,hh,Ah,yh,Rr,Jn,bg,Vs,Xn,Yn,Zn,ei,ti,Ec,vc,Dr,wc,Ue,Z,Rc,ct,Qe,He,dt,Te,qs,Dc,Cg,Eg,Pc,vg,lt,ri,Nc,Tg,wg,kc,Pr,we,Bc,Rg,Dg,js,ni,ut,Pg,Ng,kg,Bg,xg,Og,_g,Lg,$g,ii,si,oi,ai,ci,di,li,Mg,Fg,Nr,O,zs,Ug,Qg,Hg,xc,Gg,Vg,Sh,Oc,Ih,bh,qg,jg,Ch,Eh,vh,_c,zg,Th,wh,Rh,ui,gi,pi,mi,Lc,$c,Mc,Fc,Dh,Js,Hc,hi,Gc,Kg,Wg,Jg,Ph}from"../chunk-7v7dwev4.js";import"../chunk-xxq1ygp9.js";import"../chunk-vjph4eh0.js";import"../chunk-jpdpr7k6.js";import"../chunk-2sc0s7pc.js";import"../chunk-jhtp3m31.js";import"../chunk-kr8aeva1.js";import"../chunk-x0ep5ybv.js";export{Fc as AwsBoxProvisioner,vr as AwsDriver,Hg as BOOT_PARTITION_LABEL,zs as CloudDriverFactory,Ig as DEFAULT_HOST_CLEANUP_ESCALATED,Ah as DEFAULT_HOST_CLEANUP_HIGH_WATER_PERCENT,hh as DEFAULT_HOST_CLEANUP_LOW_WATER_PERCENT,Sg as DEFAULT_HOST_CLEANUP_RETENTION,yh as DEFAULT_HOST_CLEANUP_SCHEDULE,Gn as DEFAULT_RPX_CERTS_DIR,Qg as FIRST_BOOT_SCRIPT_PATH,wr as HOST_ARTIFACT_CACHE_DIR,mh as HOST_CLEANUP_SCRIPT_PATH,fh as HOST_CLEANUP_UNIT,Mc as HetznerBoxProvisioner,Dr as HetznerClient,Te as HetznerDriver,Rc as LEGACY_DRIVER_STATE_DIR,qs as LocalBoxDriver,Wg as MANAGED_CACHE_POLICY_DISABLED,Kg as MANAGED_CACHE_POLICY_OPTIMIZED,Jg as MANAGED_ORIGIN_REQUEST_POLICY_ALL_VIEWER,Dg as RASPBERRY_PI_DEFAULT_SWAP_GB,Cc as REMOTE_SCRIPT_RUNNER,jn as RPX_DIR,Sc as RPX_LAUNCHER_PATH,Ee as RPX_SERVICE_NAME,Bc as SSH_BOOTSTRAP_MARKER_DIR,we as SSH_BOOTSTRAP_VERSION,ut as SSH_DEFAULTS,li as SSH_DEPLOY_STORAGE_PATH,Cg as SSH_INSECURE_HOST_KEY_OPTS,Eg as SSH_KEEPALIVE_OPTS,si as SSH_PREFLIGHT_SCRIPT,Mg as SSH_SKIP_BOOTSTRAP_ENV,Nr as SshDriver,Pr as SystemSshTransport,Lc as UBUNTU_2404_AMI_PARAM,Rh as acquireResizeLock,Ch as applyHetznerHostOptimization,js as assertArchSupported,Fg as assertSshComputeConfig,Ec as buildAwsArtifactFetch,$c as buildBoxUserData,Ph as buildCloudFrontOriginConfig,xc as buildCloudInitFirstBoot,jg as buildHetznerHostOptimizationScript,Xn as buildHostCleanupDeployScript,bg as buildHostCleanupExecutable,Vs as buildHostCleanupInstallScript,Jn as buildHostCleanupScript,vc as buildLocalArtifactFetch,Y as buildRpxConfig,Fe as buildRpxFragmentRefreshScript,Er as buildRpxLbConfig,ve as buildRpxProvisionScript,vg as buildScpArgsFor,Zn as buildSiteDeployScript,zn as buildSshArgs,Pc as buildSshArgsFor,ni as buildSshBootstrapScript,ei as buildStaticSiteDeployScript,Ug as cloudDrivers,Eh as collectHetznerHostOptimizationReport,Oc as collectHetznerResizeManifest,Dh as createBoxProvisioner,O as createCloudDriver,Hc as deployAllComputeSites,Js as deploySiteRelease,Gs as deriveRouteId,Qn as describeScriptSyntaxError,ct as driverStateDir,Qe as driverStatePath,gi as ensureFirewall,pi as ensureServer,ui as ensureSshKey,ai as evaluatePreflight,Sh as executeHetznerServerResize,wg as findKnownHostKey,di as formatPreflightFindings,Ft as formatSshFailure,qn as gatewayHostnames,x as generateUbuntuAppCloudInit,Vn as hasAutoWwwVariant,Dc as isBoxMode,Vg as isHetznerCapacityError,Hn as isLocalDatabase,Tg as knownHostsLine,Nc as knownHostsToken,hg as normalizeRoutePath,Ue as normalizeSshPublicKey,oi as parsePreflightFacts,Gg as planHetznerServerResize,ci as preflightFailed,Ih as prepareHetznerResize,He as readDriverState,Th as readResizeCheckpoint,ti as releaseTarballTmpPath,hi as reloadRpxGateway,Wn as remoteScriptRunner,ph as renderRpxLauncher,Gc as renewRpxCertificates,_c as resizeCheckpointPath,zg as resizeLockPath,Yn as resolveExecStart,wc as resolveHetznerApiToken,qg as resolveHetznerHostOptimizationPlan,Rr as resolveHostCleanupConfig,xg as resolveSshHostKeyPolicy,Pg as resolveSshHosts,$g as resolveSshLan,kg as resolveSshPort,Bg as resolveSshPrivateKeyPath,_g as resolveSshProfile,Lg as resolveSshPublicIp,ii as resolveSshSettings,Og as resolveSshSudo,Ng as resolveSshUser,ri as scanHostKey,Ic as scpUpload,mi as serverPublicIpv4,Rg as sshBootstrapMarkerPath,Tr as sshExec,pe as sshExecOrThrow,lt as sshHostKeyFingerprint,kc as sshKnownHostsPath,Ut as summarizeRemoteFailures,Ir as surfaceRemoteNotices,vh as verifyHetznerHostOptimization,bh as verifyHetznerResize,bc as waitForCloudInit,Kn as waitForSsh,Z as wrapCloudInitUserData,dt as writeDriverState,wh as writeResizeCheckpoint};
1
+ import{Wn,jt,Pr,zt,Jn,M,Br,Xn,xr,Se,Rc,Yn,Dc,Zn,Pc,Or,vh,Th,Rg,Dg,wh,Rh,Dh,_r,ei,Pg,zs,ti,ri,ni,ii,si,Nc,kc,Lr,xc,Ve,se,Oc,mt,qe,je,ft,Pe,Ks,_c,Ng,kg,Lc,Bg,ht,oi,$c,xg,Og,Mc,$r,Ne,Fc,_g,Lg,Ws,ai,At,$g,Mg,Fg,Ug,Qg,Hg,Gg,Vg,qg,ci,di,li,ui,gi,pi,mi,jg,zg,Mr,F,Js,Kg,Wg,Jg,Uc,Xg,Yg,Ph,Qc,Nh,kh,Zg,ep,Bh,xh,Oh,Hc,tp,_h,Lh,$h,fi,hi,Ai,yi,Gc,Vc,qc,jc,Mh,Zs,Wc,Ii,Jc,rp,np,ip,Fh}from"../chunk-dw0cvqdr.js";import{to,no,io,Uh,Zc,B,Xt,fI,so,cp,ze,G,ke}from"../chunk-xgc6hskd.js";import"../chunk-thdfk76k.js";import"../chunk-zf5wdx6v.js";import"../chunk-j99nkav5.js";import"../chunk-ca191b00.js";import"../chunk-pz33w7gv.js";import"../chunk-prtvb2fh.js";import"../chunk-6m8p1n88.js";export{jc as AwsBoxProvisioner,Br as AwsDriver,Jg as BOOT_PARTITION_LABEL,Js as CloudDriverFactory,Dg as DEFAULT_HOST_CLEANUP_ESCALATED,Rh as DEFAULT_HOST_CLEANUP_HIGH_WATER_PERCENT,wh as DEFAULT_HOST_CLEANUP_LOW_WATER_PERCENT,Rg as DEFAULT_HOST_CLEANUP_RETENTION,Dh as DEFAULT_HOST_CLEANUP_SCHEDULE,to as DEFAULT_RPX_CERTS_DIR,Wg as FIRST_BOOT_SCRIPT_PATH,Or as HOST_ARTIFACT_CACHE_DIR,vh as HOST_CLEANUP_SCRIPT_PATH,Th as HOST_CLEANUP_UNIT,qc as HetznerBoxProvisioner,Lr as HetznerClient,Pe as HetznerDriver,Oc as LEGACY_DRIVER_STATE_DIR,Ks as LocalBoxDriver,np as MANAGED_CACHE_POLICY_DISABLED,rp as MANAGED_CACHE_POLICY_OPTIMIZED,ip as MANAGED_ORIGIN_REQUEST_POLICY_ALL_VIEWER,Lg as RASPBERRY_PI_DEFAULT_SWAP_GB,Pc as REMOTE_SCRIPT_RUNNER,so as RPX_DIR,cp as RPX_LAUNCHER_PATH,ze as RPX_SERVICE_NAME,Fc as SSH_BOOTSTRAP_MARKER_DIR,Ne as SSH_BOOTSTRAP_VERSION,At as SSH_DEFAULTS,mi as SSH_DEPLOY_STORAGE_PATH,Ng as SSH_INSECURE_HOST_KEY_OPTS,kg as SSH_KEEPALIVE_OPTS,di as SSH_PREFLIGHT_SCRIPT,jg as SSH_SKIP_BOOTSTRAP_ENV,Mr as SshDriver,$r as SystemSshTransport,Gc as UBUNTU_2404_AMI_PARAM,$h as acquireResizeLock,Bh as applyHetznerHostOptimization,Ws as assertArchSupported,zg as assertSshComputeConfig,Nc as buildAwsArtifactFetch,Vc as buildBoxUserData,Fh as buildCloudFrontOriginConfig,Uc as buildCloudInitFirstBoot,ep as buildHetznerHostOptimizationScript,ti as buildHostCleanupDeployScript,Pg as buildHostCleanupExecutable,zs as buildHostCleanupInstallScript,ei as buildHostCleanupScript,kc as buildLocalArtifactFetch,B as buildRpxConfig,ke as buildRpxFragmentRefreshScript,Xt as buildRpxLbConfig,G as buildRpxProvisionScript,Bg as buildScpArgsFor,ni as buildSiteDeployScript,Xn as buildSshArgs,Lc as buildSshArgsFor,ai as buildSshBootstrapScript,ii as buildStaticSiteDeployScript,Kg as cloudDrivers,xh as collectHetznerHostOptimizationReport,Qc as collectHetznerResizeManifest,Mh as createBoxProvisioner,F as createCloudDriver,Wc as deployAllComputeSites,Zs as deploySiteRelease,Zc as deriveRouteId,Wn as describeScriptSyntaxError,mt as driverStateDir,qe as driverStatePath,hi as ensureFirewall,Ai as ensureServer,fi as ensureSshKey,ui as evaluatePreflight,Ph as executeHetznerServerResize,Og as findKnownHostKey,pi as formatPreflightFindings,jt as formatSshFailure,io as gatewayHostnames,M as generateUbuntuAppCloudInit,no as hasAutoWwwVariant,_c as isBoxMode,Yg as isHetznerCapacityError,Jn as isLocalDatabase,xg as knownHostsLine,$c as knownHostsToken,Uh as normalizeRoutePath,Ve as normalizeSshPublicKey,li as parsePreflightFacts,Xg as planHetznerServerResize,gi as preflightFailed,Nh as prepareHetznerResize,je as readDriverState,_h as readResizeCheckpoint,si as releaseTarballTmpPath,Ii as reloadRpxGateway,Zn as remoteScriptRunner,fI as renderRpxLauncher,Jc as renewRpxCertificates,Hc as resizeCheckpointPath,tp as resizeLockPath,ri as resolveExecStart,xc as resolveHetznerApiToken,Zg as resolveHetznerHostOptimizationPlan,_r as resolveHostCleanupConfig,Qg as resolveSshHostKeyPolicy,$g as resolveSshHosts,qg as resolveSshLan,Fg as resolveSshPort,Ug as resolveSshPrivateKeyPath,Gg as resolveSshProfile,Vg as resolveSshPublicIp,ci as resolveSshSettings,Hg as resolveSshSudo,Mg as resolveSshUser,oi as scanHostKey,Rc as scpUpload,yi as serverPublicIpv4,_g as sshBootstrapMarkerPath,xr as sshExec,Se as sshExecOrThrow,ht as sshHostKeyFingerprint,Mc as sshKnownHostsPath,zt as summarizeRemoteFailures,Pr as surfaceRemoteNotices,Oh as verifyHetznerHostOptimization,kh as verifyHetznerResize,Dc as waitForCloudInit,Yn as waitForSsh,se as wrapCloudInitUserData,ft as writeDriverState,Lh as writeResizeCheckpoint};
@@ -107,24 +107,8 @@ export declare function mailDnsRecords(mail: ResolvedMailService): MailDnsRecord
107
107
  * is now failing verification at their end.
108
108
  */
109
109
  export declare function buildDkimScript(mail: ResolvedMailService): string[];
110
- /**
111
- * Create the declared mailboxes.
112
- *
113
- * Both `create` and `change-password` run, unconditionally, and that is not
114
- * belt-and-braces. `mail user:local create` on an existing account prints
115
- * "already exists" and **exits 0**, so a `create || change-password` chain
116
- * would never reach the second command — an operator who rotated a password in
117
- * the config and redeployed would get a box that kept the old one and reported
118
- * success. Running both means the declaration is the truth on every deploy.
119
- *
120
- * Each is tolerated failing so one bad account cannot abort a provision that
121
- * has already installed and started the server, and each runs as the service
122
- * account with the server's own `SMTP_DB_PATH` — as root it would create a
123
- * second database beside the one the server reads, and the accounts would
124
- * exist in a file nothing opens. That is also why the path comes from
125
- * `$TS_CLOUD_MAIL_DB` rather than being written in twice: see
126
- * {@link mailDbPath}.
127
- */
110
+ /** Create missing mailboxes without undoing users' password changes. Managed
111
+ * credentials explicitly opt into reconciliation on every deployment. */
128
112
  export declare function buildMailAccountScript(mail: ResolvedMailService): string[];
129
113
  /**
130
114
  * The whole provisioning sequence for the mail service.
@@ -19,7 +19,7 @@
19
19
  * It replaces the old Caddyfile generation — pantry/stacks use rpx (their own
20
20
  * tooling), so the gateway is rpx, not Caddy.
21
21
  */
22
- import type { CloudConfig, ComputeProxyConfig, RpxLoadBalancerConfig, SiteConfig, SiteRedirectConfig } from '@ts-cloud/core';
22
+ import type { CloudConfig, ComputeProxyConfig, ResolvedMailService, RpxLoadBalancerConfig, SiteConfig, SiteRedirectConfig } from '@ts-cloud/core';
23
23
  /** Default directory on the box that holds real per-domain TLS certs. */
24
24
  export declare const DEFAULT_RPX_CERTS_DIR = "/etc/rpx/certs";
25
25
  /**
@@ -298,6 +298,8 @@ export declare function isWildcardHost(host: string): boolean;
298
298
  */
299
299
  export declare function rpxGatewayJson(config: RpxGatewayConfig, extra?: Record<string, unknown>): string;
300
300
  export interface BuildRpxConfigOptions {
301
+ /** Managed mail adds its webmail hosts to this same route/certificate set. */
302
+ mail?: ResolvedMailService;
301
303
  /** Proxy config from `infrastructure.compute.proxy`. */
302
304
  proxy: ComputeProxyConfig;
303
305
  /** Directory static sites are shipped to. @default '/var/www' */