@stacksjs/ts-cloud 0.12.15 → 0.12.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/aws/index.js +1 -1
  2. package/dist/bin/chunk-005sxfmc.js +1 -0
  3. package/dist/bin/{chunk-pt2bz3kr.js → chunk-2shtky1g.js} +1 -1
  4. package/dist/bin/chunk-3zq0wkz2.js +1 -0
  5. package/dist/bin/chunk-4qzpqmhe.js +1 -0
  6. package/dist/bin/chunk-4vgbynq6.js +1 -0
  7. package/dist/bin/chunk-52wgrpe8.js +1 -0
  8. package/dist/bin/{chunk-sdwr2tnp.js → chunk-5qann9n2.js} +1 -1
  9. package/dist/bin/{chunk-gd4w6bht.js → chunk-6tty6sjf.js} +1 -1
  10. package/dist/bin/{chunk-ynr22ma8.js → chunk-7jwxgxxf.js} +1 -1
  11. package/dist/bin/{chunk-77qpn2m8.js → chunk-7xszcdqn.js} +1 -1
  12. package/dist/bin/{chunk-raj6j2j5.js → chunk-8sxb2rr0.js} +1 -1
  13. package/dist/bin/{chunk-7a7n6p2m.js → chunk-9jmnmhpy.js} +1 -1
  14. package/dist/bin/{chunk-x42gb7pq.js → chunk-9vrnrxay.js} +1 -1
  15. package/dist/bin/{chunk-9e22a51n.js → chunk-9wjgxjqp.js} +57 -57
  16. package/dist/bin/chunk-9yra64dd.js +1 -0
  17. package/dist/bin/{chunk-r1w08y38.js → chunk-a76krpa1.js} +1 -1
  18. package/dist/bin/{chunk-swete552.js → chunk-a8rn2wym.js} +5 -5
  19. package/dist/bin/{chunk-ng0949x3.js → chunk-b48j6k55.js} +1 -1
  20. package/dist/bin/{chunk-r1vtnn8w.js → chunk-be7rhw60.js} +3 -3
  21. package/dist/bin/chunk-bwvnfc74.js +1 -0
  22. package/dist/bin/chunk-cy4wwpnf.js +1 -0
  23. package/dist/bin/{chunk-s1j941z1.js → chunk-dvm4n8m8.js} +1 -1
  24. package/dist/bin/{chunk-5tsxt28g.js → chunk-dxfsq94k.js} +1 -1
  25. package/dist/bin/chunk-dy10cmt9.js +1 -0
  26. package/dist/bin/{chunk-zzsdhhmb.js → chunk-e3d9m062.js} +1 -1
  27. package/dist/bin/{chunk-kc2e193t.js → chunk-ebdybz7x.js} +61 -61
  28. package/dist/bin/chunk-fbe5kk6w.js +1 -0
  29. package/dist/bin/{chunk-yx1qgp1q.js → chunk-hzj5r6b7.js} +2 -2
  30. package/dist/bin/chunk-j3w462ep.js +1 -0
  31. package/dist/bin/{chunk-80zkjpfz.js → chunk-k3er0h4j.js} +1 -1
  32. package/dist/bin/chunk-k7w2ztw9.js +1 -0
  33. package/dist/bin/{chunk-dhxwmkhz.js → chunk-mcqkjhgp.js} +1 -1
  34. package/dist/bin/{chunk-w5hzt11d.js → chunk-mekcw1zn.js} +1 -1
  35. package/dist/bin/{chunk-7xvm2ygt.js → chunk-ndbtr4mb.js} +2 -2
  36. package/dist/bin/chunk-ntahmgqg.js +1 -0
  37. package/dist/bin/{chunk-57w9nsjk.js → chunk-p197a99s.js} +1 -1
  38. package/dist/bin/{chunk-vymg9ywg.js → chunk-pd8v6bpd.js} +1 -1
  39. package/dist/bin/{chunk-yhxpmk29.js → chunk-pthfzst7.js} +1 -1
  40. package/dist/bin/{chunk-n7eq4t9a.js → chunk-srw2jmh3.js} +1 -1
  41. package/dist/bin/chunk-t1eft7s7.js +1 -0
  42. package/dist/bin/{chunk-49sthm4q.js → chunk-t7seq21w.js} +1 -1
  43. package/dist/bin/chunk-t8n2961n.js +1 -0
  44. package/dist/bin/{chunk-pcyywgx7.js → chunk-tpjepvwa.js} +1 -1
  45. package/dist/bin/chunk-xvn07b0e.js +1 -0
  46. package/dist/bin/{chunk-8tbj9h2a.js → chunk-xyk8qe2c.js} +29 -29
  47. package/dist/bin/{chunk-4zbnwt9b.js → chunk-y1r1evt0.js} +1 -1
  48. package/dist/bin/{chunk-n8cwx54p.js → chunk-y24gfke7.js} +1 -1
  49. package/dist/bin/{chunk-vesvsvdy.js → chunk-zav02r6k.js} +1 -1
  50. package/dist/bin/{chunk-ejqhbj1h.js → chunk-zhpzxnpg.js} +1 -1
  51. package/dist/bin/{chunk-c51xp8f7.js → chunk-zs8bfer0.js} +1 -1
  52. package/dist/bin/cli.js +72 -72
  53. package/dist/bin/dashboard-server.js +1 -1
  54. package/dist/{chunk-x07tpsv0.js → chunk-1zz5n6q8.js} +2 -2
  55. package/dist/{chunk-cy6qh4ea.js → chunk-4ywy6dp5.js} +2 -2
  56. package/dist/{chunk-a6k322xc.js → chunk-7hjsnwcv.js} +19 -19
  57. package/dist/chunk-8fcrgq31.js +1 -0
  58. package/dist/{chunk-6t9tjvpy.js → chunk-8msfne57.js} +1 -1
  59. package/dist/{chunk-6nvn041c.js → chunk-93mgdgd5.js} +1 -1
  60. package/dist/{chunk-83p688yv.js → chunk-a6zymyfs.js} +1 -1
  61. package/dist/{chunk-6g81m01r.js → chunk-a7v15116.js} +1 -1
  62. package/dist/{chunk-2knc1zyy.js → chunk-ajq92t46.js} +41 -41
  63. package/dist/{chunk-zftpjxkr.js → chunk-bga3mw5f.js} +1 -1
  64. package/dist/{chunk-r5emv4x8.js → chunk-bgrre2px.js} +1 -1
  65. package/dist/{chunk-hnkw6pde.js → chunk-d1tv3wx0.js} +2 -2
  66. package/dist/chunk-eadp23eh.js +1 -0
  67. package/dist/{chunk-gd9g0v9w.js → chunk-j9rv5m58.js} +1 -1
  68. package/dist/{chunk-678rwkz8.js → chunk-jk7ecnmc.js} +71 -71
  69. package/dist/{chunk-9w32efae.js → chunk-jpbgr1wg.js} +1 -1
  70. package/dist/{chunk-rbem58rx.js → chunk-kazw813q.js} +1 -1
  71. package/dist/{chunk-w495x89g.js → chunk-mherymtx.js} +1 -1
  72. package/dist/{chunk-wjgnfg6q.js → chunk-nr1bdzwy.js} +1 -1
  73. package/dist/{chunk-jb8em9ba.js → chunk-qszktnnz.js} +1 -1
  74. package/dist/{chunk-yq3pdbz7.js → chunk-rtg6nw3n.js} +1 -1
  75. package/dist/{chunk-jvqcw0b4.js → chunk-thghrpf9.js} +11 -11
  76. package/dist/chunk-w7710vzg.js +1 -0
  77. package/dist/{chunk-g9mnmddy.js → chunk-wxv3ypt5.js} +1 -1
  78. package/dist/{chunk-88nxsyry.js → chunk-wz57brcf.js} +5 -5
  79. package/dist/chunk-xfdpxsbc.js +1 -0
  80. package/dist/deploy/index.js +1 -1
  81. package/dist/dns/index.js +1 -1
  82. package/dist/drivers/index.js +1 -1
  83. package/dist/drivers/shared/rpx-gateway.d.ts +17 -0
  84. package/dist/index.js +13 -13
  85. package/dist/operations/index.js +1 -1
  86. package/dist/protection/index.js +1 -1
  87. package/dist/spend/index.js +1 -1
  88. package/dist/ui/404.html +1 -1
  89. package/dist/ui/accept-invitation.html +1 -1
  90. package/dist/ui/access-denied.html +1 -1
  91. package/dist/ui/account/automation.html +5 -5
  92. package/dist/ui/account/security.html +1 -1
  93. package/dist/ui/applications/compose.html +6 -6
  94. package/dist/ui/applications/new.html +2 -2
  95. package/dist/ui/data/backups.html +6 -6
  96. package/dist/ui/data/services.html +6 -6
  97. package/dist/ui/data/volumes.html +6 -6
  98. package/dist/ui/index.html +6 -6
  99. package/dist/ui/infrastructure/topology.html +6 -6
  100. package/dist/ui/integrations.html +2 -2
  101. package/dist/ui/operations/alerts.html +6 -6
  102. package/dist/ui/operations/configuration.html +6 -6
  103. package/dist/ui/operations/jobs.html +5 -5
  104. package/dist/ui/operations/maintenance.html +6 -6
  105. package/dist/ui/operations/observability.html +6 -6
  106. package/dist/ui/operations/previews.html +6 -6
  107. package/dist/ui/operations/queue.html +6 -6
  108. package/dist/ui/operations/regions.html +6 -6
  109. package/dist/ui/operations/releases.html +6 -6
  110. package/dist/ui/operations/spend.html +6 -6
  111. package/dist/ui/operations/workloads.html +6 -6
  112. package/dist/ui/security.html +2 -2
  113. package/dist/ui/server/actions.html +5 -5
  114. package/dist/ui/server/activity.html +1 -1
  115. package/dist/ui/server/capacity.html +6 -6
  116. package/dist/ui/server/database.html +5 -5
  117. package/dist/ui/server/deployments.html +5 -5
  118. package/dist/ui/server/diagnostics.html +2 -2
  119. package/dist/ui/server/firewall.html +6 -6
  120. package/dist/ui/server/fleet.html +6 -6
  121. package/dist/ui/server/logs.html +6 -6
  122. package/dist/ui/server/metrics.html +5 -5
  123. package/dist/ui/server/security.html +2 -2
  124. package/dist/ui/server/services.html +2 -2
  125. package/dist/ui/server/sites.html +6 -6
  126. package/dist/ui/server/ssh-keys.html +6 -6
  127. package/dist/ui/server/team.html +6 -6
  128. package/dist/ui/server/terminal.html +2 -2
  129. package/dist/ui/serverless/alarms.html +6 -6
  130. package/dist/ui/serverless/assets.html +2 -2
  131. package/dist/ui/serverless/cost.html +2 -2
  132. package/dist/ui/serverless/data.html +6 -6
  133. package/dist/ui/serverless/deployments.html +2 -2
  134. package/dist/ui/serverless/firewall.html +2 -2
  135. package/dist/ui/serverless/functions.html +6 -6
  136. package/dist/ui/serverless/logs.html +6 -6
  137. package/dist/ui/serverless/metrics.html +2 -2
  138. package/dist/ui/serverless/queues.html +6 -6
  139. package/dist/ui/serverless/secrets.html +6 -6
  140. package/dist/ui/serverless/traces.html +6 -6
  141. package/dist/ui/serverless.html +6 -6
  142. package/dist/ui-src/src/charts.ts +1 -1
  143. package/dist/ui-src/src/topology.ts +1 -1
  144. package/package.json +3 -3
  145. package/dist/bin/chunk-1s4dny8d.js +0 -1
  146. package/dist/bin/chunk-4w80w3sm.js +0 -1
  147. package/dist/bin/chunk-4yntpqbe.js +0 -1
  148. package/dist/bin/chunk-7x0hrna6.js +0 -1
  149. package/dist/bin/chunk-971tfc6m.js +0 -1
  150. package/dist/bin/chunk-dpw8x3sr.js +0 -1
  151. package/dist/bin/chunk-h785hw6a.js +0 -1
  152. package/dist/bin/chunk-jyggrdh2.js +0 -1
  153. package/dist/bin/chunk-q524s7cx.js +0 -1
  154. package/dist/bin/chunk-q9gpw6wv.js +0 -1
  155. package/dist/bin/chunk-r6cvc2pr.js +0 -1
  156. package/dist/bin/chunk-rh2sqtew.js +0 -1
  157. package/dist/bin/chunk-tkzpbb7n.js +0 -1
  158. package/dist/bin/chunk-v78r5tx0.js +0 -1
  159. package/dist/bin/chunk-v7f4c62s.js +0 -1
  160. package/dist/bin/chunk-vx649y7t.js +0 -1
  161. package/dist/chunk-atny1wp9.js +0 -1
  162. package/dist/chunk-fdexq9e1.js +0 -1
  163. package/dist/chunk-hn2v0b0d.js +0 -1
  164. package/dist/chunk-v46b25w9.js +0 -1
  165. /package/dist/bin/{chunk-bckm6fre.js → chunk-pdw0qjq1.js} +0 -0
  166. /package/dist/{chunk-30h9rgfn.js → chunk-crpjqnjb.js} +0 -0
@@ -1,4 +1,4 @@
1
- import{Wc,_,d,Xc,O,p,ce,g,Mt,rd,Hs,sd,od,dd,_r,Js,Gt,ld,ud,yd,Id}from"./chunk-jvqcw0b4.js";import{B,u}from"./chunk-g9mnmddy.js";import{ae,kt,w,Bt,s,Xn,ys,yr,yc,Ic,J,c,Cs,$e,Ir,Sc,xt,Es,Cc,Sr,vs,Cr,ei,Lt,ii,si,Me,$t,Hc,Gc,ai,ci,at,$s,i,di,Fs,Us}from"./chunk-a6k322xc.js";import{n,l}from"./chunk-30h9rgfn.js";import{Nt,a}from"./chunk-yq3pdbz7.js";import{en}from"./chunk-x07tpsv0.js";import{tn,Ul,Vi,P,v,ji,Ql}from"./chunk-w495x89g.js";import{ue,Jt,Ji,Ke,V,re,C,pe,Zt,Je,tr}from"./chunk-88nxsyry.js";import{j}from"./chunk-zftpjxkr.js";import{b,ir,as,Rt,sr,Yl,Fa,xe,tt,vn,k,Dt,wu,Pt,pr}from"./chunk-678rwkz8.js";import{ge}from"./chunk-cy6qh4ea.js";import{y}from"./chunk-6g81m01r.js";import{Pe}from"./chunk-r5emv4x8.js";import{Ie}from"./chunk-6nvn041c.js";import{f}from"./chunk-jb8em9ba.js";function jr(e){let t=Mc(e.name),r=Ju(e.configText);if(ZS(e.configText,r.start,r.end,t))throw Error(`Site '${t}' already exists in cloud.config.ts`);let o=fm({...e,name:t}),m=e.configText.slice(0,r.end).trimEnd(),h=e.configText.slice(r.end),I=m.endsWith("{")?`
1
+ import{Wc,_,d,Xc,O,p,ce,g,Mt,rd,Hs,sd,od,dd,_r,Js,Gt,ld,ud,yd,Id}from"./chunk-thghrpf9.js";import{B,u}from"./chunk-wxv3ypt5.js";import{ae,kt,w,Bt,s,Xn,ys,yr,yc,Ic,J,c,Cs,Me,Ir,Sc,xt,Es,Cc,Sr,vs,Cr,ei,Lt,ii,si,Fe,$t,Hc,Gc,ai,ci,at,$s,i,di,Fs,Us}from"./chunk-7hjsnwcv.js";import{n,l}from"./chunk-crpjqnjb.js";import{Nt,a}from"./chunk-rtg6nw3n.js";import{en}from"./chunk-1zz5n6q8.js";import{tn,Ul,Vi,P,v,ji,Ql}from"./chunk-mherymtx.js";import{ue,Jt,Ji,We,V,re,C,pe,Zt,Xe,tr}from"./chunk-wz57brcf.js";import{j}from"./chunk-bga3mw5f.js";import{b,ir,as,Rt,sr,Yl,Fa,_e,tt,vn,k,Dt,wu,Pt,pr}from"./chunk-jk7ecnmc.js";import{ge}from"./chunk-4ywy6dp5.js";import{y}from"./chunk-a7v15116.js";import{Pe}from"./chunk-bgrre2px.js";import{Ie}from"./chunk-93mgdgd5.js";import{f}from"./chunk-qszktnnz.js";function jr(e){let t=Mc(e.name),r=Ju(e.configText);if(ZS(e.configText,r.start,r.end,t))throw Error(`Site '${t}' already exists in cloud.config.ts`);let o=fm({...e,name:t}),m=e.configText.slice(0,r.end).trimEnd(),h=e.configText.slice(r.end),I=m.endsWith("{")?`
2
2
  `:m.endsWith(",")?`
3
3
 
4
4
  `:`,
@@ -23,7 +23,7 @@ ${I}},
23
23
  ${E}// Deploy onto the box '${r}' owns rather than provisioning one.
24
24
  ${E}attachTo: '${r}',
25
25
  ${I}},
26
- `))}import{createHash as XS}from"node:crypto";function ew(e){return XS("sha256").update(ws(e)).digest("hex")}function ws(e){if(Array.isArray(e))return`[${e.map((t)=>ws(t)).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0&&typeof t!=="function").sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${ws(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function S(e,t){let r=`dashboard:${t.username.toLowerCase()}`;return e.getActorByExternalId("user",r)??e.createActor({kind:"user",externalId:r,displayName:t.name??t.username,metadata:{source:"dashboard",role:t.role}})}function Rl(e,t){let r=new Xn({cwd:e}),o=ew(t),m=r.getProjectBySlug(t.project.slug),h=t.project.slug.length>=3?t.project.slug:`${t.project.slug}-org`,I=(m?.organizationId?r.getOrganization(m.organizationId):void 0)??r.getOrganizationBySlug(h)??r.createOrganization({id:m?.organizationId,slug:h,name:t.project.name}),R=m?m.name!==t.project.name||m.desiredConfigHash!==o||m.organizationId!==I.id?r.updateProject(m.id,m.version,{name:t.project.name,organizationId:I.id,desiredConfigHash:o}):m:r.createProject({organizationId:I.id,slug:t.project.slug,name:t.project.name,desiredConfigHash:o}),A=new Map;for(let[F,z]of Object.entries(t.environments??{})){let K=r.getEnvironmentBySlug(R.id,F)??r.createEnvironment({projectId:R.id,slug:F,name:F.replace(/(^|[-_])(\w)/g,(fe,Ce,_e)=>_e.toUpperCase()),kind:String(z?.type??F),region:z?.region??t.project.region,desiredState:s(z)});A.set(F,K);let X=new Map(r.listResources(R.id,K.id).map((fe)=>[`${fe.kind}:${fe.slug}`,fe])),oe=(fe,Ce,_e,he)=>{let Ue=`${fe}:${Ce}`,me=X.get(Ue),We=s(he);if(me){if(me.name!==_e||ws(me.desiredState)!==ws(We))X.set(Ue,r.updateResource(me.id,me.version,{name:_e,desiredState:We}));return}let nt=r.createResource({projectId:R.id,environmentId:K.id,kind:fe,slug:Ce,name:_e,provider:t.cloud?.provider,desiredState:We,metadata:{source:"cloud-config"}});X.set(Ue,nt)};for(let[fe,Ce]of Object.entries(t.sites??{}))oe("application",fe,fe,Ce);let ye=z?.app;if(ye)for(let fe of["http","queue","cli"])oe("function",fe,`${fe.toUpperCase()} function`,{...s(ye),function:fe});let ne=t.infrastructure;for(let[fe,Ce]of Object.entries(ne?.functions??{}))oe("function",fe,fe,Ce);if(ne?.compute)oe("server",`${R.slug}-server`,R.name,{...s(ne.compute),label:R.name});for(let[fe,Ce]of Object.entries(ne?.databases??{}))oe("database",fe,fe,Ce);if(ne?.appDatabase)oe("database","application-database","Application database",ne.appDatabase);else if(ne?.database)oe("database","application-database","Application database",{engine:ne.database})}let E=new c(r).recoverExpired(),x=r.reconcileOrphanedOperations({policy:"fail"}),N={requeued:E.requeued+x.requeued,failed:E.failed+E.cancelled+x.failed};return{store:r,organization:I,project:R,environments:A,reconciliation:N}}var tw=["project:read","config:read","deployments:read","deployments:create","runtime:read","runtime:logs"];function Oi(e,t){let{store:r,organization:o,project:m}=e,h=new Set;for(let I of t){let R=S(r,I);h.add(R.id);let A=r.getMembershipForActor(o.id,R.id);if(A&&A.source!=="legacy")continue;let E=r.listResources(m.id).filter((H)=>H.kind==="application"&&Object.hasOwn(I.sites,H.slug)),x=I.role==="admin"?"owner":"viewer",N=I.role==="admin"||E.length===0?{type:"organization"}:{type:"resource",id:E[0].id},F=A?A.roleTemplate!==x||ws(A.scope)!==ws(N)?r.updateMembership({id:A.id,roleTemplate:x,scope:N,actorId:R.id}):A:r.createMembership({organizationId:o.id,actorId:R.id,roleTemplate:x,scope:N,source:"legacy"}),z=new Set;if(I.role==="member"&&E.length===0)for(let H of kt("viewer"))z.add(`deny|${H}|organization|`);for(let H of E){let K=I.sites[H.slug];for(let X of tw)z.add(`allow|${X}|resource|${H.id}`);if(K==="owner")z.add(`allow|config:write|resource|${H.id}`)}for(let H of r.listGrants(F.id).filter((K)=>K.source==="legacy")){let K=`${H.effect}|${H.capability}|${H.scope.type}|${H.scope.id??""}`;if(!z.has(K))r.removeGrant(H.id,R.id)}for(let H of z){let[K,X,oe,ye]=H.split("|");r.upsertGrant({organizationId:o.id,membershipId:F.id,effect:K,capability:X,scope:oe==="organization"?{type:"organization"}:{type:oe,id:ye},source:"legacy"})}}for(let I of r.listMemberships(o.id))if(I.source==="legacy"&&!h.has(I.actorId))r.revokeMembership(I.id)}async function we(e){let{controlPlane:t,environment:r,actor:o}=e,m=S(t.store,o),h=t.environments.get(r),I=e.resourceSlug&&h?t.store.listResources(t.project.id,h.id).find((x)=>x.slug===e.resourceSlug):void 0,R=new c(t.store,{workerId:`dashboard:${process.pid}`}),A=R.enqueue({projectId:t.project.id,environmentId:h?.id,resourceId:I?.id,actorId:m.id,kind:e.kind,input:e.input??{},lockKey:I?`resource:${I.id}`:h?`environment:${h.id}`:`project:${t.project.id}`,providerKey:I?.provider??"dashboard",buildSlot:e.kind.includes("deploy"),maxAttempts:1,timeoutSeconds:3600,resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;if(!R.claim(A.id)?.operation)throw Error(`Could not claim control-plane operation ${A.id}`);try{let x=await e.execute(),N=typeof x.stdout==="string"?String(x.stdout):"",F=typeof x.stderr==="string"?String(x.stderr):"";if(N)R.appendLog(A.id,N,{stream:"stdout"});if(F)R.appendLog(A.id,F,{stream:"stderr"});let z=x.ok?R.complete(A.id,If(x)):R.fail(A.id,rw(x),If(x));return{result:x,operation:z}}catch(x){throw R.fail(A.id,x instanceof Error?x.message:String(x),{ok:!1,threw:!0}),x}}function rw(e){let t=e;return String(t.error??t.stderr??"Operation failed")}function If(e){let t=e,r=typeof t.stdout==="string"?t.stdout:"",o=typeof t.stderr==="string"?t.stderr:"",m={ok:e.ok,stdoutBytes:Buffer.byteLength(r),stderrBytes:Buffer.byteLength(o)};if(typeof t.operation==="string")m.operation=t.operation;if(typeof t.error==="string")m.error=t.error;return s(m)}var Dl=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"spend.overview",path:"/operations/spend",label:"Spend & budgets",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"infrastructure.topology",path:"/infrastructure/topology",label:"Infrastructure map",group:"infrastructure",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/topology"]},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],nw=new Map(Dl.flatMap((e)=>(e.legacyPaths??[]).map((t)=>[t,e.path])));function Pl(e){return nw.get(e)}function bA(e,t){return Dl.filter((r)=>r.modes.includes(e)&&(!t||!r.adminOnly))}import ao from"node:process";import{existsSync as iw}from"node:fs";import{join as ow}from"node:path";async function Nl(e){let t=Date.now(),r=e.sourceDir??"dist";if(!iw(ow(r,"index.html")))return Qu(t,`${r}/ has no index.html — build first.`);if(!ao.env.AWS_ACCESS_KEY_ID||!ao.env.AWS_SECRET_ACCESS_KEY)return Qu(t,"Missing AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY in env.");let o=sw(e.dnsProvider);if("error"in o)return Qu(t,o.error);let m=await en({siteName:e.siteName,region:e.region??"us-east-1",domain:e.domain,bucket:e.bucket,stackName:e.stackName,certificateArn:e.certificateArn,defaultRootObject:e.defaultRootObject??"index.html",errorDocument:e.errorDocument??"404.html",cacheControl:e.cacheControl??"max-age=3600, public",sourceDir:r,cleanBucket:e.cleanBucket??!1,singlePageApp:e.singlePageApp??!1,dnsProvider:o,tags:{ManagedBy:"ts-cloud",Application:e.siteName,...e.tags},onProgress:e.onProgress});return{success:!!m.success,domain:m.domain,url:m.domain?`https://${m.domain}`:m.distributionDomain?`https://${m.distributionDomain}`:void 0,bucket:m.bucket,distributionId:m.distributionId,distributionDomain:m.distributionDomain,certificateArn:m.certificateArn,filesUploaded:m.filesUploaded,filesSkipped:m.filesSkipped,message:m.message,durationMs:Date.now()-t}}function sw(e){let t=typeof e==="string"?{provider:e}:e??{provider:"porkbun"};if(t.provider==="porkbun"){let r=t,o=r?.apiKey??ao.env.PORKBUN_API_KEY,m=r?.secretKey??ao.env.PORKBUN_SECRET_KEY??ao.env.PORKBUN_SECRET_API_KEY;if(!o||!m)return{error:"Missing PORKBUN_API_KEY / PORKBUN_SECRET_KEY in env."};return{provider:"porkbun",apiKey:o,secretKey:m}}if(t.provider==="godaddy"){let r=t,o=r?.apiKey??ao.env.GODADDY_API_KEY,m=r?.secretKey??ao.env.GODADDY_API_SECRET,h=r?.environment??ao.env.GODADDY_ENVIRONMENT;if(!o||!m)return{error:"Missing GODADDY_API_KEY / GODADDY_API_SECRET in env."};return{provider:"godaddy",apiKey:o,apiSecret:m,environment:h}}return{error:`Unsupported DNS provider: ${t.provider}`}}function Qu(e,t){return{success:!1,message:t,durationMs:Date.now()-e}}import{createHash as aw}from"node:crypto";var cw=`let coldStart = true
26
+ `))}import{createHash as XS}from"node:crypto";function ew(e){return XS("sha256").update(ws(e)).digest("hex")}function ws(e){if(Array.isArray(e))return`[${e.map((t)=>ws(t)).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0&&typeof t!=="function").sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${ws(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function S(e,t){let r=`dashboard:${t.username.toLowerCase()}`;return e.getActorByExternalId("user",r)??e.createActor({kind:"user",externalId:r,displayName:t.name??t.username,metadata:{source:"dashboard",role:t.role}})}function Rl(e,t){let r=new Xn({cwd:e}),o=ew(t),m=r.getProjectBySlug(t.project.slug),h=t.project.slug.length>=3?t.project.slug:`${t.project.slug}-org`,I=(m?.organizationId?r.getOrganization(m.organizationId):void 0)??r.getOrganizationBySlug(h)??r.createOrganization({id:m?.organizationId,slug:h,name:t.project.name}),R=m?m.name!==t.project.name||m.desiredConfigHash!==o||m.organizationId!==I.id?r.updateProject(m.id,m.version,{name:t.project.name,organizationId:I.id,desiredConfigHash:o}):m:r.createProject({organizationId:I.id,slug:t.project.slug,name:t.project.name,desiredConfigHash:o}),A=new Map;for(let[F,z]of Object.entries(t.environments??{})){let K=r.getEnvironmentBySlug(R.id,F)??r.createEnvironment({projectId:R.id,slug:F,name:F.replace(/(^|[-_])(\w)/g,(fe,Ce,xe)=>xe.toUpperCase()),kind:String(z?.type??F),region:z?.region??t.project.region,desiredState:s(z)});A.set(F,K);let X=new Map(r.listResources(R.id,K.id).map((fe)=>[`${fe.kind}:${fe.slug}`,fe])),oe=(fe,Ce,xe,he)=>{let Ue=`${fe}:${Ce}`,me=X.get(Ue),He=s(he);if(me){if(me.name!==xe||ws(me.desiredState)!==ws(He))X.set(Ue,r.updateResource(me.id,me.version,{name:xe,desiredState:He}));return}let nt=r.createResource({projectId:R.id,environmentId:K.id,kind:fe,slug:Ce,name:xe,provider:t.cloud?.provider,desiredState:He,metadata:{source:"cloud-config"}});X.set(Ue,nt)};for(let[fe,Ce]of Object.entries(t.sites??{}))oe("application",fe,fe,Ce);let ye=z?.app;if(ye)for(let fe of["http","queue","cli"])oe("function",fe,`${fe.toUpperCase()} function`,{...s(ye),function:fe});let ne=t.infrastructure;for(let[fe,Ce]of Object.entries(ne?.functions??{}))oe("function",fe,fe,Ce);if(ne?.compute)oe("server",`${R.slug}-server`,R.name,{...s(ne.compute),label:R.name});for(let[fe,Ce]of Object.entries(ne?.databases??{}))oe("database",fe,fe,Ce);if(ne?.appDatabase)oe("database","application-database","Application database",ne.appDatabase);else if(ne?.database)oe("database","application-database","Application database",{engine:ne.database})}let E=new c(r).recoverExpired(),x=r.reconcileOrphanedOperations({policy:"fail"}),N={requeued:E.requeued+x.requeued,failed:E.failed+E.cancelled+x.failed};return{store:r,organization:I,project:R,environments:A,reconciliation:N}}var tw=["project:read","config:read","deployments:read","deployments:create","runtime:read","runtime:logs"];function Oi(e,t){let{store:r,organization:o,project:m}=e,h=new Set;for(let I of t){let R=S(r,I);h.add(R.id);let A=r.getMembershipForActor(o.id,R.id);if(A&&A.source!=="legacy")continue;let E=r.listResources(m.id).filter((H)=>H.kind==="application"&&Object.hasOwn(I.sites,H.slug)),x=I.role==="admin"?"owner":"viewer",N=I.role==="admin"||E.length===0?{type:"organization"}:{type:"resource",id:E[0].id},F=A?A.roleTemplate!==x||ws(A.scope)!==ws(N)?r.updateMembership({id:A.id,roleTemplate:x,scope:N,actorId:R.id}):A:r.createMembership({organizationId:o.id,actorId:R.id,roleTemplate:x,scope:N,source:"legacy"}),z=new Set;if(I.role==="member"&&E.length===0)for(let H of kt("viewer"))z.add(`deny|${H}|organization|`);for(let H of E){let K=I.sites[H.slug];for(let X of tw)z.add(`allow|${X}|resource|${H.id}`);if(K==="owner")z.add(`allow|config:write|resource|${H.id}`)}for(let H of r.listGrants(F.id).filter((K)=>K.source==="legacy")){let K=`${H.effect}|${H.capability}|${H.scope.type}|${H.scope.id??""}`;if(!z.has(K))r.removeGrant(H.id,R.id)}for(let H of z){let[K,X,oe,ye]=H.split("|");r.upsertGrant({organizationId:o.id,membershipId:F.id,effect:K,capability:X,scope:oe==="organization"?{type:"organization"}:{type:oe,id:ye},source:"legacy"})}}for(let I of r.listMemberships(o.id))if(I.source==="legacy"&&!h.has(I.actorId))r.revokeMembership(I.id)}async function we(e){let{controlPlane:t,environment:r,actor:o}=e,m=S(t.store,o),h=t.environments.get(r),I=e.resourceSlug&&h?t.store.listResources(t.project.id,h.id).find((x)=>x.slug===e.resourceSlug):void 0,R=new c(t.store,{workerId:`dashboard:${process.pid}`}),A=R.enqueue({projectId:t.project.id,environmentId:h?.id,resourceId:I?.id,actorId:m.id,kind:e.kind,input:e.input??{},lockKey:I?`resource:${I.id}`:h?`environment:${h.id}`:`project:${t.project.id}`,providerKey:I?.provider??"dashboard",buildSlot:e.kind.includes("deploy"),maxAttempts:1,timeoutSeconds:3600,resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;if(!R.claim(A.id)?.operation)throw Error(`Could not claim control-plane operation ${A.id}`);try{let x=await e.execute(),N=typeof x.stdout==="string"?String(x.stdout):"",F=typeof x.stderr==="string"?String(x.stderr):"";if(N)R.appendLog(A.id,N,{stream:"stdout"});if(F)R.appendLog(A.id,F,{stream:"stderr"});let z=x.ok?R.complete(A.id,If(x)):R.fail(A.id,rw(x),If(x));return{result:x,operation:z}}catch(x){throw R.fail(A.id,x instanceof Error?x.message:String(x),{ok:!1,threw:!0}),x}}function rw(e){let t=e;return String(t.error??t.stderr??"Operation failed")}function If(e){let t=e,r=typeof t.stdout==="string"?t.stdout:"",o=typeof t.stderr==="string"?t.stderr:"",m={ok:e.ok,stdoutBytes:Buffer.byteLength(r),stderrBytes:Buffer.byteLength(o)};if(typeof t.operation==="string")m.operation=t.operation;if(typeof t.error==="string")m.error=t.error;return s(m)}var Dl=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"spend.overview",path:"/operations/spend",label:"Spend & budgets",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"infrastructure.topology",path:"/infrastructure/topology",label:"Infrastructure map",group:"infrastructure",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/topology"]},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],nw=new Map(Dl.flatMap((e)=>(e.legacyPaths??[]).map((t)=>[t,e.path])));function Pl(e){return nw.get(e)}function bA(e,t){return Dl.filter((r)=>r.modes.includes(e)&&(!t||!r.adminOnly))}import ao from"node:process";import{existsSync as iw}from"node:fs";import{join as ow}from"node:path";async function Nl(e){let t=Date.now(),r=e.sourceDir??"dist";if(!iw(ow(r,"index.html")))return Qu(t,`${r}/ has no index.html — build first.`);if(!ao.env.AWS_ACCESS_KEY_ID||!ao.env.AWS_SECRET_ACCESS_KEY)return Qu(t,"Missing AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY in env.");let o=sw(e.dnsProvider);if("error"in o)return Qu(t,o.error);let m=await en({siteName:e.siteName,region:e.region??"us-east-1",domain:e.domain,bucket:e.bucket,stackName:e.stackName,certificateArn:e.certificateArn,defaultRootObject:e.defaultRootObject??"index.html",errorDocument:e.errorDocument??"404.html",cacheControl:e.cacheControl??"max-age=3600, public",sourceDir:r,cleanBucket:e.cleanBucket??!1,singlePageApp:e.singlePageApp??!1,dnsProvider:o,tags:{ManagedBy:"ts-cloud",Application:e.siteName,...e.tags},onProgress:e.onProgress});return{success:!!m.success,domain:m.domain,url:m.domain?`https://${m.domain}`:m.distributionDomain?`https://${m.distributionDomain}`:void 0,bucket:m.bucket,distributionId:m.distributionId,distributionDomain:m.distributionDomain,certificateArn:m.certificateArn,filesUploaded:m.filesUploaded,filesSkipped:m.filesSkipped,message:m.message,durationMs:Date.now()-t}}function sw(e){let t=typeof e==="string"?{provider:e}:e??{provider:"porkbun"};if(t.provider==="porkbun"){let r=t,o=r?.apiKey??ao.env.PORKBUN_API_KEY,m=r?.secretKey??ao.env.PORKBUN_SECRET_KEY??ao.env.PORKBUN_SECRET_API_KEY;if(!o||!m)return{error:"Missing PORKBUN_API_KEY / PORKBUN_SECRET_KEY in env."};return{provider:"porkbun",apiKey:o,secretKey:m}}if(t.provider==="godaddy"){let r=t,o=r?.apiKey??ao.env.GODADDY_API_KEY,m=r?.secretKey??ao.env.GODADDY_API_SECRET,h=r?.environment??ao.env.GODADDY_ENVIRONMENT;if(!o||!m)return{error:"Missing GODADDY_API_KEY / GODADDY_API_SECRET in env."};return{provider:"godaddy",apiKey:o,apiSecret:m,environment:h}}return{error:`Unsupported DNS provider: ${t.provider}`}}function Qu(e,t){return{success:!1,message:t,durationMs:Date.now()-e}}import{createHash as aw}from"node:crypto";var cw=`let coldStart = true
27
27
  const initializedAt = new Date().toISOString()
28
28
  export const handler = async (event) => {
29
29
  const currentColdStart = coldStart
@@ -36,47 +36,47 @@ export const handler = async (event) => {
36
36
  body: JSON.stringify({ ok: statusCode === 200, service: 'ts-cloud-static-api', path, coldStart: currentColdStart, initializedAt })
37
37
  }
38
38
  }
39
- `;function Af(e){let t=e;return String(t?.code||t?.name||t?.statusCode||"")}function dw(e){return["NoSuchEntity","ResourceNotFoundException","404"].includes(Af(e))}function Ef(e){return["EntityAlreadyExists","ResourceAlreadyExistsException","ResourceConflictException","409"].includes(Af(e))}function Rf(e,t){let r=e?.Items;if(!r)return[];if(Array.isArray(r))return r;let o=r[t];if(o===void 0)return[];return Array.isArray(o)?o:[o]}function Yu(e){let t=e?.Aliases?.Items;if(Array.isArray(t))return t.map(String);if(typeof t==="string")return[t];return[]}function lw(e){if(!/^[A-Z0-9]{8,32}$/.test(e.distributionId))throw Error("CloudFront distribution ID is invalid");if(!/^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9-]{2,63}$/.test(e.expectedAlias))throw Error("Expected CloudFront alias is invalid");if(!/^[A-Za-z0-9-_]{1,64}$/.test(e.functionName))throw Error("Lambda function name is invalid");let t=e.pathPattern?.startsWith("/")?e.pathPattern:`/${e.pathPattern||"api/*"}`;if(t==="/"||t==="/*"||!t.endsWith("*"))throw Error("API path must be a non-default wildcard pattern such as /api/*");let r=e.originId||`${e.functionName}-url`,o=e.roleName||`${e.functionName}-execution`;if(!/^[A-Za-z0-9_.-]{1,64}$/.test(o))throw Error("IAM role name is invalid");let m=e.memorySize??256,h=e.timeout??10,I=e.logRetentionDays??14;if(m<128||m>10240)throw Error("Lambda memory must be between 128 and 10240 MB");if(h<1||h>900)throw Error("Lambda timeout must be between 1 and 900 seconds");return{region:e.region||"us-east-1",pathPattern:t,originId:r,roleName:o,memorySize:m,timeout:h,logRetentionDays:I}}function Am(e){let t=e.region||"us-east-1";return{cloudfront:new y(e.profile),iam:new ge(t,e.profile),lambda:new C(t,e.profile),logs:new pe(t,e.profile),sts:new ue(t,e.profile),sleep:(r)=>new Promise((o)=>setTimeout(o,r))}}async function EA(e,t){let r=lw(e),o=t||Am({profile:e.profile,region:r.region}),[m,h,I]=await Promise.all([o.sts.getCallerIdentity(),o.cloudfront.getDistribution(e.distributionId),o.cloudfront.getDistributionConfig(e.distributionId)]);if(!m.Account)throw Error("AWS identity did not return an account ID");if(!h.Enabled)throw Error(`CloudFront distribution ${e.distributionId} is disabled`);if(!(Yu(h).length?Yu(h):Yu(I.DistributionConfig)).includes(e.expectedAlias))throw Error(`Distribution ${e.distributionId} does not contain expected alias ${e.expectedAlias}`);let A,E=!0;try{A=await o.iam.getRole({RoleName:r.roleName})}catch(st){if(!dw(st))throw st;E=!1}let x=A?.Arn||`arn:aws:iam::${m.Account}:role/${r.roleName}`,N=await o.lambda.functionExists(e.functionName),F=N?await o.lambda.getFunctionUrl(e.functionName):null,z=await o.cloudfront.listOriginAccessControls(),H=`${e.functionName}-lambda-url`,K=z.some((st)=>st.Name===H&&st.OriginAccessControlOriginType==="lambda"),X=Rf(I.DistributionConfig.Origins,"Origin"),oe=Rf(I.DistributionConfig.CacheBehaviors,"CacheBehavior"),ye=X.some((st)=>String(st.Id)===r.originId),ne=oe.some((st)=>String(st.PathPattern)===r.pathPattern),fe=[...!E?[`create IAM execution role ${r.roleName}`]:[`reconcile IAM execution policy ${r.roleName}`],...N?[`update Lambda ${e.functionName} code and configuration`]:[`create Lambda ${e.functionName}`],...!F?["create private AWS_IAM function URL"]:[],...!K?[`create Lambda origin access control ${H}`]:[],"grant CloudFront function-URL and invocation permissions",`${ne?"reconcile":"add"} ${r.pathPattern} behavior without changing the default behavior`],Ce={command:`cloud cdn:origin:remove ${e.distributionId} FUNCTION_URL_HOST --id ${r.originId} --path '${r.pathPattern}' --apply --confirm 'remove:${e.distributionId}:${r.pathPattern}'`,removeFunction:!N,removeRole:!E},_e={mode:e.apply?"apply":"plan",accountId:m.Account,identityArn:m.Arn,distribution:{id:h.Id,arn:h.ARN,alias:e.expectedAlias,domainName:h.DomainName,status:h.Status},function:{name:e.functionName,existed:N,runtime:"nodejs22.x",urlExisted:!!F,url:F?.FunctionUrl},role:{name:r.roleName,existed:E,arn:x},origin:{id:r.originId,pathPattern:r.pathPattern,existed:ye,behaviorExisted:ne,accessControlExisted:K},changes:fe,rollback:Ce,applied:!1};if(!e.apply)return _e;let he=`${e.distributionId}:${r.pathPattern}`;if(e.confirm!==he)throw Error(`Pass exact confirmation token ${he} to mutate the live distribution`);if(!A)A=await o.iam.createRole({RoleName:r.roleName,Description:`Execution role for ${e.functionName}`,AssumeRolePolicyDocument:JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]}),Tags:[{Key:"ManagedBy",Value:"ts-cloud"}]});await o.iam.putRolePolicy({RoleName:r.roleName,PolicyName:"lambda-logs",PolicyDocument:JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:`arn:aws:logs:${r.region}:${m.Account}:log-group:/aws/lambda/${e.functionName}:*`}]})});try{await o.logs.createLogGroup(`/aws/lambda/${e.functionName}`,{ManagedBy:"ts-cloud"})}catch(st){if(!Ef(st))throw st}await o.logs.putRetentionPolicy(`/aws/lambda/${e.functionName}`,r.logRetentionDays);let Ue=e.code||cw;if(N)await o.lambda.updateFunctionCodeInline(e.functionName,Ue,"index.mjs"),await o.lambda.waitForFunctionActive(e.functionName),await o.lambda.updateFunctionConfiguration({FunctionName:e.functionName,Runtime:"nodejs22.x",Role:A.Arn,Handler:"index.handler",Description:`Private API origin for ${e.expectedAlias}`,Timeout:r.timeout,MemorySize:r.memorySize});else{let st;for(let Ft=0;Ft<8;Ft++)try{await o.lambda.createFunctionWithCode({FunctionName:e.functionName,Runtime:"nodejs22.x",Role:A.Arn,Handler:"index.handler",Code:Ue,Filename:"index.mjs",Description:`Private API origin for ${e.expectedAlias}`,Timeout:r.timeout,MemorySize:r.memorySize}),st=void 0;break}catch(dr){if(st=dr,!String(dr.message).toLowerCase().includes("role"))throw dr;await o.sleep(1000)}if(st)throw st}await o.lambda.waitForFunctionActive(e.functionName);let me=F||await o.lambda.createFunctionUrl({FunctionName:e.functionName,AuthType:"AWS_IAM",InvokeMode:"BUFFERED"});if(!me.FunctionUrl)throw Error("Lambda did not return a function URL");let We=new URL(me.FunctionUrl).hostname,nt=await o.cloudfront.findOrCreateOriginAccessControl(H,"lambda"),wt=h.ARN||`arn:aws:cloudfront::${m.Account}:distribution/${e.distributionId}`,cr=[{FunctionName:e.functionName,StatementId:"AllowCloudFrontFunctionUrl",Action:"lambda:InvokeFunctionUrl",Principal:"cloudfront.amazonaws.com",SourceArn:wt,FunctionUrlAuthType:"AWS_IAM"},{FunctionName:e.functionName,StatementId:"AllowCloudFrontInvoke",Action:"lambda:InvokeFunction",Principal:"cloudfront.amazonaws.com",SourceArn:wt,InvokedViaFunctionUrl:!0}];for(let st of cr)try{await o.lambda.addPermission(st)}catch(Ft){if(!Ef(Ft))throw Ft}return await o.cloudfront.upsertExistingDistributionOrigin(e.distributionId,{id:r.originId,domainName:We,pathPattern:r.pathPattern,originAccessControlId:nt.Id}),{..._e,function:{..._e.function,url:me.FunctionUrl},applied:!0}}async function vA(e){let t=`https://${e.alias}/`,r=`https://${e.alias}/api/health`,o=await fetch(t,{redirect:"follow",headers:{"cache-control":"no-cache"}}),m=new Uint8Array(await o.arrayBuffer()),h=aw("sha256").update(m).digest("hex"),I=Date.now(),R=await fetch(r,{redirect:"follow",headers:{"cache-control":"no-cache"}}),A=Date.now()-I,E=await R.text(),x=E;try{x=JSON.parse(E)}catch{}let N;if(e.logs&&e.functionName){let F=await e.logs.filterLogEvents({logGroupName:`/aws/lambda/${e.functionName}`,startTime:I-60000,filterPattern:'"Init Duration"',limit:25});for(let z of F.events||[]){let H=z.message?.match(/Init Duration:\s*([0-9.]+)\s*ms/i);if(H)N=Number(H[1])}}return{frontend:{url:t,status:o.status,sha256:h,unchanged:e.expectedFrontendSha256?h===e.expectedFrontendSha256:void 0,bytes:m.byteLength},api:{url:r,status:R.status,latencyMs:A,healthy:R.ok&&!!x?.ok,body:x},coldStart:{observed:N!==void 0,initDurationMs:N},verifiedAt:(e.now?.()||new Date).toISOString()}}function TA(e){let t=(e.memoryMb||256)/1024,r=Math.max(0,e.requests-(e.includeFreeTier===!1?0:1e6)),o=Math.max(0,e.requests*(e.averageDurationMs/1000)*t-(e.includeFreeTier===!1?0:400000)),m=r/1e6*0.2+o*0.0000166667,h=9.010025,I=16.425;return{lambdaUsd:Number(m.toFixed(2)),alwaysOnFargateAndAlbUsd:Number(25.435025000000003 .toFixed(2)),assumptions:["us-east-1 public list rates snapshot, July 2026","Lambda x86 request and duration pricing with optional monthly free tier","Fargate comparison uses one always-on 0.25 vCPU/0.5 GB task plus one ALB before LCU charges","excludes CloudFront, data transfer, logs, taxes, and application data services"]}}import{createHash as uw}from"node:crypto";function pw(e){let t=e;return String(t?.code||t?.name||t?.statusCode||"")}function mw(e){return pw(e)==="ValidationError"&&String(e.message).includes("does not exist")}function gw(e){return Object.fromEntries((e||[]).map((t)=>[t.OutputKey,t.OutputValue]))}function fw(e){let t=e?.Aliases?.Items??e?.Aliases;if(Array.isArray(t))return t.map(String);if(typeof t==="string")return[t];return[]}function Cf(e){if(!/^[a-z][a-z0-9-]{1,62}$/.test(e.slug))throw Error("Slug must be a lowercase DNS-safe identifier");if(!/^[A-Z0-9]{8,32}$/.test(e.distributionId))throw Error("CloudFront distribution ID is invalid");if(!/^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9-]{2,63}$/.test(e.expectedAlias))throw Error("Expected distribution alias is invalid");let t=e.imageUri.match(/@((?:sha256:)[a-f0-9]{64})$/i)?.[1];if(!t)throw Error("Container image must use an immutable ECR digest URI ending in @sha256:<64 hex>");let r=e.stackName||`${e.slug}-backend`;if(!/^[A-Za-z][A-Za-z0-9-]{0,127}$/.test(r))throw Error("CloudFormation stack name is invalid");let o=e.pathPattern||"/api/*";if(!/^\/[A-Za-z0-9_.*?~!$&'()+,;=:@%/-]+\*$/.test(o)||o==="/*")throw Error("Backend path must be a non-default wildcard pattern");let m=e.originId||`${e.slug}-backend`;if(!/^[A-Za-z0-9_.-]{1,128}$/.test(m))throw Error("CloudFront origin ID is invalid");if(e.originVerifySecret&&e.originVerifySecret.length<24)throw Error("Origin verification secret must contain at least 24 characters");if(!!e.originDomain!==!!e.certificateArn)throw Error("A custom origin domain and matching ACM certificate ARN must be provided together");return{stackName:r,region:e.region||"us-east-1",pathPattern:o,originId:m,digest:t}}function ym(e){let t=e.region||"us-east-1";return{cloudformation:new f(t,e.profile),cloudfront:new y(e.profile),sts:new ue(t,e.profile),fetch,sleep:(r)=>new Promise((o)=>setTimeout(o,r))}}function Im(e){let t=Cf(e),r=od({name:e.name,slug:e.slug,domain:e.originDomain||e.expectedAlias,imageUri:e.imageUri,certificateArn:e.certificateArn,originVerifySecret:e.originVerifySecret,desiredCount:e.desiredCount,database:e.database,cache:e.cache,queue:e.queue}),o=sd(r);return o.Description=`Managed backend for existing static frontend ${e.expectedAlias}`,o.Metadata={ManagedBy:"ts-cloud",ExistingDistributionId:e.distributionId,ExistingDistributionAlias:e.expectedAlias,BackendPathPattern:t.pathPattern,ContainerDigest:t.digest},o}async function hw(e,t,r){let o;for(let m=0;m<30;m++){let h=Date.now();try{let I=await e.fetch(t,{redirect:"manual",headers:r?{"x-origin-verify":r}:void 0}),R=Date.now()-h,A=await I.text(),E=A;try{E=JSON.parse(A)}catch{}if(I.ok)return{url:t,status:I.status,latencyMs:R,body:E};o=Error(`origin returned ${I.status}`)}catch(I){o=I}if(m<29)await e.sleep(1e4)}throw Error(`Backend origin did not become healthy: ${o instanceof Error?o.message:String(o)}`)}async function wA(e,t){let r=Cf(e),o=t||ym({region:r.region,profile:e.profile}),[m,h]=await Promise.all([o.sts.getCallerIdentity(),o.cloudfront.getDistribution(e.distributionId)]);if(!m.Account)throw Error("AWS identity did not return an account ID");if(!h.Enabled)throw Error(`CloudFront distribution ${e.distributionId} is disabled`);if(!fw(h).includes(e.expectedAlias))throw Error(`Distribution ${e.distributionId} does not contain expected alias ${e.expectedAlias}`);let I;try{I=(await o.cloudformation.describeStacks({stackName:r.stackName})).Stacks[0]}catch(fe){if(!mw(fe))throw fe}let R=Im(e),A=JSON.stringify(R);if(Buffer.byteLength(A)>51200)throw Error("Generated template exceeds the direct CloudFormation template body limit");let E=Object.values(R.Resources||{}).reduce((fe,Ce)=>(fe[Ce.Type]=(fe[Ce.Type]||0)+1,fe),{}),x=[`cloud cdn:origin:remove ${e.distributionId} ${e.originDomain||"ALB_HOST"} --id ${r.originId} --path '${r.pathPattern}' --profile ${e.profile||"default"} --apply --confirm 'remove:${e.distributionId}:${r.pathPattern}'`,`After CloudFront is deployed, restore external DNS if changed and delete stack ${r.stackName} only with an approved data-retention decision.`],N={mode:e.apply?"apply":"plan",accountId:m.Account,stack:{name:r.stackName,existed:!!I,status:I?.StackStatus,templateSha256:uw("sha256").update(A).digest("hex"),resourceCount:Object.keys(R.Resources||{}).length,resourceTypes:E},distribution:{id:h.Id,alias:e.expectedAlias,domainName:h.DomainName,status:h.Status,pathPattern:r.pathPattern,originId:r.originId},artifact:{imageUri:e.imageUri,digest:r.digest},services:{database:e.database!==!1,cache:e.cache!==!1,queue:e.queue!==!1,mail:"ses",desiredCount:e.desiredCount||1},cloudFrontApplied:!1,dnsApplied:!1,applied:!1,rollback:x};if(!e.apply)return N;let F=`${e.distributionId}:${r.pathPattern}:${r.stackName}`;if(e.confirm!==F)throw Error(`Pass exact confirmation token ${F} to provision the backend and change live routing`);if(I)try{await o.cloudformation.updateStack({stackName:r.stackName,templateBody:A,capabilities:["CAPABILITY_NAMED_IAM"],tags:[{Key:"ManagedBy",Value:"ts-cloud"},{Key:"Application",Value:e.slug}]}),await o.cloudformation.waitForStack(r.stackName,"stack-update-complete")}catch(fe){if(!String(fe.message).includes("No updates are to be performed"))throw fe}else await o.cloudformation.createStack({stackName:r.stackName,templateBody:A,capabilities:["CAPABILITY_NAMED_IAM"],onFailure:"ROLLBACK",tags:[{Key:"ManagedBy",Value:"ts-cloud"},{Key:"Application",Value:e.slug}]}),await o.cloudformation.waitForStack(r.stackName,"stack-create-complete");let z=(await o.cloudformation.describeStacks({stackName:r.stackName})).Stacks[0],H=gw(z?.Outputs),K=H.AppLoadBalancerDnsName;if(!K)throw Error("Backend stack did not return AppLoadBalancerDnsName");let X=!1;if(e.originDomain&&e.originDomain!==K){if(!o.dns)throw Error(`External DNS provider is required to map ${e.originDomain} to ${K}`);let fe=await o.dns.upsertRecord(e.originDomain,{name:e.originDomain,type:"CNAME",content:K,ttl:300});if(!fe.success)throw Error(fe.message||"External DNS update failed");X=!0}let oe=e.originDomain||K,ye=e.certificateArn?"https-only":"http-only",ne=e.skipHealthCheck?void 0:await hw(o,`${ye==="https-only"?"https":"http"}://${oe}/api/health`,e.originVerifySecret);return await o.cloudfront.upsertExistingDistributionOrigin(e.distributionId,{id:r.originId,domainName:oe,pathPattern:r.pathPattern,protocolPolicy:ye,customHeaders:e.originVerifySecret?{"X-Origin-Verify":e.originVerifySecret}:void 0}),{...N,outputs:H,health:ne,cloudFrontApplied:!0,dnsApplied:X,applied:!0}}function RA(e={}){let r={fargate:730*(e.desiredCount||1)*0.012342500000000001,applicationLoadBalancer:16.425,natGateway:32.85,postgres:730*(e.multiAzDatabase?0.032:0.016),redis:23.36};return{monthlyUsd:Number(Object.values(r).reduce((o,m)=>o+m,0).toFixed(2)),components:Object.fromEntries(Object.entries(r).map(([o,m])=>[o,Number(m.toFixed(2))])),assumptions:["us-east-1 public on-demand rate snapshot, July 2026","one 0.25 vCPU/0.5 GB Linux Fargate task unless desiredCount is changed","one ALB before LCU charges and one NAT gateway before data processing","single-AZ db.t4g.micro PostgreSQL by default and two cache.t4g.micro Redis nodes","excludes storage, backups, CloudFront, data transfer, public IPv4, logs, email, queue requests, taxes, and free-tier credits"]}}import{execFileSync as yw}from"node:child_process";import{createHash as vw}from"node:crypto";import{existsSync as Pf,mkdirSync as bw,mkdtempSync as Sw,readdirSync as ww,readFileSync as kw,rmSync as Iw,statSync as _f,writeFileSync as Ew}from"node:fs";import{tmpdir as Rw}from"node:os";import{basename as Aw,join as fa,relative as Cw,resolve as Zu}from"node:path";var Pw=new Set([".git","node_modules","dist","coverage"]);function Tf(e,t=e){let r=[];for(let o of ww(e).sort()){if(Pw.has(o))continue;let m=fa(e,o);if(Xc(m,t))continue;let h=_f(m);if(h.isDirectory())r.push(...Tf(m,t));else if(h.isFile())r.push(Cw(t,m))}return r}function Sm(e){let t=Zu(e);if(!Pf(t)||!_f(t).isDirectory())throw Error(`Container context does not exist: ${t}`);let r=vw("sha256");for(let o of Tf(t))r.update(o),r.update("\x00"),r.update(kw(fa(t,o))),r.update("\x00");return r.digest("hex")}function Cm(e){return{ecr:new Pe(e.region||"us-east-1",e.profile),run:(t,r,o)=>{yw(t,r,{cwd:o?.cwd,env:o?.env,stdio:o?.stdio||"inherit"})}}}async function DA(e,t){let r=Zu(e.context),o=Zu(e.dockerfile||fa(r,"Dockerfile"));if(!Pf(o))throw Error(`Dockerfile does not exist: ${o}`);if(!e.repository.split("/").every((H)=>/^[a-z0-9][a-z0-9._-]*$/.test(H)&&!/[._-]$/.test(H)&&!/[._-]{2}/.test(H)))throw Error("ECR repository name is invalid");let I=t||Cm(e),R=Sm(r),A=`sha-${R.slice(0,20)}`,E="";try{E=(await I.ecr.describeRepositories({repositoryNames:[e.repository]})).repositories?.[0]?.repositoryUri||""}catch{}if(!E)E=(await I.ecr.createRepository({repositoryName:e.repository,imageTagMutability:"IMMUTABLE",imageScanningConfiguration:{scanOnPush:!0},tags:[{Key:"ManagedBy",Value:"ts-cloud"}]})).repository?.repositoryUri||"";if(!E)throw Error(`Could not resolve ECR repository URI for ${e.repository}`);await I.ecr.putLifecyclePolicy({repositoryName:e.repository,lifecyclePolicyText:JSON.stringify({rules:[{rulePriority:1,description:"Retain the newest 25 release images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:25},action:{type:"expire"}}]})});let x=`${E}:${A}`,N=Sw(fa(Rw(),"ts-cloud-container-"));try{I.run("docker",["version"],{stdio:"ignore"}),I.run("docker",["build","--platform",e.platform||"linux/amd64","--provenance=false","--sbom=false","--file",o,"--tag",x,r],{cwd:r});let H=(await I.ecr.getAuthorizationToken()).authorizationData?.[0];if(!H?.authorizationToken||!H.proxyEndpoint)throw Error("ECR did not return Docker authorization data");let K=H.proxyEndpoint.replace(/^https?:\/\//,""),X=fa(N,"docker");bw(X,{recursive:!0}),Ew(fa(X,"config.json"),JSON.stringify({auths:{[K]:{auth:H.authorizationToken}}}),{mode:384}),I.run("docker",["push",x],{env:{...process.env,DOCKER_CONFIG:X}})}finally{Iw(N,{recursive:!0,force:!0})}let z=(await I.ecr.describeImages({repositoryName:e.repository,imageIds:[{imageTag:A}]})).imageDetails?.[0]?.imageDigest;if(!z||!/^sha256:[a-f0-9]{64}$/i.test(z))throw Error(`ECR did not return an immutable digest for ${Aw(x)}`);return{repository:e.repository,tag:A,imageUri:x,digest:z,digestUri:`${E}@${z}`,contextSha256:R}}import{existsSync as _w,readdirSync as Tw,readFileSync as xw,statSync as Dw}from"node:fs";import{join as xf,relative as Ow}from"node:path";function Is(e,t){let r=e.environments?.[t]?.app;if(!r)throw Error(`No serverless app configured for environment '${t}'. Add environments.${t}.app to your config.`);let o=e.project.slug,m=e.environments?.[t]?.region||e.project.region||"us-east-1";return{app:r,slug:o,region:m,stackName:Mt(e,t),artifactBucket:rd(o,t),assetsBucket:Hs(o,t)}}async function ks(e,t=8){let r;for(let o=0;o<t;o++)try{return await e()}catch(m){let h=m?.code||m?.name||"",I=String(m?.message||"");if(h==="ResourceConflictException"||/update is in progress|currently in the following state/i.test(I)){r=m,await new Promise((R)=>setTimeout(R,3000));continue}throw m}throw r}var Df=(e,t)=>`releases/${e}/${t}/current.json`;async function Lc(e,t,r,o){try{return await e.getObjectJson(t,Df(r,o))}catch{return null}}async function Of(e,t,r,o,m){await e.putObjectJson(t,Df(r,o),m)}async function $w(e,t){if(!e.secrets)return{};let r=new V(t),o={},m=Array.isArray(e.secrets)?e.secrets.map((h)=>({envName:h.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),secretId:h})):Object.entries(e.secrets).map(([h,I])=>({envName:h,secretId:I}));if(Array.isArray(e.secrets)){let h=new Map;for(let{envName:R,secretId:A}of m)h.set(R,[...h.get(R)??[],A]);let I=[...h.entries()].filter(([,R])=>R.length>1);if(I.length){let R=I.map(([A,E])=>`${A} ← ${E.join(", ")}`).join("; ");throw Error(`serverless secrets: multiple secrets map to the same env var (${R}). Use the map form { ENV_NAME: 'secret/id' } to disambiguate.`)}}for(let{envName:h,secretId:I}of m){let A=(await r.getSecretValue({SecretId:I})).SecretString??"";try{let E=JSON.parse(A);if(E&&typeof E==="object"&&!Array.isArray(E)){for(let[x,N]of Object.entries(E))o[x]=String(N);continue}}catch{}o[h]=A}return o}function Li(e,t){let r={},o=t.DbProxyEndpoint||t.DbEndpoint;if(o)r.DB_CONNECTION="mysql",r.DB_HOST=o,r.DB_PORT="3306",r.DB_DATABASE=r.DB_DATABASE||"app";if(t.CacheEndpoint){if(r.REDIS_HOST=t.CacheEndpoint,r.REDIS_PORT="6379",e.cache?.driver==="elasticache")r.CACHE_STORE="redis",r.CACHE_DRIVER="redis",r.SESSION_DRIVER="redis"}return r}function Kt(e,t,r,o,m,h,I,R={}){let A=e.kind==="php"?yd({cacheDriver:e.cache?.driver==="elasticache"?"redis":"dynamodb"}):{};return{TSCLOUD_LAMBDA_MODE:o,TSCLOUD_ENV:r,MAINTENANCE_MODE:"0",...e.octane?{TSCLOUD_OCTANE:"1"}:{},...e.serveAssets?{TSCLOUD_SERVE_ASSETS:"1"}:{},...e.redirectRobotsTxt===!1?{TSCLOUD_REDIRECT_ROBOTS_TXT:"0"}:{},...A,...R,...t.app.cache?.driver!=="elasticache"?{TSCLOUD_CACHE_TABLE:`${t.slug}-${r}-cache`}:{},...I?{TSCLOUD_QUEUE:I,SQS_QUEUE:I}:{},...h?{ASSET_URL:h}:{},...e.env??{},...m}}function Nw(e){let t=e.slice(e.lastIndexOf(".")).toLowerCase();return{".html":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".txt":"text/plain",".map":"application/json"}[t]??"application/octet-stream"}function*$f(e){for(let t of Tw(e)){let r=xf(e,t);if(Dw(r).isDirectory())yield*$f(r);else yield r}}async function jw(e,t,r,o,m=!1){let h=0;for(let I of $f(r)){let R=Ow(r,I).replace(/\\/g,"/");if(!m&&R.split("/").some((A)=>A.startsWith(".")))continue;await e.putObject({bucket:t,key:`${o}/${R}`,body:xw(I),contentType:Nw(I),cacheControl:"public, max-age=31536000, immutable"}),h++}return h}function Mw(e,t){let r=Object.entries(t).reduce((o,[m,h])=>o+Buffer.byteLength(`${m}=${h}`,"utf8"),0);if(r>4096){let o=Object.entries(t).map(([m,h])=>[m,Buffer.byteLength(`${m}=${h}`,"utf8")]).sort((m,h)=>h[1]-m[1]).slice(0,5).map(([m,h])=>`${m} (${h}B)`).join(", ");throw Error(`${e}: environment variables total ${r}B, over AWS's 4096B limit (${r-4096}B too large). Largest: ${o}. Move large/secret values out of env — store them in Secrets Manager and fetch at cold start.`)}}async function Za(e,t,r,o){Mw(t,r),await ks(()=>e.updateFunctionConfiguration({FunctionName:t,Environment:{Variables:r}})),await e.waitForFunctionActive(t,120);let m=o.kind==="image"?{FunctionName:t,ImageUri:o.imageUri}:{FunctionName:t,S3Bucket:o.bucket,S3Key:o.key};await ks(()=>e.updateFunctionCode(m)),await e.waitForFunctionActive(t,120)}async function Bc(e,t){let o=(await ks(()=>e.publishVersion({FunctionName:t}))).Version;if(!o)throw Error(`publishVersion returned no version for ${t}`);return await ks(()=>e.updateAlias({FunctionName:t,Name:"live",FunctionVersion:o})),o}async function Yo(e,t,r={}){let o=Is(e,t),{app:m,slug:h,region:I,stackName:R,artifactBucket:A}=o,E=r.projectRoot??process.cwd();ji(`Deploying serverless app: ${h} (${t})`),P(`Stack: ${R}`),P(`Region: ${I}`);let x=new a(I),N=new f(I),F=new C(I),z=m.kind==="php",H=m.packaging==="image",K=Js(m),X,oe,ye,ne,fe=[];if(H&&K.usesLayer&&K.layerKind!=="php")throw Error(`packaging: 'image' currently supports PHP and managed Node runtimes. ${K.kind}${K.kind==="node"?` ${K.version}`:""} uses a custom runtime — `+"use the default zip packaging (the runtime layer is built + attached automatically).");if(H){v("Building + pushing container image");let{buildAndPushServerlessImage:Ee}=await import("./chunk-hn2v0b0d.js"),Be=await Ee({app:m,projectRoot:E,region:I,repository:`${h}-${t}`,skipBuild:r.skipBuild,onStep:(It)=>P(` ${It}`)});X=Be.handlers,oe={kind:"image",imageUri:Be.imageUri},ye=Be.tag,fe.push({ParameterKey:"ImageUri",ParameterValue:Be.imageUri})}else{v("Packaging application");let Ee=z?Id({projectRoot:E,app:m,skipBuild:r.skipBuild,onStep:(Ut)=>P(` ${Ut}`)}):await _r({projectRoot:E,app:m,skipBuild:r.skipBuild,onStep:(Ut)=>P(` ${Ut}`)}),Be=dd(h,t,Ee.sha256);if(P(`Artifact: ${Ee.sha256.slice(0,12)} (${(Ee.zip.length/1024).toFixed(0)} KB)`),X=Ee.handlers,ye=Ee.sha256,K.usesLayer){let Ut=K.layerEnvVar?process.env[K.layerEnvVar]:void 0;if(ne=m.layers??(Ut?[Ut]:void 0),!ne?.length){let Fe=K.layerKind==="php"?"serverless:build-php-layer":K.layerKind==="bun"?"serverless:build-bun-layer":"serverless:build-node-layer";throw Error(`${K.kind} apps on provided.al2023 need a runtime layer. Set environments.<env>.app.layers or the ${K.layerEnvVar} env var (build one with \`cloud ${Fe}\`)${K.kind==="node"?", or use a managed Node version (18/20/22)":""}.`)}}if(!await x.bucketExists(A))v(`Creating artifact bucket ${A}`),await x.createBucket(A);if(await x.headObject(A,Be).then((Ut)=>Ut!==null).catch(()=>!1))P("Artifact already uploaded — reusing");else v("Uploading artifact"),await x.putObject({bucket:A,key:Be,body:Ee.zip,contentType:"application/zip"});oe={kind:"zip",bucket:A,key:Be},fe.push({ParameterKey:"ArtifactBucket",ParameterValue:A},{ParameterKey:"ArtifactKey",ParameterValue:Be})}let Ce=ud({config:e,environment:t,app:m,handlers:X,runtimeLayers:ne}),_e=JSON.stringify(Ce.template),he=["CAPABILITY_NAMED_IAM"],Ue=await N.describeStacks({stackName:R}).then((Ee)=>Ee.Stacks[0]?.StackStatus).catch(()=>{return}),me=Ue!==void 0;if(Ue&&/DELETE_IN_PROGRESS/.test(Ue))v("Waiting for an in-progress stack delete to finish"),await N.waitForStack(R,"stack-delete-complete").catch(()=>{}),me=!1;else if(Ue&&/(?:ROLLBACK_COMPLETE|REVIEW_IN_PROGRESS|CREATE_FAILED)/.test(Ue))v(`Deleting unusable stack (status ${Ue}) before recreate`),await N.deleteStack(R),await N.waitForStack(R,"stack-delete-complete").catch(()=>{}),me=!1;v(me?"Updating infrastructure stack":"Creating infrastructure stack");try{if(me)await N.updateStack({stackName:R,templateBody:_e,parameters:fe,capabilities:he}),await N.waitForStack(R,"stack-update-complete");else await N.createStack({stackName:R,templateBody:_e,parameters:fe,capabilities:he,onFailure:"DELETE"}),await N.waitForStack(R,"stack-create-complete")}catch(Ee){if(/No updates are to be performed/i.test(String(Ee?.message)))P("No infrastructure changes");else throw Ee}let We=await N.getStackOutputs(R).catch(()=>({})),nt;if(m.assets){let Ee=xf(E,m.assets);if(_w(Ee)){let Be=m.assetDomain||We.AssetsCdnDomain;nt=Be?`https://${Be}/${ye}`:void 0,v(`Syncing assets from ${m.assets}`);let It=await jw(x,o.assetsBucket,Ee,ye,m.dotFilesAsAssets);P(`Uploaded ${It} asset(s)${nt?` → ${nt}`:""}`)}else Vi(`Assets directory not found: ${Ee}`)}v("Resolving secrets");let wt=await $w(m,I);if(m.database?.connection==="aurora-serverless")try{let Be=await new V(I).getSecretValue({SecretId:`${h}/${t}/db`}),It=JSON.parse(Be.SecretString??"{}");if(It.username)wt.DB_USERNAME=It.username;if(It.password)wt.DB_PASSWORD=It.password}catch(Ee){Vi(`Could not resolve Aurora DB credentials: ${Ee.message}`)}if(!await x.bucketExists(A))await x.createBucket(A);let cr=await Lc(x,A,h,t),st={},Ft=Ce.queueNames[0],dr=Li(m,We);if(v("Activating functions"),st.http=Kt(m,o,t,"http",wt,nt,Ft,dr),await Za(F,Ce.functionNames.http,st.http,oe),st.cli=Kt(m,o,t,"cli",wt,nt,Ft,dr),await Za(F,Ce.functionNames.cli,st.cli,oe),Ce.queueNames.length)st.queue=Kt(m,o,t,"queue",wt,nt,Ft,dr),await Za(F,Ce.functionNames.queue,st.queue,oe);let vt=(m.provisionedConcurrency??0)>0,Y={};if(vt){if(v("Publishing versions + flipping live alias"),Y.http=await Bc(F,Ce.functionNames.http),Y.cli=await Bc(F,Ce.functionNames.cli),Ce.queueNames.length)Y.queue=await Bc(F,Ce.functionNames.queue)}if(await Of(x,A,h,t,{sha:ye,code:oe,previousSha:cr?.sha,previousCode:cr?.code,previousFunctionEnv:cr?.functionEnv,...vt?{functionVersions:Y,previousFunctionVersions:cr?.functionVersions}:{},functionEnv:st,functionNames:{http:Ce.functionNames.http,cli:Ce.functionNames.cli,...Ce.queueNames.length?{queue:Ce.functionNames.queue}:{}},assetUrl:nt,timestamp:new Date().toISOString()}),!r.skipDeployHooks&&m.deploy?.length){v("Running deploy hooks");for(let Ee of m.deploy){P(` deploy: ${Ee}`);let Be=await F.invoke({FunctionName:Ce.functionNames.cli,InvocationType:"RequestResponse",Payload:{command:Ee},LogType:"Tail"});if(Be.FunctionError)throw Ul("Deploy hook failed — the new build is ALREADY LIVE."),P(` Roll back with: cloud serverless:rollback --env ${t}`),Error(`Deploy hook failed (${Ee}): ${Be.Payload}`)}}let be=We.HttpApiEndpoint;if(!r.skipHealthCheck&&be){v("Health check");try{let Ee=await fetch(be,{method:"GET"});P(`GET ${be} → ${Ee.status}`)}catch(Ee){Vi(`Health check could not reach ${be}: ${Ee.message}`)}}Ql(["Serverless deploy complete","",be?`URL: ${be}`:"",`Stack: ${R}`,`Build: ${ye.slice(0,12)}`].filter(Boolean).join(`
40
- `),"green")}async function Kr(e,t){let r=Is(e,t),o=new a(r.region),m=new C(r.region),h=await Lc(o,r.artifactBucket,r.slug,t);if(!h)throw Error("No previous release to redeploy. Run a full deploy first.");ji(`Redeploying ${r.slug} (${t}) — build ${h.sha.slice(0,12)}`);for(let[I,R]of Object.entries(h.functionNames)){if(!R)continue;v(`Re-activating ${I} (${R})`),await Za(m,R,h.functionEnv[I]??{},h.code);let A=h.functionVersions?.[I];if(A)await ks(()=>m.updateAlias({FunctionName:R,Name:"live",FunctionVersion:A}))}tn("Redeploy complete")}async function Wr(e,t){let r=Is(e,t),o=new a(r.region),m=new C(r.region),h=await Lc(o,r.artifactBucket,r.slug,t);if(!h?.previousCode)throw Error("No previous release to roll back to.");ji(`Rolling back ${r.slug} (${t}) → ${h.previousSha?.slice(0,12)}`);for(let[I,R]of Object.entries(h.functionNames)){if(!R)continue;v(`Restoring ${I} (${R})`);let A=h.previousFunctionEnv?.[I]??h.functionEnv[I]??{};await Za(m,R,A,h.previousCode);let E=h.previousFunctionVersions?.[I];if(E)await ks(()=>m.updateAlias({FunctionName:R,Name:"live",FunctionVersion:E}))}await Of(o,r.artifactBucket,r.slug,t,{...h,sha:h.previousSha??h.sha,code:h.previousCode,functionEnv:h.previousFunctionEnv??h.functionEnv,functionVersions:h.previousFunctionVersions??h.functionVersions,previousSha:void 0,previousCode:void 0,previousFunctionEnv:void 0,previousFunctionVersions:void 0,timestamp:new Date().toISOString()}),tn("Rollback complete")}async function Wt(e,t,r,o){let m=Is(e,t),h=new C(m.region),I=`${m.slug}-${t}-http`,A={...(await h.getFunction(I)).Configuration?.Environment?.Variables??{}};if(A.MAINTENANCE_MODE=r?"1":"0",r&&o)A.MAINTENANCE_BYPASS_SECRET=o;if(!r)delete A.MAINTENANCE_BYPASS_SECRET;if(await ks(()=>h.updateFunctionConfiguration({FunctionName:I,Environment:{Variables:A}})),(m.app.provisionedConcurrency??0)>0)await h.waitForFunctionActive(I,120),await Bc(h,I);tn(r?"Application is now in maintenance mode (503)":"Application is live")}async function ze(e,t,r){let o=Is(e,t),m=new C(o.region),h=`${o.slug}-${t}-cli`,I=await m.invoke({FunctionName:h,InvocationType:"RequestResponse",Payload:{command:r},LogType:"Tail"});if(I.FunctionError)throw Error(`Command failed: ${I.Payload}`);return I.Payload??""}async function Nr(e,t){let r=Is(e,t),o=new f(r.region),m=new C(r.region),h=new a(r.region),I="not deployed",R={};try{let{Stacks:H}=await o.describeStacks({stackName:r.stackName});I=H?.[0]?.StackStatus??I;for(let K of H?.[0]?.Outputs??[])if(K.OutputKey)R[K.OutputKey]=K.OutputValue??""}catch{}let A=ld(r.app,r.slug,t),E=r.app.provisionedConcurrency??0,x=["http","cli",...A.length?["queue"]:[]],N=`${r.slug}-${t}`,F=[];for(let H of x){let K=`${N}-${H}`,X={mode:H,name:K,version:"$LATEST"};if(E>0){let oe=await m.getAlias(K,"live").catch(()=>null);if(oe?.FunctionVersion){X.version=oe.FunctionVersion;let ye=await m.getProvisionedConcurrencyConfig(K,"live").catch(()=>null);if(ye)X.provisioned={status:ye.Status??"-",allocated:ye.AllocatedProvisionedConcurrentExecutions??0,requested:ye.RequestedProvisionedConcurrentExecutions??0}}}F.push(X)}let z=await Lc(h,r.artifactBucket,r.slug,t).catch(()=>null);return{slug:r.slug,environment:t,region:r.region,stackStatus:I,endpoint:R.HttpApiEndpoint,assetUrl:z?.assetUrl,scheduler:r.app.scheduler??"on",queues:A,provisionedConcurrency:E,functions:F,lastRelease:z?{sha:z.sha,timestamp:z.timestamp}:void 0}}function Bw(e,t){return`${e}-${t}-db`}async function Nf(e,t,r,o){let m=Is(e,t);if(m.app.database?.connection!=="aurora-serverless")throw Error("No Aurora Serverless v2 database is configured for this environment.");let{RDSClient:h}=await import("./chunk-fdexq9e1.js"),I=new h(m.region),R=Bw(m.slug,t);v(`Scaling ${R} → ${r}–${o} ACUs`),await I.modifyDBCluster({DBClusterIdentifier:R,ServerlessV2ScalingConfiguration:{MinCapacity:r,MaxCapacity:o},ApplyImmediately:!0}),tn(`Scaling applied to ${R} (takes effect shortly).`)}class hi{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new n(Nt(t))}async query(e){let t=new URLSearchParams(l({Version:"2010-08-01",...e})).toString();return this.client.request({service:"monitoring",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:t})}async getMetricStatistics(e){let t={Action:"GetMetricStatistics",Namespace:e.Namespace,MetricName:e.MetricName,StartTime:e.StartTime.toISOString(),EndTime:e.EndTime.toISOString(),Period:e.Period};(e.Statistics??[]).forEach((h,I)=>{t[`Statistics.member.${I+1}`]=h}),(e.ExtendedStatistics??[]).forEach((h,I)=>{t[`ExtendedStatistics.member.${I+1}`]=h}),(e.Dimensions??[]).forEach((h,I)=>{t[`Dimensions.member.${I+1}.Name`]=h.Name,t[`Dimensions.member.${I+1}.Value`]=h.Value});let r=await this.query(t),m=(r.GetMetricStatisticsResult||r)?.Datapoints?.member??[];if(!Array.isArray(m))m=m?[m]:[];return m.map((h)=>{let I={},R=h.ExtendedStatistics?.entry;if(R){if(!Array.isArray(R))R=[R];for(let A of R)if(A?.key!=null)I[A.key]=Number(A.value)}return{Timestamp:h.Timestamp,Sum:h.Sum!=null?Number(h.Sum):void 0,Average:h.Average!=null?Number(h.Average):void 0,Maximum:h.Maximum!=null?Number(h.Maximum):void 0,Minimum:h.Minimum!=null?Number(h.Minimum):void 0,Percentiles:Object.keys(I).length?I:void 0,Unit:h.Unit}})}async getMetricSeries(e){let t=/^p\d/.test(e.Stat);return(await this.getMetricStatistics({Namespace:e.Namespace,MetricName:e.MetricName,Dimensions:e.Dimensions,StartTime:e.StartTime,EndTime:e.EndTime,Period:e.Period,Statistics:t?[]:[e.Stat],ExtendedStatistics:t?[e.Stat]:[]})).slice().sort((o,m)=>new Date(o.Timestamp??0).getTime()-new Date(m.Timestamp??0).getTime()).map((o)=>t?o.Percentiles?.[e.Stat]??0:o[e.Stat]??0)}async describeAlarms(e){let t={Action:"DescribeAlarms"};if(e?.AlarmNamePrefix)t.AlarmNamePrefix=e.AlarmNamePrefix;if(e?.MaxRecords)t.MaxRecords=e.MaxRecords;let r=await this.query(t),m=(r.DescribeAlarmsResult||r)?.MetricAlarms?.member??[];if(!Array.isArray(m))m=m?[m]:[];return m.map((h)=>({AlarmName:h.AlarmName,StateValue:h.StateValue,MetricName:h.MetricName,ComparisonOperator:h.ComparisonOperator,Threshold:h.Threshold!=null?Number(h.Threshold):void 0,Namespace:h.Namespace}))}async putMetricAlarm(e){let t={Action:"PutMetricAlarm",AlarmName:e.AlarmName,Namespace:e.Namespace,MetricName:e.MetricName,ComparisonOperator:e.ComparisonOperator,Threshold:e.Threshold,EvaluationPeriods:e.EvaluationPeriods,Period:e.Period,Statistic:e.Statistic};if(e.AlarmDescription)t.AlarmDescription=e.AlarmDescription;(e.Dimensions??[]).forEach((r,o)=>{t[`Dimensions.member.${o+1}.Name`]=r.Name,t[`Dimensions.member.${o+1}.Value`]=r.Value}),(e.AlarmActions??[]).forEach((r,o)=>{t[`AlarmActions.member.${o+1}`]=r}),await this.query(t)}async deleteAlarms(e){if(!e.length)return;let t={Action:"DeleteAlarms"};e.forEach((r,o)=>{t[`AlarmNames.member.${o+1}`]=r}),await this.query(t)}}class Xu{client;region;constructor(e="us-east-1"){this.region=e,this.client=new n}async call(e,t){return this.client.request({service:"wafv2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSWAF_20190729.${e}`},body:JSON.stringify(t)})}async listWebACLs(e="REGIONAL"){return(await this.call("ListWebACLs",{Scope:e,Limit:100}))?.WebACLs??[]}async getWebACLRules(e,t,r="REGIONAL"){return((await this.call("GetWebACL",{Name:e,Id:t,Scope:r}))?.WebACL?.Rules??[]).map((h)=>({Name:h.Name,Priority:h.Priority,Action:h.Action?Object.keys(h.Action)[0]:h.OverrideAction?Object.keys(h.OverrideAction)[0]:"count"}))}}var Lw=[{index:0,id:"clients",label:"Clients"},{index:1,id:"dns",label:"DNS & TLS"},{index:2,id:"edge",label:"Edge"},{index:3,id:"routing",label:"Routing"},{index:4,id:"apps",label:"Applications"},{index:5,id:"runtime",label:"Background runtime"},{index:6,id:"data",label:"Data services"},{index:7,id:"durability",label:"Durability"}],Fw=[{index:0,id:"clients",label:"Clients"},{index:1,id:"dns",label:"DNS & TLS"},{index:2,id:"edge",label:"Edge"},{index:3,id:"entry",label:"Entry points"},{index:4,id:"compute",label:"Compute"},{index:5,id:"messaging",label:"Messaging & pooling"},{index:6,id:"data",label:"Data services"},{index:7,id:"durability",label:"Durability"}],zw=[{match:/^redis/,kind:"cache",label:"Redis"},{match:/^(?:mysql|mariadb)/,kind:"database",label:"MySQL"},{match:/^postgres/,kind:"database",label:"PostgreSQL"},{match:/^meilisearch/,kind:"database",label:"Meilisearch"},{match:/^vitess|^vtgate/,kind:"database",label:"Vitess"},{match:/^memcached/,kind:"cache",label:"Memcached"}],Uw=/^(?:rpx-gateway|nginx|caddy|traefik|haproxy)$/;function Le(e,t=""){let r=e==null?"":String(e).trim();return r&&r!=="-"&&r!=="—"?r:t}function qw(e){return Array.isArray(e)?e.length:0}function qn(e){let t=Le(e).toLowerCase();if(!t)return"unknown";if(["running","live","active","available","success","ok","healthy","enabled"].includes(t))return"ok";if(["failed","stopped","unreachable","error","critical","disabled"].includes(t))return"bad";if(["configured","creating","pending","degraded","shadowed","warn","unknown"].includes(t))return"warn";return"warn"}function fr(e,t,r){if(r.has(t.source)&&r.has(t.target))e.push(t)}function ft(e,t={}){let r=[],o=[],m=[],h=e.server??{},I=Array.isArray(e.sites)?e.sites:[],R=Array.isArray(e.services)?e.services:[],A=Array.isArray(e.workers)?e.workers:[],E=e.security??{},x=!!e._serverReachable&&!e.metricsUnavailable,N="box";if(!x)m.push("The compute box could not be probed, so live service state is missing; the shape comes from your cloud config.");r.push({id:"internet",label:"Internet",kind:"internet",layer:0,status:"ok",sub:"Public traffic",facts:[],external:!0});let F=[...new Set(I.map((he)=>Le(he.domain)||Le(he.route).split("/")[0]).filter((he)=>he&&he!=="internal"&&he!=="loopback"))],z=Array.isArray(E.tlsCertificates)?E.tlsCertificates:[],H=z.filter((he)=>Number(he?.daysRemaining??999)<21).length;r.push({id:"dns",label:F.length===1?F[0]:"Public domains",kind:"dns",layer:1,status:H?"warn":F.length?"ok":"unknown",sub:F.length>1?`${F.length} domains`:"DNS & certificates",facts:[{label:"Domains",value:F.length?F.slice(0,6).join(", "):"none resolved"},{label:"Certificates",value:z.length?`${z.length} issued`:"none reported"},...H?[{label:"Expiring",value:`${H} within 21 days`}]:[]],href:"/server/security",external:!0});let K=E.firewall??{},X=Array.isArray(E.ports)?E.ports:[];r.push({id:"firewall",label:"Host firewall",kind:"firewall",layer:2,status:qn(K.status),sub:Le(K.summary,"Inbound filtering"),facts:[{label:"State",value:Le(K.status,"unknown")},{label:"Open ports",value:X.length?X.map((he)=>Le(he.listen)).join(", "):"not reported"}],href:"/server/firewall",group:"box"});let oe=R.find((he)=>Uw.test(Le(he.name)));r.push({id:"proxy",label:Le(oe?.name,"Reverse proxy"),kind:"proxy",layer:3,status:oe?qn(oe.status):"unknown",sub:"TLS termination & routing",facts:[{label:"Service",value:Le(oe?.name,"not detected")},{label:"State",value:Le(oe?.status,x?"not running":"not probed")},{label:"Routes",value:`${I.length} site${I.length===1?"":"s"}`}],href:"/server/services",group:"box"});for(let he of I){let Ue=`site:${Le(he.name)}`;if(!Le(he.name))continue;r.push({id:Ue,label:Le(he.name),kind:"site",layer:4,status:qn(he.status),sub:Le(he.runtime,"runtime"),facts:[{label:"Route",value:Le(he.route,"internal")},{label:"Runtime",value:Le(he.runtime,"unknown")},{label:"Delivery",value:Le(he.deploy,"unknown")},{label:"TLS",value:Le(he.tls,"unknown")},...he.responseMs!=null?[{label:"Response",value:`${Math.round(Number(he.responseMs))} ms`}]:[],...he.httpStatus!=null?[{label:"HTTP",value:String(he.httpStatus)}]:[]],href:"/server/sites",group:"box"})}for(let he of A){let Ue=`worker:${Le(he.name)}`;if(!Le(he.name))continue;r.push({id:Ue,label:Le(he.name),kind:"worker",layer:5,status:qn(he.status),sub:`${Number(he.processes??1)} process${Number(he.processes??1)===1?"":"es"}`,facts:[{label:"Processes",value:String(he.processes??1)},{label:"State",value:Le(he.status,"unknown")},...Le(he.site)?[{label:"Site",value:Le(he.site)}]:[]],href:"/operations/jobs",group:"box"})}let ye=e.serverScheduler??{};if(ye.enabled)r.push({id:"scheduler",label:"Scheduler",kind:"scheduler",layer:5,status:"ok",sub:"Cron dispatch",facts:[{label:"Last run",value:Le(ye.lastRun,"unknown")}],href:"/operations/jobs",group:"box"});let ne=R.map((he)=>{let Ue=Le(he.name),me=zw.find((We)=>We.match.test(Ue));return me?{service:he,name:Ue,...me}:null}).filter((he)=>!!he);for(let he of ne)r.push({id:`data:${he.name}`,label:he.label,kind:he.kind,layer:6,status:qn(he.service.status),sub:he.name,facts:[{label:"Unit",value:he.name},{label:"State",value:Le(he.service.status,"unknown")}],href:"/data/services",group:"box"});let fe=e.backup??{};if(fe.enabled)r.push({id:"backup",label:"Backups",kind:"backup",layer:7,status:"ok",sub:Le(fe.destination,"destination"),facts:[{label:"Destination",value:Le(fe.destination,"unknown")},{label:"Schedule",value:Le(fe.schedule,"unknown")},{label:"Retention",value:`${fe.retention??0} copies`},{label:"Last run",value:Le(fe.last,"unknown")}],href:"/data/backups"});let Ce=new Set(r.map((he)=>he.id));fr(o,{source:"internet",target:"dns",flow:"request",label:"https"},Ce),fr(o,{source:"dns",target:"firewall",flow:"request",label:"443/80"},Ce),fr(o,{source:"firewall",target:"proxy",flow:"request"},Ce);for(let he of I){let Ue=`site:${Le(he.name)}`;fr(o,{source:"proxy",target:Ue,flow:"request",label:Le(he.path)||void 0,status:qn(he.status)},Ce)}for(let he of A){let Ue=`worker:${Le(he.name)}`,me=`site:${Le(he.site)}`;if(Ce.has(me))fr(o,{source:me,target:Ue,flow:"async",label:"queue"},Ce);else fr(o,{source:"proxy",target:Ue,flow:"async",label:"queue"},Ce)}for(let he of A)fr(o,{source:"scheduler",target:`worker:${Le(he.name)}`,flow:"async",label:"dispatch"},Ce);let _e=[...I.map((he)=>`site:${Le(he.name)}`),...A.map((he)=>`worker:${Le(he.name)}`)];for(let he of ne)for(let Ue of _e)fr(o,{source:Ue,target:`data:${he.name}`,flow:"data",label:"localhost"},Ce);if(ne.length&&_e.length)m.push("Data-service edges show co-location on the box: every process on it can reach localhost. They are not a declared per-site binding.");for(let he of ne)fr(o,{source:`data:${he.name}`,target:"backup",flow:"backup",label:"snapshot"},Ce);for(let he of I)fr(o,{source:`site:${Le(he.name)}`,target:"backup",flow:"backup"},Ce);return{mode:"server",project:Le(t.project)||Le(e.project?.name)||Le(h.name,"project"),environment:Le(t.environment)||Le(e.environment,"production"),provider:Le(h.provider,"unknown"),region:Le(h.region,"unknown"),generatedAt:new Date().toISOString(),layers:Lw,groups:[{id:"box",label:Le(h.name,"App server"),sub:[Le(h.provider),Le(h.region),Le(h.ip)].filter(Boolean).join(" · ")}],nodes:r,links:o,notes:m}}function $i(e,t={}){let r=[],o=[],m=[],h=e.app??{},I=Array.isArray(e.functions)?e.functions:[],R=Array.isArray(e.queues)?e.queues:[],A=e.metrics??{};if(!I.length)m.push("No Lambda functions were read for this environment, so the compute layer is empty rather than assumed.");r.push({id:"internet",label:"Internet",kind:"internet",layer:0,status:"ok",sub:"Public traffic",facts:[],external:!0});let E=Le(h.url),x=E.replace(/^https?:\/\//,"").split("/")[0];r.push({id:"dns",label:x||"Application domain",kind:"dns",layer:1,status:x?"ok":"unknown",sub:"DNS & certificates",facts:[{label:"Endpoint",value:E||"not resolved"}],external:!0});let N=e.waf;if(N)r.push({id:"waf",label:"WAF",kind:"waf",layer:2,status:qn(N.status??"active"),sub:Le(N.scope,"Managed rules"),facts:[{label:"Web ACL",value:Le(N.name,"unnamed")},...N.blocked!=null?[{label:"Blocked (24h)",value:String(N.blocked)}]:[],{label:"Rules",value:String(qw(e.wafRules))}],href:"/serverless/firewall"});let F=e.assetsInfo;if(F)r.push({id:"cdn",label:"Asset CDN",kind:"cdn",layer:2,status:"ok",sub:Le(F.cdn,"CloudFront"),facts:[{label:"Distribution",value:Le(F.cdn,"unknown")},{label:"Custom domain",value:Le(F.customDomain,"none")}],href:"/serverless/assets"}),r.push({id:"assets",label:"Asset bucket",kind:"storage",layer:6,status:"ok",sub:Le(F.bucket,"S3"),facts:[{label:"Bucket",value:Le(F.bucket,"unknown")},...F.files?[{label:"Objects",value:String(F.files)}]:[],...F.sizeMb?[{label:"Size",value:`${F.sizeMb} MB`}]:[]],href:"/serverless/assets"});let z=I.find((me)=>Le(me.key).startsWith("http"));r.push({id:"gateway",label:"HTTP entry point",kind:"gateway",layer:3,status:z?"ok":"unknown",sub:"Function URL / API Gateway",facts:[{label:"Endpoint",value:E||"not resolved"},{label:"Invocations (24h)",value:String(A.invocations??0)},...A.errorRatePct!=null?[{label:"Error rate",value:`${A.errorRatePct}%`}]:[]],href:"/serverless/metrics"});for(let me of I){let We=`fn:${Le(me.name)}`;if(!Le(me.name))continue;let nt=Number(me.errors??0),wt=Number(me.invocations??0);r.push({id:We,label:Le(me.key,Le(me.name)),kind:"function",layer:4,status:nt>0?wt&&nt/wt>0.02?"bad":"warn":wt?"ok":"idle",sub:Le(me.runtime,"lambda"),facts:[{label:"Function",value:Le(me.name)},{label:"Memory",value:`${me.memory??0} MB`},{label:"Timeout",value:`${me.timeout??0}s`},{label:"Invocations (24h)",value:String(wt)},{label:"Errors (24h)",value:String(nt)},{label:"p95",value:`${me.p95??0} ms`},...me.provisioned?[{label:"Provisioned",value:Le(me.provisioned)}]:[]],href:"/serverless/functions"})}for(let me of R){let We=`queue:${Le(me.name)}`;if(!Le(me.name))continue;let nt=Number(me.dlq??0);r.push({id:We,label:Le(me.name),kind:"queue",layer:5,status:nt>0?"bad":Number(me.visible??0)>0?"warn":"ok",sub:"SQS",facts:[{label:"Visible",value:String(me.visible??0)},{label:"In flight",value:String(me.inFlight??0)},{label:"Processed (24h)",value:String(me.processed??0)},{label:"Dead letter",value:String(nt)}],href:"/serverless/queues"})}let H=e.aurora;if(H)r.push({id:"database",label:"Aurora Serverless",kind:"database",layer:6,status:qn(H.status),sub:Le(H.engine,"aurora"),facts:[{label:"Cluster",value:Le(H.id,"unknown")},{label:"Capacity",value:`${H.currentAcu??0} ACU (${H.minAcu??0}–${H.maxAcu??0})`},{label:"Connections",value:String(H.connections??0)}],href:"/serverless/data"});let K=e.proxy;if(K)r.push({id:"rds-proxy",label:"RDS Proxy",kind:"database",layer:5,status:qn(K.status),sub:"Connection pooling",facts:[{label:"Proxy",value:Le(K.name,"unknown")},{label:"Endpoint",value:Le(K.endpoint,"unknown")},{label:"Pooled",value:String(K.pooledConns??0)}],href:"/serverless/data"});let X=e.redis;if(X)r.push({id:"cache",label:"ElastiCache",kind:"cache",layer:6,status:qn(X.status),sub:Le(X.node,"redis"),facts:[{label:"Group",value:Le(X.id,"unknown")},{label:"Hit rate",value:`${X.hitRate??0}%`}],href:"/serverless/data"});let oe=e.efs;if(oe)r.push({id:"efs",label:"EFS",kind:"filesystem",layer:6,status:qn(oe.status),sub:Le(oe.mount,"/mnt/local"),facts:[{label:"File system",value:Le(oe.id,"unknown")},{label:"Mount",value:Le(oe.mount,"unknown")},{label:"Size",value:`${oe.sizeMb??0} MB`}],href:"/data/volumes"});let ye=e.scheduler??{};if(ye.enabled)r.push({id:"scheduler",label:"Scheduler",kind:"scheduler",layer:3,status:"ok",sub:Le(ye.expression,"rate(1 minute)"),facts:[{label:"Expression",value:Le(ye.expression,"unknown")},{label:"Last run",value:Le(ye.lastRun,"unknown")}],href:"/operations/jobs"});let ne=new Set(r.map((me)=>me.id)),fe=ne.has("waf")?"waf":"gateway";fr(o,{source:"internet",target:"dns",flow:"request",label:"https"},ne),fr(o,{source:"dns",target:fe,flow:"request"},ne),fr(o,{source:"dns",target:"cdn",flow:"request",label:"assets"},ne),fr(o,{source:"waf",target:"gateway",flow:"request",label:"allowed"},ne),fr(o,{source:"cdn",target:"assets",flow:"data",label:"origin"},ne);let Ce=I.filter((me)=>Le(me.key).startsWith("http")),_e=I.filter((me)=>Le(me.key).startsWith("queue")),he=I.filter((me)=>Le(me.key).startsWith("cli"));for(let me of Ce)fr(o,{source:"gateway",target:`fn:${Le(me.name)}`,flow:"request",label:"invoke"},ne);for(let me of he)fr(o,{source:"scheduler",target:`fn:${Le(me.name)}`,flow:"async",label:"schedule"},ne);for(let me of R){for(let We of Ce)fr(o,{source:`fn:${Le(We.name)}`,target:`queue:${Le(me.name)}`,flow:"async",label:"publish"},ne);for(let We of _e)fr(o,{source:`queue:${Le(me.name)}`,target:`fn:${Le(We.name)}`,flow:"async",label:"consume"},ne)}let Ue=["rds-proxy","database","cache","efs","assets"];for(let me of I){let We=`fn:${Le(me.name)}`;if(ne.has("rds-proxy"))fr(o,{source:We,target:"rds-proxy",flow:"data",label:"pooled"},ne);else fr(o,{source:We,target:"database",flow:"data",label:"sql"},ne);for(let nt of Ue.filter((wt)=>wt!=="rds-proxy"&&wt!=="database"))fr(o,{source:We,target:nt,flow:"data"},ne)}return fr(o,{source:"rds-proxy",target:"database",flow:"data",label:"sql"},ne),{mode:"serverless",project:Le(t.project)||Le(h.name,"application"),environment:Le(t.environment)||Le(h.env,"production"),provider:"aws",region:Le(h.region,"unknown"),generatedAt:new Date().toISOString(),layers:Fw,groups:[],nodes:r,links:o,notes:m}}function bm(e,t,r={}){return e==="serverless"?$i(t,r):ft(t,r)}function jf(e){return String(e).padStart(2,"0")}function ha(e){return`${e.getUTCFullYear()}-${jf(e.getUTCMonth()+1)}-${jf(e.getUTCDate())}`}function Vw(e){let t=Math.max(0,Math.round((Date.now()-e)/1000));if(t<60)return`${t}s ago`;let r=Math.round(t/60);if(r<60)return`${r}m ago`;let o=Math.round(r/60);if(o<48)return`${o}h ago`;return`${Math.round(o/24)}d ago`}async function Xa(e,t,r,o,m,h){let I=await e.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:r,Dimensions:[{Name:"FunctionName",Value:t}],StartTime:m,EndTime:h,Period:86400,Statistics:[o]}).catch(()=>[]);if(!I.length)return 0;if(o==="Sum")return I.reduce((R,A)=>R+(A.Sum??0),0);if(o==="Maximum")return Math.max(...I.map((R)=>R.Maximum??0));return I.reduce((R,A)=>R+(A.Average??0),0)/I.length}async function ec(e,t,r,o,m,h,I){let R=await e.getMetricStatistics({Namespace:t,MetricName:r,Dimensions:o,StartTime:h,EndTime:I,Period:86400,Statistics:[m]}).catch(()=>[]);if(!R.length)return 0;if(m==="Sum")return R.reduce((A,E)=>A+(E.Sum??0),0);if(m==="Maximum")return Math.max(...R.map((A)=>A.Maximum??0));return R.reduce((A,E)=>A+(E.Average??0),0)/R.length}async function ep(e,t,r,o,m){let h=await e.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:[{Name:"FunctionName",Value:t}],StartTime:o,EndTime:m,Period:86400,ExtendedStatistics:[r]}).catch(()=>[]);return Math.round(h.reduce((I,R)=>I+(R.Percentiles?.[r]??0),0))}async function Jr(e,t){let r=await Nr(e,t),o=r.region,m=new hi(o),h=new C(o),I=new pe(o),R=new Date,A=new Date(R.getTime()-86400000),E=e.environments?.[t]?.app,x={};x.app={name:r.slug,env:t,region:o,runtime:E?.kind==="php"?`php-${E?.phpVersion??"8.3"} (fpm)`:E?.kind??"node",url:r.endpoint??"",build:r.lastRelease?.sha?.slice(0,7)??"—",deployedAt:r.lastRelease?.timestamp??"—"},x.maintenance={enabled:!1},x.scheduler={enabled:r.scheduler!=="off",expression:r.scheduler==="sub-minute"?"rate(1 minute) · sub-minute":"rate(1 minute)",lastRun:"—"};let N=0,F=0,z=0,H=[],K=[],X=[];for(let fe of r.functions){let[Ce,_e,he,Ue,me,We,nt,wt,cr]=await Promise.all([Xa(m,fe.name,"Invocations","Sum",A,R),Xa(m,fe.name,"Errors","Sum",A,R),Xa(m,fe.name,"Throttles","Sum",A,R),Xa(m,fe.name,"Duration","Average",A,R),h.getFunction(fe.name).catch(()=>null),ep(m,fe.name,"p50",A,R),ep(m,fe.name,"p95",A,R),ep(m,fe.name,"p99",A,R),m.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:fe.name}],StartTime:new Date(R.getTime()-43200000),EndTime:R,Period:3600,Stat:"Sum"}).catch(()=>[])]);N+=Ce,F+=_e,z=Math.max(z,Ue);let st=me?.Configuration?.MemorySize??0,Ft=Object.keys(me?.Configuration?.Environment?.Variables??{}),dr=[],vt=0;try{let{events:be=[]}=await I.filterLogEvents({logGroupName:`/aws/lambda/${fe.name}`,startTime:A.getTime(),limit:120});for(let Ee of be){let Be=(Ee.message??"").trim(),It=/Max Memory Used:\s*(\d+)\s*MB/.exec(Be);if(It)vt=Math.max(vt,Number(It[1]));if(Be&&!/^(?:START|END|REPORT|INIT_START)/.test(Be))X.push({source:fe.mode||fe.name,timestamp:new Date(Ee.timestamp??0).toISOString(),when:Vw(Ee.timestamp??0),message:Be.slice(0,400),level:/error|exception|fatal|panic|traceback/i.test(Be)?"error":/warn|warning|timeout|retr(?:y|ies)|throttl/i.test(Be)?"warn":"info"})}dr=be.filter((Ee)=>!/^(?:START|END|REPORT|INIT_START)/.test((Ee.message??"").trim())).slice(-6).map((Ee)=>({ts:new Date(Ee.timestamp??0).toISOString().slice(11,19),msg:(Ee.message??"").trim().slice(0,120),err:/error|exception|fatal/i.test(Ee.message??"")}))}catch{}let Y=Math.max(1,...cr);H.push({key:fe.mode,name:fe.name,version:fe.version,memory:st,timeout:me?.Configuration?.Timeout??0,runtime:me?.Configuration?.Runtime??"provided.al2023",invocations:Math.round(Ce),errors:Math.round(_e),p95:nt||Math.round(Ue),status:"active",provisioned:fe.provisioned?`${fe.provisioned.allocated}/${fe.provisioned.requested}`:void 0}),K.push({key:fe.mode,name:fe.name,runtime:me?.Configuration?.Runtime??"provided.al2023",arch:me?.Configuration?.Architectures?.[0]??"x86_64",memory:st,timeout:me?.Configuration?.Timeout??0,ephemeral:me?.Configuration?.EphemeralStorage?.Size??512,version:fe.version,concurrency:E?.concurrency??"—",invocations:Math.round(Ce),errors:Math.round(_e),throttles:Math.round(he),p50:We||Math.round(Ue),p95:nt||Math.round(Ue),p99:wt||Math.round(Ue),maxMem:vt,spark:cr.length?cr.map((be)=>Math.round(be/Y*100)):[0],env:Ft.length?Ft:["(none)"],recent:dr.length?dr:[{ts:"—",msg:"no recent events",err:!1}]})}x.functions=H,x.functionsDetail=K,x.serverlessLogs=X.sort((fe,Ce)=>String(Ce.timestamp).localeCompare(String(fe.timestamp))).slice(0,600),x.serverlessLogsEmptyReason=X.length?void 0:"No recent function logs were found in CloudWatch for this environment.";let oe=N?Number((F/N*100).toFixed(2)):0,ye=Math.round(await Xa(m,r.functions[0]?.name??"","ConcurrentExecutions","Maximum",A,R));x.metrics={invocations:Math.round(N),errorRatePct:oe,p95Ms:Math.round(z),coldStartPct:void 0,concurrency:ye,estCostUsd:void 0};try{let fe=new re(o),Ce=[],_e=[],he=0;try{let{QueueUrl:me}=await fe.getQueueUrl(`${r.slug}-${t}-dlq`),{Attributes:We}=await fe.getQueueAttributes(me);he=Number(We.ApproximateNumberOfMessages??0)}catch{}let Ue=E?Gt(E,r.slug,t):[];for(let me of Ue){let We=me.name.replace(`${r.slug}-${t}-`,""),nt=0,wt=0;try{let{QueueUrl:st}=await fe.getQueueUrl(me.name),{Attributes:Ft}=await fe.getQueueAttributes(st);nt=Number(Ft.ApproximateNumberOfMessages??0),wt=Number(Ft.ApproximateNumberOfMessagesNotVisible??0)}catch{}let cr=Math.round(await ec(m,"AWS/SQS","NumberOfMessagesDeleted",[{Name:"QueueName",Value:me.name}],"Sum",A,R));Ce.push({name:We,visible:nt,inFlight:wt,processed:cr,dlq:he}),_e.push({name:me.name,short:We,visible:nt,inFlight:wt,delayed:0,processed:cr,oldestSec:0,concurrency:me.concurrency??E?.queueConcurrency??"—",tries:E?.queueTries??3,visTimeout:(E?.queueTimeout??120)*6,dlq:he})}if(Ce.length)x.queues=Ce;if(_e.length)x.queuesDetail=_e;x.dlqItems=[]}catch{}try{let fe=new f(o),{Stacks:Ce}=await fe.describeStacks({stackName:Mt(e,t)}),_e={};for(let he of Ce?.[0]?.Outputs??[])if(he.OutputKey)_e[he.OutputKey]=he.OutputValue??"";if(E?.database?.connection==="aurora-serverless"){let he=`${r.slug}-${t}-db`,Ue=[{Name:"DBClusterIdentifier",Value:he}],[me,We]=await Promise.all([ec(m,"AWS/RDS","ServerlessDatabaseCapacity",Ue,"Average",A,R),ec(m,"AWS/RDS","DatabaseConnections",Ue,"Maximum",A,R)]);if(x.aurora={id:he,engine:"aurora-mysql",minAcu:E?.database?.minCapacity??0.5,maxAcu:E?.database?.maxCapacity??4,currentAcu:me?Number(me.toFixed(1)):E?.database?.minCapacity??0.5,database:"app",connections:Math.round(We),status:_e.DbEndpoint?"available":"creating"},E?.rdsProxy)x.proxy={name:`${r.slug}-${t}-proxy`,endpoint:_e.DbProxyEndpoint??"—",pooledConns:Math.round(We),status:"available"}}if(E?.cache?.driver==="elasticache"){let he=`${r.slug}-${t}-cache`,Ue=[{Name:"CacheClusterId",Value:`${he}-001`}],[me,We]=await Promise.all([ec(m,"AWS/ElastiCache","CacheHits",Ue,"Sum",A,R),ec(m,"AWS/ElastiCache","CacheMisses",Ue,"Sum",A,R)]),nt=me+We>0?Number((me/(me+We)*100).toFixed(1)):0;x.redis={id:he,node:"cache.t4g.micro",engine:"redis",hitRate:nt,status:_e.CacheEndpoint?"available":"creating"}}if(E?.efs){let he=0;try{if(_e.EfsFileSystemId){let Ue=new tr(o),{FileSystems:me}=await Ue.describeFileSystems({FileSystemId:_e.EfsFileSystemId});he=Number(((me?.[0]?.SizeInBytes?.Value??0)/1048576).toFixed(1))}}catch{}x.efs={id:_e.EfsFileSystemId??"efs",mount:"/mnt/local",sizeMb:he,status:"available"}}x.assetsInfo=_e.AssetsCdnDomain?{bucket:_e.AssetsBucketName??`${r.slug}-${t}-assets`,cdn:_e.AssetsCdnDomain,customDomain:E?.assetDomain??"—",assetUrl:r.assetUrl??"—",files:0,sizeMb:0,cacheHitPct:0,build:x.app.build}:void 0}catch{}if(x.assetsInfo)try{let Ce=await new a(o).list({bucket:x.assetsInfo.bucket,maxKeys:1000});x.assetsInfo.files=Ce.length,x.assetsInfo.sizeMb=Number((Ce.reduce((_e,he)=>_e+(he.Size??0),0)/1048576).toFixed(1)),x.assetsRecent=Ce.slice(0,8).map((_e)=>({path:`/${_e.Key}`,size:`${Math.max(1,Math.round((_e.Size??0)/1024))} KB`,type:_e.Key.split(".").pop()??""}))}catch{}try{if(E?.secrets){let fe=Array.isArray(E.secrets)?E.secrets.map((Ce)=>({key:Ce.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),source:Ce})):Object.entries(E.secrets).map(([Ce,_e])=>({key:Ce,source:String(_e)}));x.secretsList=fe.map((Ce)=>({...Ce,updated:"—"}))}}catch{}try{let fe=new a(o),Ce=`${r.slug}-${t}-deployments`,_e=await fe.getObjectJson(Ce,`deployments/${r.slug}/${t}/history.json`).catch(()=>null);if(_e?.records?.length)x.deploymentsDetail=_e.records.slice(-12).reverse().map((he)=>({sha:(he.sha??"").slice(0,7),status:he.status??"success",when:he.timestamp??"—",took:he.took??"—",by:he.by??"—",version:he.version??"—",hooks:he.hooks??[]}))}catch{}x.metricsTotals={invocations:x.metrics.invocations,errors:Math.round(F),errorRatePct:oe,p95Ms:x.metrics.p95Ms,throttles:K.reduce((fe,Ce)=>fe+Ce.throttles,0),coldStartPct:void 0,estCostUsd:void 0,concurrency:ye},x.metricsPerFn=K.map((fe)=>({key:fe.key,invocations:fe.invocations,errors:fe.errors,throttles:fe.throttles,avgMs:fe.p50,maxMs:fe.p99,costUsd:void 0}));try{x.invSpark=await m.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:r.functions.find((fe)=>fe.mode==="http")?.name??""}],StartTime:new Date(R.getTime()-86400000),EndTime:R,Period:3600,Stat:"Sum"})}catch{}try{let fe=new Ji,Ce=R,_e=new Date(Date.UTC(Ce.getUTCFullYear(),Ce.getUTCMonth(),1)),he=new Date(Date.UTC(Ce.getUTCFullYear(),Ce.getUTCMonth()-1,1)),[Ue,me]=await Promise.all([fe.getCostByService({start:ha(_e),end:ha(Ce),granularity:"MONTHLY"}).catch(()=>[]),fe.getCostByService({start:ha(he),end:ha(_e),granularity:"MONTHLY"}).catch(()=>[])]);if(Ue.length){let We=Ue.reduce((vt,Y)=>vt+Y.amount,0),nt=me.reduce((vt,Y)=>vt+Y.amount,0),wt=Ce.getUTCDate(),cr=new Date(Date.UTC(Ce.getUTCFullYear(),Ce.getUTCMonth()+1,0)).getUTCDate();x.costSummary={monthToDateUsd:Number(We.toFixed(2)),projectedUsd:Number((We/wt*cr).toFixed(2)),lastMonthUsd:Number(nt.toFixed(2)),dailyAvgUsd:Number((We/wt).toFixed(2))},x.costServices=Ue.filter((vt)=>vt.amount>0).sort((vt,Y)=>Y.amount-vt.amount).slice(0,12).map((vt)=>({name:vt.service,usd:Number(vt.amount.toFixed(2)),note:""})),x.metrics.estCostUsd=Number((We/wt).toFixed(2)),x.metricsTotals.estCostUsd=x.metrics.estCostUsd,x.costTrend=await fe.getDailyTotals({start:ha(_e),end:ha(Ce)}).catch(()=>[]);let st=Ue.find((vt)=>/lambda/i.test(vt.service))?.amount??0,Ft=(vt)=>vt.invocations*(vt.p50/1000)*(vt.memory/1024),dr=K.reduce((vt,Y)=>vt+Ft(Y),0)||1;x.costPerFn=K.map((vt)=>({key:vt.key,requests:vt.invocations,gbSec:Math.round(Ft(vt)),usd:Number((st*(Ft(vt)/dr)).toFixed(2))}))}}catch{}if(E?.firewall)try{let fe=await m.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"BlockedRequests",StartTime:A,EndTime:R,Period:86400,Statistics:["Sum"]}).catch(()=>[]),Ce=await m.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"AllowedRequests",StartTime:A,EndTime:R,Period:86400,Statistics:["Sum"]}).catch(()=>[]);x.waf={enabled:!0,scope:"REGIONAL",acl:`${r.slug}-${t}-waf`,allowed24h:Math.round(Ce.reduce((_e,he)=>_e+(he.Sum??0),0)),blocked24h:Math.round(fe.reduce((_e,he)=>_e+(he.Sum??0),0))};try{let _e=new Xu(o),he=await _e.listWebACLs("REGIONAL"),Ue=he.find((me)=>me.Name?.includes(`${r.slug}-${t}`))??he[0];if(Ue?.Name&&Ue.Id){x.waf.acl=Ue.Name;let me=await _e.getWebACLRules(Ue.Name,Ue.Id,"REGIONAL");if(me.length)x.wafRules=me.map((We)=>({name:We.Name??"—",detail:`priority ${We.Priority??0}`,action:We.Action??"count",blocked24h:0}))}}catch{}}catch{}let ne=[];if(x.aurora)ne.push({name:"Aurora Serverless v2",detail:`${x.aurora.id} · ${x.aurora.minAcu}-${x.aurora.maxAcu} ACU`,status:x.aurora.status});if(x.proxy)ne.push({name:"RDS Proxy",detail:x.proxy.name,status:x.proxy.status});if(x.redis)ne.push({name:`ElastiCache (${x.redis.engine})`,detail:`${x.redis.node} · ${x.redis.hitRate}% hit rate`,status:x.redis.status});if(x.efs)ne.push({name:"EFS",detail:`${x.efs.mount} · ${x.efs.sizeMb} MB`,status:x.efs.status});if(ne.length)x.dataServices=ne;if(r.scheduler!=="off"&&E?.kind==="php")try{let fe=await ze(e,t,"schedule:list"),Ce=[];for(let _e of(fe||"").split(`
41
- `)){let he=/^\s*([\d*/,\-\s]+?)\s{2,}(.+?)(?:\s{2,}Next Due.*)?$/.exec(_e);if(he&&/[*\d]/.test(he[1])&&he[1].trim().split(/\s+/).length===5)Ce.push({command:he[2].trim().replace(/^php artisan /,""),cron:he[1].trim(),desc:"",lastRun:"—",lastStatus:"ok"})}if(Ce.length)x.schedulerTasks=Ce}catch{}return x.topology=$i(x,{project:e.project.name,environment:t}),x}function es(e){let t=Number(e);return Number.isFinite(t)&&t>=0?t:null}function Ww(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return null;let t=Date.parse(`${e}T12:00:00.000Z`);return Number.isFinite(t)?new Date(t).toISOString():null}function kl(e,t){if(!e||typeof e!=="object")return[];let r={source:t.name},o=[],m=t.now,h=(E,x,N,F=m)=>{if(x!==null)o.push({name:E,value:x,unit:N,timestamp:F,attributes:r})};h("storage.egress.month",es(e.monthBytes),"bytes"),h("storage.egress.today",es(e.todayBytes),"bytes"),h("storage.egress.projected_month",es(e.projectedMonthBytes),"bytes");let I=es(e.budgetBytes);if(I!==null&&I>0){h("storage.egress.budget",I,"bytes");let E=e.budgetUsedPercent,x=typeof E==="number"&&Number.isFinite(E)?E:es(e.monthBytes)!==null?Math.round(es(e.monthBytes)/I*1000)/10:null;h("storage.egress.budget_used_percent",x,"percent")}let R=t.maxReplayDays??45,A=Array.isArray(e.days)?e.days.slice(-R):[];for(let E of A){let x=Ww(String(E?.date??"")),N=es(E?.bytes);if(!x||N===null)continue;o.push({name:"storage.egress.day",value:N,unit:"bytes",timestamp:x,attributes:r});let F=es(E?.downloads);if(F!==null)o.push({name:"storage.egress.day_downloads",value:F,unit:"count",timestamp:x,attributes:r})}return o}async function Bl(e,t=process.env,r=fetch){let o=e.tokenEnv?t[e.tokenEnv]:void 0,m=await r(e.url,{headers:o?{Authorization:`Bearer ${o}`}:{},signal:AbortSignal.timeout(1e4)});if(!m.ok)throw Error(`HTTP ${m.status}`);return await m.json()}async function Zo(e,t){let r=[],o=[];if(!Array.isArray(e)||e.length===0)return{metrics:r,errors:o};let m=await Promise.all(e.map(async(h)=>{if(!h?.name||!h?.url)return{endpoint:h,error:"egress endpoint needs both a name and a url"};try{let I=await Bl(h,t.env,t.fetchImpl);return{endpoint:h,report:I}}catch(I){return{endpoint:h,error:I instanceof Error?I.message:String(I)}}}));for(let h of m){let I=`egress:${h.endpoint?.name??"unnamed"}`;if("error"in h&&h.error){o.push({source:I,message:h.error});continue}r.push(...kl(h.report,{name:h.endpoint.name,now:t.now}))}return{metrics:r,errors:o}}import{createHash as R_}from"node:crypto";import{existsSync as Zi,mkdtempSync as Gg,readdirSync as AS,rmSync as Gs,statSync as MS}from"node:fs";import{readFile as pi,writeFile as Ws}from"node:fs/promises";import{tmpdir as Lu}from"node:os";import{dirname as A_,extname as _c,join as rr,normalize as C_,relative as P_,resolve as __,sep as T_}from"node:path";import{fileURLToPath as x_}from"node:url";class ho extends Error{status;code;requestId;constructor(e,t,r,o){super(r);this.status=e;this.code=t;this.requestId=o}}class Ld{options;baseUrl;fetchFn;constructor(e){this.options=e;this.baseUrl=e.baseUrl.replace(/\/$/,""),this.fetchFn=e.fetch??fetch}async request(e,t={}){let r=await this.fetchFn(`${this.baseUrl}${e}`,{...t,headers:{accept:"application/json",authorization:`Bearer ${this.options.token}`,...t.headers}}),o=await r.json().catch(()=>({}));if(!r.ok)throw new ho(r.status,o.error?.code??"api_error",o.error?.message??"API request failed.",o.error?.requestId??r.headers.get("x-request-id")??void 0);return o}listProjects(e={}){return this.request(`/api/v1/projects?${new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).map(([t,r])=>[t,String(r)])))}`)}listEnvironments(e,t={}){return this.request(`/api/v1/projects/${encodeURIComponent(e)}/environments?${new URLSearchParams(Object.fromEntries(Object.entries(t).filter(([,r])=>r!==void 0).map(([r,o])=>[r,String(o)])))}`)}listServices(e,t){return this.request(`/api/v1/services?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}listOperations(e){return this.request(`/api/v1/operations${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listComposeTemplates(){return this.request("/api/v1/compose-templates")}listComposeApplications(e,t){return this.request(`/api/v1/compose-applications?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}previewCompose(e){return this.request("/api/v1/compose-applications/preview",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createComposeApplication(e){return this.request("/api/v1/compose-applications",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}composeServices(e){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/services`)}composeAction(e,t,r={}){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}releaseCapabilities(e,t={}){return this.request(`/api/v1/releases/capabilities?${new URLSearchParams({kind:e,health:String(!!t.health),replicas:String(t.replicas??1)})}`)}listReleases(e,t={}){return this.request(`/api/v1/releases?${new URLSearchParams({projectId:e,...t})}`)}createReleaseArtifact(e){return this.request("/api/v1/release-artifacts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createRelease(e){return this.request("/api/v1/releases",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}releaseAction(e,t,r={}){return this.request(`/api/v1/releases/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}createDeployment(e,t){return this.request("/api/v1/deployments",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}detectApplication(e){return this.request("/api/v1/application-detections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}planApplication(e){return this.request("/api/v1/application-plans",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}listApplicationDrafts(e){return this.request(`/api/v1/application-drafts?projectId=${encodeURIComponent(e)}`)}createApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createApplication(e,t){return this.request("/api/v1/applications",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}uploadApplicationArtifact(e,t,r){return this.request("/api/v1/application-artifacts",{method:"POST",headers:{"content-type":"application/octet-stream","x-project-id":e,"x-artifact-filename":t},body:r})}listRegistryConnections(){return this.request("/api/v1/registry-connections")}createRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}disconnectRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({id:e})})}listQueue(e={}){let t=new URLSearchParams(Object.entries(e).filter(([,r])=>r!==void 0).map(([r,o])=>[r,String(o)]));return this.request(`/api/v1/queue?${t}`)}operationLogs(e,t={}){let r=new URLSearchParams(Object.entries(t).filter(([,o])=>o!==void 0).map(([o,m])=>[o,String(m)]));return this.request(`/api/v1/operations/${encodeURIComponent(e)}/logs?${r}`)}streamOperationLogs(e,t=0){return this.fetchFn(`${this.baseUrl}/api/v1/operations/${encodeURIComponent(e)}/logs/stream`,{headers:{accept:"text/event-stream",authorization:`Bearer ${this.options.token}`,"last-event-id":String(t)}})}cancelOperation(e){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/cancel`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}retryOperation(e,t,r=0){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/retry`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({errorClass:t,delayMs:r})})}queueSettings(){return this.request("/api/v1/queue/settings")}updateQueueSettings(e){return this.request("/api/v1/queue/settings",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:"update queue limits",concurrency:e})})}listPreviews(e){return this.request(`/api/v1/previews${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listPreviewDefinitions(e){return this.request(`/api/v1/preview-definitions?projectId=${encodeURIComponent(e)}`)}createPreviewDefinition(e){return this.request("/api/v1/preview-definitions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createPreview(e){return this.request("/api/v1/previews",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}destroyPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/destroy`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:t})})}extendPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/extend`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hours:t})})}rebuildPreview(e){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/rebuild`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}usage(e={}){let t=new URLSearchParams;for(let[r,o]of Object.entries(e))if(o)t.set(r,String(o));return this.request(`/api/v1/usage${t.size>0?`?${t}`:""}`)}usageRollups(e){let t=new URLSearchParams({from:e.from,to:e.to});if(e.projectId)t.set("projectId",e.projectId);if(e.environmentId)t.set("environmentId",e.environmentId);if(e.limit)t.set("limit",String(e.limit));for(let r of e.meters??[])t.append("meter",r);return this.request(`/api/v1/usage/rollups?${t}`)}allowance(e="deploy",t={}){let r=new URLSearchParams({operation:e});if(t.projectId)r.set("projectId",t.projectId);if(t.environmentId)r.set("environmentId",t.environmentId);return this.request(`/api/v1/spend/allowance?${r}`)}budgets(e={}){let t=new URLSearchParams;for(let[r,o]of Object.entries(e))if(o)t.set(r,String(o));return this.request(`/api/v1/spend/budgets${t.size>0?`?${t}`:""}`)}anomalies(e={}){let t=new URLSearchParams;if(e.projectId)t.set("projectId",e.projectId);if(e.since)t.set("since",e.since);if(e.unacknowledged)t.set("unacknowledged","true");return this.request(`/api/v1/spend/anomalies${t.size>0?`?${t}`:""}`)}}import{createHash as $k}from"node:crypto";import{lstatSync as Hw,readdirSync as Kw,readFileSync as Jw}from"node:fs";import{relative as Gw,resolve as Mf,sep as Qw}from"node:path";function Yw(e){return new Map(e.map((t)=>[t.path.replace(/^\.\//,"").replace(/\\/g,"/"),t]))}function Rs(e,t,r){return{path:e,reason:t,weight:r}}function Bf(e){try{return e?.content?JSON.parse(e.content):{}}catch{return{}}}function ya(e,t,r,o,m,h){return{framework:e,strategy:t,confidence:r,evidence:o,defaults:{build:m,runtime:{target:t==="static"?"serverless":t==="serverless"?"serverless":t==="dockerfile"||t==="prebuilt_image"?"container":"server",architecture:"x86_64",port:t==="static"||t==="serverless"?void 0:3000,healthCheck:t==="static"?void 0:{protocol:"http",path:"/health"}}},description:h}}function va(e){let t=Yw(e.slice(0,1e4)),r=[];if(t.has("Dockerfile"))r.push(ya("dockerfile","dockerfile",0.99,[Rs("Dockerfile","A root Dockerfile defines an explicit reproducible build.",1)],{kind:"dockerfile",context:".",dockerfile:"Dockerfile"},"Build the repository with its Dockerfile and run the resulting OCI image."));let o=Bf(t.get("composer.json"));if(t.has("artisan")&&o.require?.["laravel/framework"])r.push(ya("laravel","server",0.98,[Rs("artisan","Laravel Artisan entrypoint is present.",0.45),Rs("composer.json","Requires laravel/framework.",0.55)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",buildCommand:"php artisan config:cache && php artisan route:cache && php artisan view:cache",startCommand:"php artisan serve --host=0.0.0.0 --port=$PORT"},"Install a production Composer tree, warm Laravel caches, and run the HTTP application."));else if(t.has("composer.json"))r.push(ya("php","server",0.82,[Rs("composer.json","Composer metadata identifies a PHP application.",0.8)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",startCommand:"php -S 0.0.0.0:$PORT -t public"},"Install Composer dependencies and run the configured PHP document root."));let m=Bf(t.get("package.json"));if(t.has("package.json")){let h=t.has("bun.lock")||t.has("bun.lockb")||m.engines?.bun,I=h?"bun":"node",R=h?"bun":"node",A=[Rs("package.json",`Defines ${m.scripts?.build?"build and ":""}${m.scripts?.start?"start ":""}scripts.`,0.55)];if(h)A.push(Rs(t.has("bun.lock")?"bun.lock":t.has("bun.lockb")?"bun.lockb":"package.json","Pins the Bun package manager/runtime.",0.35));let E=!!(m.dependencies?.vite||m.devDependencies?.vite||m.dependencies?.["@stacksjs/bunpress"]||m.devDependencies?.["@stacksjs/bunpress"])&&!m.scripts?.start,x=E?{kind:"static",installCommand:`${I} install --frozen-lockfile`,buildCommand:`${I} run build`,publishDirectory:"dist"}:{kind:"server",runtime:I,installCommand:`${I} install --frozen-lockfile`,buildCommand:m.scripts?.build?`${I} run build`:void 0,startCommand:m.scripts?.start?`${I} run start`:I==="bun"?"bun run index.ts":"node index.js"};r.push(ya(R,x.kind,Math.min(0.94,A.reduce((N,F)=>N+F.weight,0)),A,x,E?"Install dependencies, build static assets, and publish the output directory.":`Install dependencies, build if configured, and start the ${I} server.`))}if(!r.length&&(t.has("index.html")||t.has("public/index.html")))r.push(ya("static","static",0.78,[Rs(t.has("index.html")?"index.html":"public/index.html","A static HTML entrypoint is present.",0.78)],{kind:"static",publishDirectory:t.has("index.html")?".":"public"},"Publish the static directory without a runtime process."));if(!r.length)r.push(ya("unknown","buildpack",0.2,[],{kind:"buildpack",runtime:"node"},"No supported framework signature was conclusive; choose commands and runtime manually."));return r.sort((h,I)=>I.confidence-h.confidence||h.framework.localeCompare(I.framework))}function tp(e,t={}){let r=Mf(e),o=t.maxFiles??1e4,m=t.maxContentBytes??262144,h=[],I=new Set(["Dockerfile","package.json","composer.json","index.html","public/index.html","bun.lock","bun.lockb","artisan"]),R=new Set([".git",".ts-cloud",".cache",".next",".nuxt",".output",".turbo",".bun","node_modules","vendor","pantry","dist","build","coverage"]),A=(E)=>{for(let x of Kw(E).sort()){if(R.has(x))continue;let N=Mf(E,x),F=Gw(r,N).split(Qw).join("/");if(!F||F.startsWith("../"))throw Error("Detection path escaped the application root");let z=Hw(N);if(z.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${F}`);if(z.isDirectory())A(N);else if(z.isFile()){if(h.length>=o)throw Error("Application file-count limit exceeded");let H={path:F,size:z.size};if(I.has(F)&&z.size<=m)H.content=Jw(N,"utf8");h.push(H)}}};return A(r),h}function np(e){if(Array.isArray(e))return`[${e.map(np).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${np(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function tc(e){return!!e&&!e.startsWith("/")&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function An(e,t,r,o){return{path:e,code:t,message:r,alternatives:o}}function rp(e){return JSON.parse(JSON.stringify(e))}function Zw(e){let t=Object.fromEntries(Object.entries(e.environment??{}).map(([r,o])=>[r,typeof o==="string"?o:`\${${o.secretRef}}`]));if(e.build.kind==="prebuilt_image"||e.build.kind==="dockerfile")return rp({infrastructure:{containers:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,cpu:e.runtime.cpu,memory:e.runtime.memoryMb,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,environment:t}}}});if(e.runtime.target==="serverless"||e.build.kind==="serverless")return rp({serverless:{apps:{[e.slug]:{source:e.source,build:e.build,architecture:e.runtime.architecture,environment:t,domain:e.domain}}}});return rp({sites:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,env:t,domain:e.domain?.hostname}}})}function Vn(e,t=[]){let r=[],o=(H)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(H),m=Object.fromEntries(Object.entries(e.environment??{}).map(([H,K])=>{if(typeof K==="string"&&o(H))return r.push(An(`environment.${H}`,"write_only_secret_required",`${H} must be supplied through the write-only secrets boundary.`)),[H,{secretRef:H}];return[H,K]})),h=e.build;if(e.build.kind==="dockerfile"&&e.build.buildArgs){let H=Object.fromEntries(Object.entries(e.build.buildArgs).map(([K,X])=>{if(o(K))return r.push(An(`build.buildArgs.${K}`,"write_only_build_secret_required",`${K} must be declared in secretNames instead of buildArgs.`)),[K,"[REDACTED]"];return[K,X]}));h={...e.build,buildArgs:H}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.slug))r.push(An("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!tc((e.source.kind==="git"?e.source.monorepoRoot:e.source.kind==="local"?e.source.root:".")??"."))r.push(An("source","unsafe_source_root","Source root must stay inside the source tree."));if(e.source.kind==="git"&&e.source.sparsePaths?.some((H)=>!tc(H)))r.push(An("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(e.build.kind==="dockerfile"&&(!tc(e.build.context)||!tc(e.build.dockerfile)))r.push(An("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(e.build.kind==="static"&&!tc(e.build.publishDirectory))r.push(An("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(e.build.kind==="server"&&!e.build.startCommand.trim())r.push(An("build.startCommand","missing_start_command","A server start command is required.",["Use static output","Use a Dockerfile"]));if(e.source.kind==="image"&&e.build.kind!=="prebuilt_image")r.push(An("build.kind","image_requires_prebuilt","An OCI image source must use the prebuilt-image strategy.",["Select prebuilt image"]));if(e.build.kind==="prebuilt_image"&&e.runtime.target!=="container")r.push(An("runtime.target","image_requires_container","Prebuilt images require the container runtime target.",["Select container target"]));if(e.runtime.target==="serverless"&&e.build.kind==="dockerfile")r.push(An("runtime.target","unsupported_serverless_dockerfile","Dockerfile builds currently target the container service path.",["Select container target","Select serverless package"]));if(e.runtime.port!==void 0&&(!Number.isInteger(e.runtime.port)||e.runtime.port<1||e.runtime.port>65535))r.push(An("runtime.port","invalid_port","Port must be an integer from 1 to 65535."));let I=e.runtime.healthCheck;if(I&&I.protocol!=="tcp"&&(!I.path||!I.path.startsWith("/")||/[\r\n]/.test(I.path)))r.push(An("runtime.healthCheck.path","invalid_health_path","HTTP health checks require a path beginning with /."));if(e.domain?.hostname&&(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i.test(e.domain.hostname)||e.domain.hostname.includes("..")))r.push(An("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let R=Object.values(m).flatMap((H)=>typeof H==="object"?[H.secretRef]:[]),A=[...new Set([...e.requiredSecretNames??[],...e.build.kind==="dockerfile"?e.build.secretNames??[]:[],...R])].sort(),E=new Set(t),x=A.filter((H)=>!E.has(H)),N={apiVersion:"ts-cloud.dev/v1",kind:"Application",metadata:{name:e.name,slug:e.slug,projectId:e.projectId,environmentId:e.environmentId},spec:{source:e.source,build:h,runtime:e.runtime,environment:m,domain:e.domain}},F=[...new Set([e.source.kind==="git"?"git:read":e.source.kind==="image"?"registry:pull":e.source.kind==="artifact"?"artifact:inspect":"filesystem:read",e.runtime.target==="container"?"containers":e.runtime.target==="serverless"?"serverless":"servers",e.domain?"dns":""])].filter(Boolean).sort(),z=[...new Set([e.runtime.target,e.runtime.cpu?`${e.runtime.cpu} vCPU`:"",e.runtime.memoryMb?`${e.runtime.memoryMb} MB memory`:"",(e.runtime.minInstances??0)>0?`${e.runtime.minInstances} minimum instances`:"scales from zero where supported",e.domain?"managed DNS/TLS":""])].filter(Boolean);return{valid:r.length===0&&x.length===0,issues:r,missingSecrets:x,manifest:N,configPatch:Zw({...e,build:h,environment:m}),capabilityRequirements:F,costDrivers:z,serializedManifest:`${np(N)}
39
+ `;function Af(e){let t=e;return String(t?.code||t?.name||t?.statusCode||"")}function dw(e){return["NoSuchEntity","ResourceNotFoundException","404"].includes(Af(e))}function Ef(e){return["EntityAlreadyExists","ResourceAlreadyExistsException","ResourceConflictException","409"].includes(Af(e))}function Rf(e,t){let r=e?.Items;if(!r)return[];if(Array.isArray(r))return r;let o=r[t];if(o===void 0)return[];return Array.isArray(o)?o:[o]}function Yu(e){let t=e?.Aliases?.Items;if(Array.isArray(t))return t.map(String);if(typeof t==="string")return[t];return[]}function lw(e){if(!/^[A-Z0-9]{8,32}$/.test(e.distributionId))throw Error("CloudFront distribution ID is invalid");if(!/^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9-]{2,63}$/.test(e.expectedAlias))throw Error("Expected CloudFront alias is invalid");if(!/^[A-Za-z0-9-_]{1,64}$/.test(e.functionName))throw Error("Lambda function name is invalid");let t=e.pathPattern?.startsWith("/")?e.pathPattern:`/${e.pathPattern||"api/*"}`;if(t==="/"||t==="/*"||!t.endsWith("*"))throw Error("API path must be a non-default wildcard pattern such as /api/*");let r=e.originId||`${e.functionName}-url`,o=e.roleName||`${e.functionName}-execution`;if(!/^[A-Za-z0-9_.-]{1,64}$/.test(o))throw Error("IAM role name is invalid");let m=e.memorySize??256,h=e.timeout??10,I=e.logRetentionDays??14;if(m<128||m>10240)throw Error("Lambda memory must be between 128 and 10240 MB");if(h<1||h>900)throw Error("Lambda timeout must be between 1 and 900 seconds");return{region:e.region||"us-east-1",pathPattern:t,originId:r,roleName:o,memorySize:m,timeout:h,logRetentionDays:I}}function Am(e){let t=e.region||"us-east-1";return{cloudfront:new y(e.profile),iam:new ge(t,e.profile),lambda:new C(t,e.profile),logs:new pe(t,e.profile),sts:new ue(t,e.profile),sleep:(r)=>new Promise((o)=>setTimeout(o,r))}}async function EA(e,t){let r=lw(e),o=t||Am({profile:e.profile,region:r.region}),[m,h,I]=await Promise.all([o.sts.getCallerIdentity(),o.cloudfront.getDistribution(e.distributionId),o.cloudfront.getDistributionConfig(e.distributionId)]);if(!m.Account)throw Error("AWS identity did not return an account ID");if(!h.Enabled)throw Error(`CloudFront distribution ${e.distributionId} is disabled`);if(!(Yu(h).length?Yu(h):Yu(I.DistributionConfig)).includes(e.expectedAlias))throw Error(`Distribution ${e.distributionId} does not contain expected alias ${e.expectedAlias}`);let A,E=!0;try{A=await o.iam.getRole({RoleName:r.roleName})}catch(st){if(!dw(st))throw st;E=!1}let x=A?.Arn||`arn:aws:iam::${m.Account}:role/${r.roleName}`,N=await o.lambda.functionExists(e.functionName),F=N?await o.lambda.getFunctionUrl(e.functionName):null,z=await o.cloudfront.listOriginAccessControls(),H=`${e.functionName}-lambda-url`,K=z.some((st)=>st.Name===H&&st.OriginAccessControlOriginType==="lambda"),X=Rf(I.DistributionConfig.Origins,"Origin"),oe=Rf(I.DistributionConfig.CacheBehaviors,"CacheBehavior"),ye=X.some((st)=>String(st.Id)===r.originId),ne=oe.some((st)=>String(st.PathPattern)===r.pathPattern),fe=[...!E?[`create IAM execution role ${r.roleName}`]:[`reconcile IAM execution policy ${r.roleName}`],...N?[`update Lambda ${e.functionName} code and configuration`]:[`create Lambda ${e.functionName}`],...!F?["create private AWS_IAM function URL"]:[],...!K?[`create Lambda origin access control ${H}`]:[],"grant CloudFront function-URL and invocation permissions",`${ne?"reconcile":"add"} ${r.pathPattern} behavior without changing the default behavior`],Ce={command:`cloud cdn:origin:remove ${e.distributionId} FUNCTION_URL_HOST --id ${r.originId} --path '${r.pathPattern}' --apply --confirm 'remove:${e.distributionId}:${r.pathPattern}'`,removeFunction:!N,removeRole:!E},xe={mode:e.apply?"apply":"plan",accountId:m.Account,identityArn:m.Arn,distribution:{id:h.Id,arn:h.ARN,alias:e.expectedAlias,domainName:h.DomainName,status:h.Status},function:{name:e.functionName,existed:N,runtime:"nodejs22.x",urlExisted:!!F,url:F?.FunctionUrl},role:{name:r.roleName,existed:E,arn:x},origin:{id:r.originId,pathPattern:r.pathPattern,existed:ye,behaviorExisted:ne,accessControlExisted:K},changes:fe,rollback:Ce,applied:!1};if(!e.apply)return xe;let he=`${e.distributionId}:${r.pathPattern}`;if(e.confirm!==he)throw Error(`Pass exact confirmation token ${he} to mutate the live distribution`);if(!A)A=await o.iam.createRole({RoleName:r.roleName,Description:`Execution role for ${e.functionName}`,AssumeRolePolicyDocument:JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]}),Tags:[{Key:"ManagedBy",Value:"ts-cloud"}]});await o.iam.putRolePolicy({RoleName:r.roleName,PolicyName:"lambda-logs",PolicyDocument:JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:`arn:aws:logs:${r.region}:${m.Account}:log-group:/aws/lambda/${e.functionName}:*`}]})});try{await o.logs.createLogGroup(`/aws/lambda/${e.functionName}`,{ManagedBy:"ts-cloud"})}catch(st){if(!Ef(st))throw st}await o.logs.putRetentionPolicy(`/aws/lambda/${e.functionName}`,r.logRetentionDays);let Ue=e.code||cw;if(N)await o.lambda.updateFunctionCodeInline(e.functionName,Ue,"index.mjs"),await o.lambda.waitForFunctionActive(e.functionName),await o.lambda.updateFunctionConfiguration({FunctionName:e.functionName,Runtime:"nodejs22.x",Role:A.Arn,Handler:"index.handler",Description:`Private API origin for ${e.expectedAlias}`,Timeout:r.timeout,MemorySize:r.memorySize});else{let st;for(let Ft=0;Ft<8;Ft++)try{await o.lambda.createFunctionWithCode({FunctionName:e.functionName,Runtime:"nodejs22.x",Role:A.Arn,Handler:"index.handler",Code:Ue,Filename:"index.mjs",Description:`Private API origin for ${e.expectedAlias}`,Timeout:r.timeout,MemorySize:r.memorySize}),st=void 0;break}catch(dr){if(st=dr,!String(dr.message).toLowerCase().includes("role"))throw dr;await o.sleep(1000)}if(st)throw st}await o.lambda.waitForFunctionActive(e.functionName);let me=F||await o.lambda.createFunctionUrl({FunctionName:e.functionName,AuthType:"AWS_IAM",InvokeMode:"BUFFERED"});if(!me.FunctionUrl)throw Error("Lambda did not return a function URL");let He=new URL(me.FunctionUrl).hostname,nt=await o.cloudfront.findOrCreateOriginAccessControl(H,"lambda"),wt=h.ARN||`arn:aws:cloudfront::${m.Account}:distribution/${e.distributionId}`,cr=[{FunctionName:e.functionName,StatementId:"AllowCloudFrontFunctionUrl",Action:"lambda:InvokeFunctionUrl",Principal:"cloudfront.amazonaws.com",SourceArn:wt,FunctionUrlAuthType:"AWS_IAM"},{FunctionName:e.functionName,StatementId:"AllowCloudFrontInvoke",Action:"lambda:InvokeFunction",Principal:"cloudfront.amazonaws.com",SourceArn:wt,InvokedViaFunctionUrl:!0}];for(let st of cr)try{await o.lambda.addPermission(st)}catch(Ft){if(!Ef(Ft))throw Ft}return await o.cloudfront.upsertExistingDistributionOrigin(e.distributionId,{id:r.originId,domainName:He,pathPattern:r.pathPattern,originAccessControlId:nt.Id}),{...xe,function:{...xe.function,url:me.FunctionUrl},applied:!0}}async function vA(e){let t=`https://${e.alias}/`,r=`https://${e.alias}/api/health`,o=await fetch(t,{redirect:"follow",headers:{"cache-control":"no-cache"}}),m=new Uint8Array(await o.arrayBuffer()),h=aw("sha256").update(m).digest("hex"),I=Date.now(),R=await fetch(r,{redirect:"follow",headers:{"cache-control":"no-cache"}}),A=Date.now()-I,E=await R.text(),x=E;try{x=JSON.parse(E)}catch{}let N;if(e.logs&&e.functionName){let F=await e.logs.filterLogEvents({logGroupName:`/aws/lambda/${e.functionName}`,startTime:I-60000,filterPattern:'"Init Duration"',limit:25});for(let z of F.events||[]){let H=z.message?.match(/Init Duration:\s*([0-9.]+)\s*ms/i);if(H)N=Number(H[1])}}return{frontend:{url:t,status:o.status,sha256:h,unchanged:e.expectedFrontendSha256?h===e.expectedFrontendSha256:void 0,bytes:m.byteLength},api:{url:r,status:R.status,latencyMs:A,healthy:R.ok&&!!x?.ok,body:x},coldStart:{observed:N!==void 0,initDurationMs:N},verifiedAt:(e.now?.()||new Date).toISOString()}}function TA(e){let t=(e.memoryMb||256)/1024,r=Math.max(0,e.requests-(e.includeFreeTier===!1?0:1e6)),o=Math.max(0,e.requests*(e.averageDurationMs/1000)*t-(e.includeFreeTier===!1?0:400000)),m=r/1e6*0.2+o*0.0000166667,h=9.010025,I=16.425;return{lambdaUsd:Number(m.toFixed(2)),alwaysOnFargateAndAlbUsd:Number(25.435025000000003 .toFixed(2)),assumptions:["us-east-1 public list rates snapshot, July 2026","Lambda x86 request and duration pricing with optional monthly free tier","Fargate comparison uses one always-on 0.25 vCPU/0.5 GB task plus one ALB before LCU charges","excludes CloudFront, data transfer, logs, taxes, and application data services"]}}import{createHash as uw}from"node:crypto";function pw(e){let t=e;return String(t?.code||t?.name||t?.statusCode||"")}function mw(e){return pw(e)==="ValidationError"&&String(e.message).includes("does not exist")}function gw(e){return Object.fromEntries((e||[]).map((t)=>[t.OutputKey,t.OutputValue]))}function fw(e){let t=e?.Aliases?.Items??e?.Aliases;if(Array.isArray(t))return t.map(String);if(typeof t==="string")return[t];return[]}function Cf(e){if(!/^[a-z][a-z0-9-]{1,62}$/.test(e.slug))throw Error("Slug must be a lowercase DNS-safe identifier");if(!/^[A-Z0-9]{8,32}$/.test(e.distributionId))throw Error("CloudFront distribution ID is invalid");if(!/^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9-]{2,63}$/.test(e.expectedAlias))throw Error("Expected distribution alias is invalid");let t=e.imageUri.match(/@((?:sha256:)[a-f0-9]{64})$/i)?.[1];if(!t)throw Error("Container image must use an immutable ECR digest URI ending in @sha256:<64 hex>");let r=e.stackName||`${e.slug}-backend`;if(!/^[A-Za-z][A-Za-z0-9-]{0,127}$/.test(r))throw Error("CloudFormation stack name is invalid");let o=e.pathPattern||"/api/*";if(!/^\/[A-Za-z0-9_.*?~!$&'()+,;=:@%/-]+\*$/.test(o)||o==="/*")throw Error("Backend path must be a non-default wildcard pattern");let m=e.originId||`${e.slug}-backend`;if(!/^[A-Za-z0-9_.-]{1,128}$/.test(m))throw Error("CloudFront origin ID is invalid");if(e.originVerifySecret&&e.originVerifySecret.length<24)throw Error("Origin verification secret must contain at least 24 characters");if(!!e.originDomain!==!!e.certificateArn)throw Error("A custom origin domain and matching ACM certificate ARN must be provided together");return{stackName:r,region:e.region||"us-east-1",pathPattern:o,originId:m,digest:t}}function ym(e){let t=e.region||"us-east-1";return{cloudformation:new f(t,e.profile),cloudfront:new y(e.profile),sts:new ue(t,e.profile),fetch,sleep:(r)=>new Promise((o)=>setTimeout(o,r))}}function Im(e){let t=Cf(e),r=od({name:e.name,slug:e.slug,domain:e.originDomain||e.expectedAlias,imageUri:e.imageUri,certificateArn:e.certificateArn,originVerifySecret:e.originVerifySecret,desiredCount:e.desiredCount,database:e.database,cache:e.cache,queue:e.queue}),o=sd(r);return o.Description=`Managed backend for existing static frontend ${e.expectedAlias}`,o.Metadata={ManagedBy:"ts-cloud",ExistingDistributionId:e.distributionId,ExistingDistributionAlias:e.expectedAlias,BackendPathPattern:t.pathPattern,ContainerDigest:t.digest},o}async function hw(e,t,r){let o;for(let m=0;m<30;m++){let h=Date.now();try{let I=await e.fetch(t,{redirect:"manual",headers:r?{"x-origin-verify":r}:void 0}),R=Date.now()-h,A=await I.text(),E=A;try{E=JSON.parse(A)}catch{}if(I.ok)return{url:t,status:I.status,latencyMs:R,body:E};o=Error(`origin returned ${I.status}`)}catch(I){o=I}if(m<29)await e.sleep(1e4)}throw Error(`Backend origin did not become healthy: ${o instanceof Error?o.message:String(o)}`)}async function wA(e,t){let r=Cf(e),o=t||ym({region:r.region,profile:e.profile}),[m,h]=await Promise.all([o.sts.getCallerIdentity(),o.cloudfront.getDistribution(e.distributionId)]);if(!m.Account)throw Error("AWS identity did not return an account ID");if(!h.Enabled)throw Error(`CloudFront distribution ${e.distributionId} is disabled`);if(!fw(h).includes(e.expectedAlias))throw Error(`Distribution ${e.distributionId} does not contain expected alias ${e.expectedAlias}`);let I;try{I=(await o.cloudformation.describeStacks({stackName:r.stackName})).Stacks[0]}catch(fe){if(!mw(fe))throw fe}let R=Im(e),A=JSON.stringify(R);if(Buffer.byteLength(A)>51200)throw Error("Generated template exceeds the direct CloudFormation template body limit");let E=Object.values(R.Resources||{}).reduce((fe,Ce)=>(fe[Ce.Type]=(fe[Ce.Type]||0)+1,fe),{}),x=[`cloud cdn:origin:remove ${e.distributionId} ${e.originDomain||"ALB_HOST"} --id ${r.originId} --path '${r.pathPattern}' --profile ${e.profile||"default"} --apply --confirm 'remove:${e.distributionId}:${r.pathPattern}'`,`After CloudFront is deployed, restore external DNS if changed and delete stack ${r.stackName} only with an approved data-retention decision.`],N={mode:e.apply?"apply":"plan",accountId:m.Account,stack:{name:r.stackName,existed:!!I,status:I?.StackStatus,templateSha256:uw("sha256").update(A).digest("hex"),resourceCount:Object.keys(R.Resources||{}).length,resourceTypes:E},distribution:{id:h.Id,alias:e.expectedAlias,domainName:h.DomainName,status:h.Status,pathPattern:r.pathPattern,originId:r.originId},artifact:{imageUri:e.imageUri,digest:r.digest},services:{database:e.database!==!1,cache:e.cache!==!1,queue:e.queue!==!1,mail:"ses",desiredCount:e.desiredCount||1},cloudFrontApplied:!1,dnsApplied:!1,applied:!1,rollback:x};if(!e.apply)return N;let F=`${e.distributionId}:${r.pathPattern}:${r.stackName}`;if(e.confirm!==F)throw Error(`Pass exact confirmation token ${F} to provision the backend and change live routing`);if(I)try{await o.cloudformation.updateStack({stackName:r.stackName,templateBody:A,capabilities:["CAPABILITY_NAMED_IAM"],tags:[{Key:"ManagedBy",Value:"ts-cloud"},{Key:"Application",Value:e.slug}]}),await o.cloudformation.waitForStack(r.stackName,"stack-update-complete")}catch(fe){if(!String(fe.message).includes("No updates are to be performed"))throw fe}else await o.cloudformation.createStack({stackName:r.stackName,templateBody:A,capabilities:["CAPABILITY_NAMED_IAM"],onFailure:"ROLLBACK",tags:[{Key:"ManagedBy",Value:"ts-cloud"},{Key:"Application",Value:e.slug}]}),await o.cloudformation.waitForStack(r.stackName,"stack-create-complete");let z=(await o.cloudformation.describeStacks({stackName:r.stackName})).Stacks[0],H=gw(z?.Outputs),K=H.AppLoadBalancerDnsName;if(!K)throw Error("Backend stack did not return AppLoadBalancerDnsName");let X=!1;if(e.originDomain&&e.originDomain!==K){if(!o.dns)throw Error(`External DNS provider is required to map ${e.originDomain} to ${K}`);let fe=await o.dns.upsertRecord(e.originDomain,{name:e.originDomain,type:"CNAME",content:K,ttl:300});if(!fe.success)throw Error(fe.message||"External DNS update failed");X=!0}let oe=e.originDomain||K,ye=e.certificateArn?"https-only":"http-only",ne=e.skipHealthCheck?void 0:await hw(o,`${ye==="https-only"?"https":"http"}://${oe}/api/health`,e.originVerifySecret);return await o.cloudfront.upsertExistingDistributionOrigin(e.distributionId,{id:r.originId,domainName:oe,pathPattern:r.pathPattern,protocolPolicy:ye,customHeaders:e.originVerifySecret?{"X-Origin-Verify":e.originVerifySecret}:void 0}),{...N,outputs:H,health:ne,cloudFrontApplied:!0,dnsApplied:X,applied:!0}}function RA(e={}){let r={fargate:730*(e.desiredCount||1)*0.012342500000000001,applicationLoadBalancer:16.425,natGateway:32.85,postgres:730*(e.multiAzDatabase?0.032:0.016),redis:23.36};return{monthlyUsd:Number(Object.values(r).reduce((o,m)=>o+m,0).toFixed(2)),components:Object.fromEntries(Object.entries(r).map(([o,m])=>[o,Number(m.toFixed(2))])),assumptions:["us-east-1 public on-demand rate snapshot, July 2026","one 0.25 vCPU/0.5 GB Linux Fargate task unless desiredCount is changed","one ALB before LCU charges and one NAT gateway before data processing","single-AZ db.t4g.micro PostgreSQL by default and two cache.t4g.micro Redis nodes","excludes storage, backups, CloudFront, data transfer, public IPv4, logs, email, queue requests, taxes, and free-tier credits"]}}import{execFileSync as yw}from"node:child_process";import{createHash as vw}from"node:crypto";import{existsSync as Pf,mkdirSync as bw,mkdtempSync as Sw,readdirSync as ww,readFileSync as kw,rmSync as Iw,statSync as _f,writeFileSync as Ew}from"node:fs";import{tmpdir as Rw}from"node:os";import{basename as Aw,join as fa,relative as Cw,resolve as Zu}from"node:path";var Pw=new Set([".git","node_modules","dist","coverage"]);function Tf(e,t=e){let r=[];for(let o of ww(e).sort()){if(Pw.has(o))continue;let m=fa(e,o);if(Xc(m,t))continue;let h=_f(m);if(h.isDirectory())r.push(...Tf(m,t));else if(h.isFile())r.push(Cw(t,m))}return r}function Sm(e){let t=Zu(e);if(!Pf(t)||!_f(t).isDirectory())throw Error(`Container context does not exist: ${t}`);let r=vw("sha256");for(let o of Tf(t))r.update(o),r.update("\x00"),r.update(kw(fa(t,o))),r.update("\x00");return r.digest("hex")}function Cm(e){return{ecr:new Pe(e.region||"us-east-1",e.profile),run:(t,r,o)=>{yw(t,r,{cwd:o?.cwd,env:o?.env,stdio:o?.stdio||"inherit"})}}}async function DA(e,t){let r=Zu(e.context),o=Zu(e.dockerfile||fa(r,"Dockerfile"));if(!Pf(o))throw Error(`Dockerfile does not exist: ${o}`);if(!e.repository.split("/").every((H)=>/^[a-z0-9][a-z0-9._-]*$/.test(H)&&!/[._-]$/.test(H)&&!/[._-]{2}/.test(H)))throw Error("ECR repository name is invalid");let I=t||Cm(e),R=Sm(r),A=`sha-${R.slice(0,20)}`,E="";try{E=(await I.ecr.describeRepositories({repositoryNames:[e.repository]})).repositories?.[0]?.repositoryUri||""}catch{}if(!E)E=(await I.ecr.createRepository({repositoryName:e.repository,imageTagMutability:"IMMUTABLE",imageScanningConfiguration:{scanOnPush:!0},tags:[{Key:"ManagedBy",Value:"ts-cloud"}]})).repository?.repositoryUri||"";if(!E)throw Error(`Could not resolve ECR repository URI for ${e.repository}`);await I.ecr.putLifecyclePolicy({repositoryName:e.repository,lifecyclePolicyText:JSON.stringify({rules:[{rulePriority:1,description:"Retain the newest 25 release images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:25},action:{type:"expire"}}]})});let x=`${E}:${A}`,N=Sw(fa(Rw(),"ts-cloud-container-"));try{I.run("docker",["version"],{stdio:"ignore"}),I.run("docker",["build","--platform",e.platform||"linux/amd64","--provenance=false","--sbom=false","--file",o,"--tag",x,r],{cwd:r});let H=(await I.ecr.getAuthorizationToken()).authorizationData?.[0];if(!H?.authorizationToken||!H.proxyEndpoint)throw Error("ECR did not return Docker authorization data");let K=H.proxyEndpoint.replace(/^https?:\/\//,""),X=fa(N,"docker");bw(X,{recursive:!0}),Ew(fa(X,"config.json"),JSON.stringify({auths:{[K]:{auth:H.authorizationToken}}}),{mode:384}),I.run("docker",["push",x],{env:{...process.env,DOCKER_CONFIG:X}})}finally{Iw(N,{recursive:!0,force:!0})}let z=(await I.ecr.describeImages({repositoryName:e.repository,imageIds:[{imageTag:A}]})).imageDetails?.[0]?.imageDigest;if(!z||!/^sha256:[a-f0-9]{64}$/i.test(z))throw Error(`ECR did not return an immutable digest for ${Aw(x)}`);return{repository:e.repository,tag:A,imageUri:x,digest:z,digestUri:`${E}@${z}`,contextSha256:R}}import{existsSync as _w,readdirSync as Tw,readFileSync as xw,statSync as Dw}from"node:fs";import{join as xf,relative as Ow}from"node:path";function Is(e,t){let r=e.environments?.[t]?.app;if(!r)throw Error(`No serverless app configured for environment '${t}'. Add environments.${t}.app to your config.`);let o=e.project.slug,m=e.environments?.[t]?.region||e.project.region||"us-east-1";return{app:r,slug:o,region:m,stackName:Mt(e,t),artifactBucket:rd(o,t),assetsBucket:Hs(o,t)}}async function ks(e,t=8){let r;for(let o=0;o<t;o++)try{return await e()}catch(m){let h=m?.code||m?.name||"",I=String(m?.message||"");if(h==="ResourceConflictException"||/update is in progress|currently in the following state/i.test(I)){r=m,await new Promise((R)=>setTimeout(R,3000));continue}throw m}throw r}var Df=(e,t)=>`releases/${e}/${t}/current.json`;async function Lc(e,t,r,o){try{return await e.getObjectJson(t,Df(r,o))}catch{return null}}async function Of(e,t,r,o,m){await e.putObjectJson(t,Df(r,o),m)}async function $w(e,t){if(!e.secrets)return{};let r=new V(t),o={},m=Array.isArray(e.secrets)?e.secrets.map((h)=>({envName:h.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),secretId:h})):Object.entries(e.secrets).map(([h,I])=>({envName:h,secretId:I}));if(Array.isArray(e.secrets)){let h=new Map;for(let{envName:R,secretId:A}of m)h.set(R,[...h.get(R)??[],A]);let I=[...h.entries()].filter(([,R])=>R.length>1);if(I.length){let R=I.map(([A,E])=>`${A} ← ${E.join(", ")}`).join("; ");throw Error(`serverless secrets: multiple secrets map to the same env var (${R}). Use the map form { ENV_NAME: 'secret/id' } to disambiguate.`)}}for(let{envName:h,secretId:I}of m){let A=(await r.getSecretValue({SecretId:I})).SecretString??"";try{let E=JSON.parse(A);if(E&&typeof E==="object"&&!Array.isArray(E)){for(let[x,N]of Object.entries(E))o[x]=String(N);continue}}catch{}o[h]=A}return o}function Li(e,t){let r={},o=t.DbProxyEndpoint||t.DbEndpoint;if(o)r.DB_CONNECTION="mysql",r.DB_HOST=o,r.DB_PORT="3306",r.DB_DATABASE=r.DB_DATABASE||"app";if(t.CacheEndpoint){if(r.REDIS_HOST=t.CacheEndpoint,r.REDIS_PORT="6379",e.cache?.driver==="elasticache")r.CACHE_STORE="redis",r.CACHE_DRIVER="redis",r.SESSION_DRIVER="redis"}return r}function Kt(e,t,r,o,m,h,I,R={}){let A=e.kind==="php"?yd({cacheDriver:e.cache?.driver==="elasticache"?"redis":"dynamodb"}):{};return{TSCLOUD_LAMBDA_MODE:o,TSCLOUD_ENV:r,MAINTENANCE_MODE:"0",...e.octane?{TSCLOUD_OCTANE:"1"}:{},...e.serveAssets?{TSCLOUD_SERVE_ASSETS:"1"}:{},...e.redirectRobotsTxt===!1?{TSCLOUD_REDIRECT_ROBOTS_TXT:"0"}:{},...A,...R,...t.app.cache?.driver!=="elasticache"?{TSCLOUD_CACHE_TABLE:`${t.slug}-${r}-cache`}:{},...I?{TSCLOUD_QUEUE:I,SQS_QUEUE:I}:{},...h?{ASSET_URL:h}:{},...e.env??{},...m}}function Nw(e){let t=e.slice(e.lastIndexOf(".")).toLowerCase();return{".html":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".txt":"text/plain",".map":"application/json"}[t]??"application/octet-stream"}function*$f(e){for(let t of Tw(e)){let r=xf(e,t);if(Dw(r).isDirectory())yield*$f(r);else yield r}}async function jw(e,t,r,o,m=!1){let h=0;for(let I of $f(r)){let R=Ow(r,I).replace(/\\/g,"/");if(!m&&R.split("/").some((A)=>A.startsWith(".")))continue;await e.putObject({bucket:t,key:`${o}/${R}`,body:xw(I),contentType:Nw(I),cacheControl:"public, max-age=31536000, immutable"}),h++}return h}function Mw(e,t){let r=Object.entries(t).reduce((o,[m,h])=>o+Buffer.byteLength(`${m}=${h}`,"utf8"),0);if(r>4096){let o=Object.entries(t).map(([m,h])=>[m,Buffer.byteLength(`${m}=${h}`,"utf8")]).sort((m,h)=>h[1]-m[1]).slice(0,5).map(([m,h])=>`${m} (${h}B)`).join(", ");throw Error(`${e}: environment variables total ${r}B, over AWS's 4096B limit (${r-4096}B too large). Largest: ${o}. Move large/secret values out of env — store them in Secrets Manager and fetch at cold start.`)}}async function Za(e,t,r,o){Mw(t,r),await ks(()=>e.updateFunctionConfiguration({FunctionName:t,Environment:{Variables:r}})),await e.waitForFunctionActive(t,120);let m=o.kind==="image"?{FunctionName:t,ImageUri:o.imageUri}:{FunctionName:t,S3Bucket:o.bucket,S3Key:o.key};await ks(()=>e.updateFunctionCode(m)),await e.waitForFunctionActive(t,120)}async function Bc(e,t){let o=(await ks(()=>e.publishVersion({FunctionName:t}))).Version;if(!o)throw Error(`publishVersion returned no version for ${t}`);return await ks(()=>e.updateAlias({FunctionName:t,Name:"live",FunctionVersion:o})),o}async function Yo(e,t,r={}){let o=Is(e,t),{app:m,slug:h,region:I,stackName:R,artifactBucket:A}=o,E=r.projectRoot??process.cwd();ji(`Deploying serverless app: ${h} (${t})`),P(`Stack: ${R}`),P(`Region: ${I}`);let x=new a(I),N=new f(I),F=new C(I),z=m.kind==="php",H=m.packaging==="image",K=Js(m),X,oe,ye,ne,fe=[];if(H&&K.usesLayer&&K.layerKind!=="php")throw Error(`packaging: 'image' currently supports PHP and managed Node runtimes. ${K.kind}${K.kind==="node"?` ${K.version}`:""} uses a custom runtime — `+"use the default zip packaging (the runtime layer is built + attached automatically).");if(H){v("Building + pushing container image");let{buildAndPushServerlessImage:Ee}=await import("./chunk-8fcrgq31.js"),Ne=await Ee({app:m,projectRoot:E,region:I,repository:`${h}-${t}`,skipBuild:r.skipBuild,onStep:(It)=>P(` ${It}`)});X=Ne.handlers,oe={kind:"image",imageUri:Ne.imageUri},ye=Ne.tag,fe.push({ParameterKey:"ImageUri",ParameterValue:Ne.imageUri})}else{v("Packaging application");let Ee=z?Id({projectRoot:E,app:m,skipBuild:r.skipBuild,onStep:(Ut)=>P(` ${Ut}`)}):await _r({projectRoot:E,app:m,skipBuild:r.skipBuild,onStep:(Ut)=>P(` ${Ut}`)}),Ne=dd(h,t,Ee.sha256);if(P(`Artifact: ${Ee.sha256.slice(0,12)} (${(Ee.zip.length/1024).toFixed(0)} KB)`),X=Ee.handlers,ye=Ee.sha256,K.usesLayer){let Ut=K.layerEnvVar?process.env[K.layerEnvVar]:void 0;if(ne=m.layers??(Ut?[Ut]:void 0),!ne?.length){let Le=K.layerKind==="php"?"serverless:build-php-layer":K.layerKind==="bun"?"serverless:build-bun-layer":"serverless:build-node-layer";throw Error(`${K.kind} apps on provided.al2023 need a runtime layer. Set environments.<env>.app.layers or the ${K.layerEnvVar} env var (build one with \`cloud ${Le}\`)${K.kind==="node"?", or use a managed Node version (18/20/22)":""}.`)}}if(!await x.bucketExists(A))v(`Creating artifact bucket ${A}`),await x.createBucket(A);if(await x.headObject(A,Ne).then((Ut)=>Ut!==null).catch(()=>!1))P("Artifact already uploaded — reusing");else v("Uploading artifact"),await x.putObject({bucket:A,key:Ne,body:Ee.zip,contentType:"application/zip"});oe={kind:"zip",bucket:A,key:Ne},fe.push({ParameterKey:"ArtifactBucket",ParameterValue:A},{ParameterKey:"ArtifactKey",ParameterValue:Ne})}let Ce=ud({config:e,environment:t,app:m,handlers:X,runtimeLayers:ne}),xe=JSON.stringify(Ce.template),he=["CAPABILITY_NAMED_IAM"],Ue=await N.describeStacks({stackName:R}).then((Ee)=>Ee.Stacks[0]?.StackStatus).catch(()=>{return}),me=Ue!==void 0;if(Ue&&/DELETE_IN_PROGRESS/.test(Ue))v("Waiting for an in-progress stack delete to finish"),await N.waitForStack(R,"stack-delete-complete").catch(()=>{}),me=!1;else if(Ue&&/(?:ROLLBACK_COMPLETE|REVIEW_IN_PROGRESS|CREATE_FAILED)/.test(Ue))v(`Deleting unusable stack (status ${Ue}) before recreate`),await N.deleteStack(R),await N.waitForStack(R,"stack-delete-complete").catch(()=>{}),me=!1;v(me?"Updating infrastructure stack":"Creating infrastructure stack");try{if(me)await N.updateStack({stackName:R,templateBody:xe,parameters:fe,capabilities:he}),await N.waitForStack(R,"stack-update-complete");else await N.createStack({stackName:R,templateBody:xe,parameters:fe,capabilities:he,onFailure:"DELETE"}),await N.waitForStack(R,"stack-create-complete")}catch(Ee){if(/No updates are to be performed/i.test(String(Ee?.message)))P("No infrastructure changes");else throw Ee}let He=await N.getStackOutputs(R).catch(()=>({})),nt;if(m.assets){let Ee=xf(E,m.assets);if(_w(Ee)){let Ne=m.assetDomain||He.AssetsCdnDomain;nt=Ne?`https://${Ne}/${ye}`:void 0,v(`Syncing assets from ${m.assets}`);let It=await jw(x,o.assetsBucket,Ee,ye,m.dotFilesAsAssets);P(`Uploaded ${It} asset(s)${nt?` → ${nt}`:""}`)}else Vi(`Assets directory not found: ${Ee}`)}v("Resolving secrets");let wt=await $w(m,I);if(m.database?.connection==="aurora-serverless")try{let Ne=await new V(I).getSecretValue({SecretId:`${h}/${t}/db`}),It=JSON.parse(Ne.SecretString??"{}");if(It.username)wt.DB_USERNAME=It.username;if(It.password)wt.DB_PASSWORD=It.password}catch(Ee){Vi(`Could not resolve Aurora DB credentials: ${Ee.message}`)}if(!await x.bucketExists(A))await x.createBucket(A);let cr=await Lc(x,A,h,t),st={},Ft=Ce.queueNames[0],dr=Li(m,He);if(v("Activating functions"),st.http=Kt(m,o,t,"http",wt,nt,Ft,dr),await Za(F,Ce.functionNames.http,st.http,oe),st.cli=Kt(m,o,t,"cli",wt,nt,Ft,dr),await Za(F,Ce.functionNames.cli,st.cli,oe),Ce.queueNames.length)st.queue=Kt(m,o,t,"queue",wt,nt,Ft,dr),await Za(F,Ce.functionNames.queue,st.queue,oe);let vt=(m.provisionedConcurrency??0)>0,Y={};if(vt){if(v("Publishing versions + flipping live alias"),Y.http=await Bc(F,Ce.functionNames.http),Y.cli=await Bc(F,Ce.functionNames.cli),Ce.queueNames.length)Y.queue=await Bc(F,Ce.functionNames.queue)}if(await Of(x,A,h,t,{sha:ye,code:oe,previousSha:cr?.sha,previousCode:cr?.code,previousFunctionEnv:cr?.functionEnv,...vt?{functionVersions:Y,previousFunctionVersions:cr?.functionVersions}:{},functionEnv:st,functionNames:{http:Ce.functionNames.http,cli:Ce.functionNames.cli,...Ce.queueNames.length?{queue:Ce.functionNames.queue}:{}},assetUrl:nt,timestamp:new Date().toISOString()}),!r.skipDeployHooks&&m.deploy?.length){v("Running deploy hooks");for(let Ee of m.deploy){P(` deploy: ${Ee}`);let Ne=await F.invoke({FunctionName:Ce.functionNames.cli,InvocationType:"RequestResponse",Payload:{command:Ee},LogType:"Tail"});if(Ne.FunctionError)throw Ul("Deploy hook failed — the new build is ALREADY LIVE."),P(` Roll back with: cloud serverless:rollback --env ${t}`),Error(`Deploy hook failed (${Ee}): ${Ne.Payload}`)}}let be=He.HttpApiEndpoint;if(!r.skipHealthCheck&&be){v("Health check");try{let Ee=await fetch(be,{method:"GET"});P(`GET ${be} → ${Ee.status}`)}catch(Ee){Vi(`Health check could not reach ${be}: ${Ee.message}`)}}Ql(["Serverless deploy complete","",be?`URL: ${be}`:"",`Stack: ${R}`,`Build: ${ye.slice(0,12)}`].filter(Boolean).join(`
40
+ `),"green")}async function Kr(e,t){let r=Is(e,t),o=new a(r.region),m=new C(r.region),h=await Lc(o,r.artifactBucket,r.slug,t);if(!h)throw Error("No previous release to redeploy. Run a full deploy first.");ji(`Redeploying ${r.slug} (${t}) — build ${h.sha.slice(0,12)}`);for(let[I,R]of Object.entries(h.functionNames)){if(!R)continue;v(`Re-activating ${I} (${R})`),await Za(m,R,h.functionEnv[I]??{},h.code);let A=h.functionVersions?.[I];if(A)await ks(()=>m.updateAlias({FunctionName:R,Name:"live",FunctionVersion:A}))}tn("Redeploy complete")}async function Wr(e,t){let r=Is(e,t),o=new a(r.region),m=new C(r.region),h=await Lc(o,r.artifactBucket,r.slug,t);if(!h?.previousCode)throw Error("No previous release to roll back to.");ji(`Rolling back ${r.slug} (${t}) → ${h.previousSha?.slice(0,12)}`);for(let[I,R]of Object.entries(h.functionNames)){if(!R)continue;v(`Restoring ${I} (${R})`);let A=h.previousFunctionEnv?.[I]??h.functionEnv[I]??{};await Za(m,R,A,h.previousCode);let E=h.previousFunctionVersions?.[I];if(E)await ks(()=>m.updateAlias({FunctionName:R,Name:"live",FunctionVersion:E}))}await Of(o,r.artifactBucket,r.slug,t,{...h,sha:h.previousSha??h.sha,code:h.previousCode,functionEnv:h.previousFunctionEnv??h.functionEnv,functionVersions:h.previousFunctionVersions??h.functionVersions,previousSha:void 0,previousCode:void 0,previousFunctionEnv:void 0,previousFunctionVersions:void 0,timestamp:new Date().toISOString()}),tn("Rollback complete")}async function Wt(e,t,r,o){let m=Is(e,t),h=new C(m.region),I=`${m.slug}-${t}-http`,A={...(await h.getFunction(I)).Configuration?.Environment?.Variables??{}};if(A.MAINTENANCE_MODE=r?"1":"0",r&&o)A.MAINTENANCE_BYPASS_SECRET=o;if(!r)delete A.MAINTENANCE_BYPASS_SECRET;if(await ks(()=>h.updateFunctionConfiguration({FunctionName:I,Environment:{Variables:A}})),(m.app.provisionedConcurrency??0)>0)await h.waitForFunctionActive(I,120),await Bc(h,I);tn(r?"Application is now in maintenance mode (503)":"Application is live")}async function Ke(e,t,r){let o=Is(e,t),m=new C(o.region),h=`${o.slug}-${t}-cli`,I=await m.invoke({FunctionName:h,InvocationType:"RequestResponse",Payload:{command:r},LogType:"Tail"});if(I.FunctionError)throw Error(`Command failed: ${I.Payload}`);return I.Payload??""}async function Nr(e,t){let r=Is(e,t),o=new f(r.region),m=new C(r.region),h=new a(r.region),I="not deployed",R={};try{let{Stacks:H}=await o.describeStacks({stackName:r.stackName});I=H?.[0]?.StackStatus??I;for(let K of H?.[0]?.Outputs??[])if(K.OutputKey)R[K.OutputKey]=K.OutputValue??""}catch{}let A=ld(r.app,r.slug,t),E=r.app.provisionedConcurrency??0,x=["http","cli",...A.length?["queue"]:[]],N=`${r.slug}-${t}`,F=[];for(let H of x){let K=`${N}-${H}`,X={mode:H,name:K,version:"$LATEST"};if(E>0){let oe=await m.getAlias(K,"live").catch(()=>null);if(oe?.FunctionVersion){X.version=oe.FunctionVersion;let ye=await m.getProvisionedConcurrencyConfig(K,"live").catch(()=>null);if(ye)X.provisioned={status:ye.Status??"-",allocated:ye.AllocatedProvisionedConcurrentExecutions??0,requested:ye.RequestedProvisionedConcurrentExecutions??0}}}F.push(X)}let z=await Lc(h,r.artifactBucket,r.slug,t).catch(()=>null);return{slug:r.slug,environment:t,region:r.region,stackStatus:I,endpoint:R.HttpApiEndpoint,assetUrl:z?.assetUrl,scheduler:r.app.scheduler??"on",queues:A,provisionedConcurrency:E,functions:F,lastRelease:z?{sha:z.sha,timestamp:z.timestamp}:void 0}}function Bw(e,t){return`${e}-${t}-db`}async function Nf(e,t,r,o){let m=Is(e,t);if(m.app.database?.connection!=="aurora-serverless")throw Error("No Aurora Serverless v2 database is configured for this environment.");let{RDSClient:h}=await import("./chunk-eadp23eh.js"),I=new h(m.region),R=Bw(m.slug,t);v(`Scaling ${R} → ${r}–${o} ACUs`),await I.modifyDBCluster({DBClusterIdentifier:R,ServerlessV2ScalingConfiguration:{MinCapacity:r,MaxCapacity:o},ApplyImmediately:!0}),tn(`Scaling applied to ${R} (takes effect shortly).`)}class hi{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new n(Nt(t))}async query(e){let t=new URLSearchParams(l({Version:"2010-08-01",...e})).toString();return this.client.request({service:"monitoring",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:t})}async getMetricStatistics(e){let t={Action:"GetMetricStatistics",Namespace:e.Namespace,MetricName:e.MetricName,StartTime:e.StartTime.toISOString(),EndTime:e.EndTime.toISOString(),Period:e.Period};(e.Statistics??[]).forEach((h,I)=>{t[`Statistics.member.${I+1}`]=h}),(e.ExtendedStatistics??[]).forEach((h,I)=>{t[`ExtendedStatistics.member.${I+1}`]=h}),(e.Dimensions??[]).forEach((h,I)=>{t[`Dimensions.member.${I+1}.Name`]=h.Name,t[`Dimensions.member.${I+1}.Value`]=h.Value});let r=await this.query(t),m=(r.GetMetricStatisticsResult||r)?.Datapoints?.member??[];if(!Array.isArray(m))m=m?[m]:[];return m.map((h)=>{let I={},R=h.ExtendedStatistics?.entry;if(R){if(!Array.isArray(R))R=[R];for(let A of R)if(A?.key!=null)I[A.key]=Number(A.value)}return{Timestamp:h.Timestamp,Sum:h.Sum!=null?Number(h.Sum):void 0,Average:h.Average!=null?Number(h.Average):void 0,Maximum:h.Maximum!=null?Number(h.Maximum):void 0,Minimum:h.Minimum!=null?Number(h.Minimum):void 0,Percentiles:Object.keys(I).length?I:void 0,Unit:h.Unit}})}async getMetricSeries(e){let t=/^p\d/.test(e.Stat);return(await this.getMetricStatistics({Namespace:e.Namespace,MetricName:e.MetricName,Dimensions:e.Dimensions,StartTime:e.StartTime,EndTime:e.EndTime,Period:e.Period,Statistics:t?[]:[e.Stat],ExtendedStatistics:t?[e.Stat]:[]})).slice().sort((o,m)=>new Date(o.Timestamp??0).getTime()-new Date(m.Timestamp??0).getTime()).map((o)=>t?o.Percentiles?.[e.Stat]??0:o[e.Stat]??0)}async describeAlarms(e){let t={Action:"DescribeAlarms"};if(e?.AlarmNamePrefix)t.AlarmNamePrefix=e.AlarmNamePrefix;if(e?.MaxRecords)t.MaxRecords=e.MaxRecords;let r=await this.query(t),m=(r.DescribeAlarmsResult||r)?.MetricAlarms?.member??[];if(!Array.isArray(m))m=m?[m]:[];return m.map((h)=>({AlarmName:h.AlarmName,StateValue:h.StateValue,MetricName:h.MetricName,ComparisonOperator:h.ComparisonOperator,Threshold:h.Threshold!=null?Number(h.Threshold):void 0,Namespace:h.Namespace}))}async putMetricAlarm(e){let t={Action:"PutMetricAlarm",AlarmName:e.AlarmName,Namespace:e.Namespace,MetricName:e.MetricName,ComparisonOperator:e.ComparisonOperator,Threshold:e.Threshold,EvaluationPeriods:e.EvaluationPeriods,Period:e.Period,Statistic:e.Statistic};if(e.AlarmDescription)t.AlarmDescription=e.AlarmDescription;(e.Dimensions??[]).forEach((r,o)=>{t[`Dimensions.member.${o+1}.Name`]=r.Name,t[`Dimensions.member.${o+1}.Value`]=r.Value}),(e.AlarmActions??[]).forEach((r,o)=>{t[`AlarmActions.member.${o+1}`]=r}),await this.query(t)}async deleteAlarms(e){if(!e.length)return;let t={Action:"DeleteAlarms"};e.forEach((r,o)=>{t[`AlarmNames.member.${o+1}`]=r}),await this.query(t)}}class Xu{client;region;constructor(e="us-east-1"){this.region=e,this.client=new n}async call(e,t){return this.client.request({service:"wafv2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSWAF_20190729.${e}`},body:JSON.stringify(t)})}async listWebACLs(e="REGIONAL"){return(await this.call("ListWebACLs",{Scope:e,Limit:100}))?.WebACLs??[]}async getWebACLRules(e,t,r="REGIONAL"){return((await this.call("GetWebACL",{Name:e,Id:t,Scope:r}))?.WebACL?.Rules??[]).map((h)=>({Name:h.Name,Priority:h.Priority,Action:h.Action?Object.keys(h.Action)[0]:h.OverrideAction?Object.keys(h.OverrideAction)[0]:"count"}))}}var Lw=[{index:0,id:"clients",label:"Clients"},{index:1,id:"dns",label:"DNS & TLS"},{index:2,id:"edge",label:"Edge"},{index:3,id:"routing",label:"Routing"},{index:4,id:"apps",label:"Applications"},{index:5,id:"runtime",label:"Background runtime"},{index:6,id:"data",label:"Data services"},{index:7,id:"durability",label:"Durability"}],Fw=[{index:0,id:"clients",label:"Clients"},{index:1,id:"dns",label:"DNS & TLS"},{index:2,id:"edge",label:"Edge"},{index:3,id:"entry",label:"Entry points"},{index:4,id:"compute",label:"Compute"},{index:5,id:"messaging",label:"Messaging & pooling"},{index:6,id:"data",label:"Data services"},{index:7,id:"durability",label:"Durability"}],zw=[{match:/^redis/,kind:"cache",label:"Redis"},{match:/^(?:mysql|mariadb)/,kind:"database",label:"MySQL"},{match:/^postgres/,kind:"database",label:"PostgreSQL"},{match:/^meilisearch/,kind:"database",label:"Meilisearch"},{match:/^vitess|^vtgate/,kind:"database",label:"Vitess"},{match:/^memcached/,kind:"cache",label:"Memcached"}],Uw=/^(?:rpx-gateway|nginx|caddy|traefik|haproxy)$/;function Be(e,t=""){let r=e==null?"":String(e).trim();return r&&r!=="-"&&r!=="—"?r:t}function qw(e){return Array.isArray(e)?e.length:0}function qn(e){let t=Be(e).toLowerCase();if(!t)return"unknown";if(["running","live","active","available","success","ok","healthy","enabled"].includes(t))return"ok";if(["failed","stopped","unreachable","error","critical","disabled"].includes(t))return"bad";if(["configured","creating","pending","degraded","shadowed","warn","unknown"].includes(t))return"warn";return"warn"}function fr(e,t,r){if(r.has(t.source)&&r.has(t.target))e.push(t)}function ft(e,t={}){let r=[],o=[],m=[],h=e.server??{},I=Array.isArray(e.sites)?e.sites:[],R=Array.isArray(e.services)?e.services:[],A=Array.isArray(e.workers)?e.workers:[],E=e.security??{},x=!!e._serverReachable&&!e.metricsUnavailable,N="box";if(!x)m.push("The compute box could not be probed, so live service state is missing; the shape comes from your cloud config.");r.push({id:"internet",label:"Internet",kind:"internet",layer:0,status:"ok",sub:"Public traffic",facts:[],external:!0});let F=[...new Set(I.map((he)=>Be(he.domain)||Be(he.route).split("/")[0]).filter((he)=>he&&he!=="internal"&&he!=="loopback"))],z=Array.isArray(E.tlsCertificates)?E.tlsCertificates:[],H=z.filter((he)=>Number(he?.daysRemaining??999)<21).length;r.push({id:"dns",label:F.length===1?F[0]:"Public domains",kind:"dns",layer:1,status:H?"warn":F.length?"ok":"unknown",sub:F.length>1?`${F.length} domains`:"DNS & certificates",facts:[{label:"Domains",value:F.length?F.slice(0,6).join(", "):"none resolved"},{label:"Certificates",value:z.length?`${z.length} issued`:"none reported"},...H?[{label:"Expiring",value:`${H} within 21 days`}]:[]],href:"/server/security",external:!0});let K=E.firewall??{},X=Array.isArray(E.ports)?E.ports:[];r.push({id:"firewall",label:"Host firewall",kind:"firewall",layer:2,status:qn(K.status),sub:Be(K.summary,"Inbound filtering"),facts:[{label:"State",value:Be(K.status,"unknown")},{label:"Open ports",value:X.length?X.map((he)=>Be(he.listen)).join(", "):"not reported"}],href:"/server/firewall",group:"box"});let oe=R.find((he)=>Uw.test(Be(he.name)));r.push({id:"proxy",label:Be(oe?.name,"Reverse proxy"),kind:"proxy",layer:3,status:oe?qn(oe.status):"unknown",sub:"TLS termination & routing",facts:[{label:"Service",value:Be(oe?.name,"not detected")},{label:"State",value:Be(oe?.status,x?"not running":"not probed")},{label:"Routes",value:`${I.length} site${I.length===1?"":"s"}`}],href:"/server/services",group:"box"});for(let he of I){let Ue=`site:${Be(he.name)}`;if(!Be(he.name))continue;r.push({id:Ue,label:Be(he.name),kind:"site",layer:4,status:qn(he.status),sub:Be(he.runtime,"runtime"),facts:[{label:"Route",value:Be(he.route,"internal")},{label:"Runtime",value:Be(he.runtime,"unknown")},{label:"Delivery",value:Be(he.deploy,"unknown")},{label:"TLS",value:Be(he.tls,"unknown")},...he.responseMs!=null?[{label:"Response",value:`${Math.round(Number(he.responseMs))} ms`}]:[],...he.httpStatus!=null?[{label:"HTTP",value:String(he.httpStatus)}]:[]],href:"/server/sites",group:"box"})}for(let he of A){let Ue=`worker:${Be(he.name)}`;if(!Be(he.name))continue;r.push({id:Ue,label:Be(he.name),kind:"worker",layer:5,status:qn(he.status),sub:`${Number(he.processes??1)} process${Number(he.processes??1)===1?"":"es"}`,facts:[{label:"Processes",value:String(he.processes??1)},{label:"State",value:Be(he.status,"unknown")},...Be(he.site)?[{label:"Site",value:Be(he.site)}]:[]],href:"/operations/jobs",group:"box"})}let ye=e.serverScheduler??{};if(ye.enabled)r.push({id:"scheduler",label:"Scheduler",kind:"scheduler",layer:5,status:"ok",sub:"Cron dispatch",facts:[{label:"Last run",value:Be(ye.lastRun,"unknown")}],href:"/operations/jobs",group:"box"});let ne=R.map((he)=>{let Ue=Be(he.name),me=zw.find((He)=>He.match.test(Ue));return me?{service:he,name:Ue,...me}:null}).filter((he)=>!!he);for(let he of ne)r.push({id:`data:${he.name}`,label:he.label,kind:he.kind,layer:6,status:qn(he.service.status),sub:he.name,facts:[{label:"Unit",value:he.name},{label:"State",value:Be(he.service.status,"unknown")}],href:"/data/services",group:"box"});let fe=e.backup??{};if(fe.enabled)r.push({id:"backup",label:"Backups",kind:"backup",layer:7,status:"ok",sub:Be(fe.destination,"destination"),facts:[{label:"Destination",value:Be(fe.destination,"unknown")},{label:"Schedule",value:Be(fe.schedule,"unknown")},{label:"Retention",value:`${fe.retention??0} copies`},{label:"Last run",value:Be(fe.last,"unknown")}],href:"/data/backups"});let Ce=new Set(r.map((he)=>he.id));fr(o,{source:"internet",target:"dns",flow:"request",label:"https"},Ce),fr(o,{source:"dns",target:"firewall",flow:"request",label:"443/80"},Ce),fr(o,{source:"firewall",target:"proxy",flow:"request"},Ce);for(let he of I){let Ue=`site:${Be(he.name)}`;fr(o,{source:"proxy",target:Ue,flow:"request",label:Be(he.path)||void 0,status:qn(he.status)},Ce)}for(let he of A){let Ue=`worker:${Be(he.name)}`,me=`site:${Be(he.site)}`;if(Ce.has(me))fr(o,{source:me,target:Ue,flow:"async",label:"queue"},Ce);else fr(o,{source:"proxy",target:Ue,flow:"async",label:"queue"},Ce)}for(let he of A)fr(o,{source:"scheduler",target:`worker:${Be(he.name)}`,flow:"async",label:"dispatch"},Ce);let xe=[...I.map((he)=>`site:${Be(he.name)}`),...A.map((he)=>`worker:${Be(he.name)}`)];for(let he of ne)for(let Ue of xe)fr(o,{source:Ue,target:`data:${he.name}`,flow:"data",label:"localhost"},Ce);if(ne.length&&xe.length)m.push("Data-service edges show co-location on the box: every process on it can reach localhost. They are not a declared per-site binding.");for(let he of ne)fr(o,{source:`data:${he.name}`,target:"backup",flow:"backup",label:"snapshot"},Ce);for(let he of I)fr(o,{source:`site:${Be(he.name)}`,target:"backup",flow:"backup"},Ce);return{mode:"server",project:Be(t.project)||Be(e.project?.name)||Be(h.name,"project"),environment:Be(t.environment)||Be(e.environment,"production"),provider:Be(h.provider,"unknown"),region:Be(h.region,"unknown"),generatedAt:new Date().toISOString(),layers:Lw,groups:[{id:"box",label:Be(h.name,"App server"),sub:[Be(h.provider),Be(h.region),Be(h.ip)].filter(Boolean).join(" · ")}],nodes:r,links:o,notes:m}}function $i(e,t={}){let r=[],o=[],m=[],h=e.app??{},I=Array.isArray(e.functions)?e.functions:[],R=Array.isArray(e.queues)?e.queues:[],A=e.metrics??{};if(!I.length)m.push("No Lambda functions were read for this environment, so the compute layer is empty rather than assumed.");r.push({id:"internet",label:"Internet",kind:"internet",layer:0,status:"ok",sub:"Public traffic",facts:[],external:!0});let E=Be(h.url),x=E.replace(/^https?:\/\//,"").split("/")[0];r.push({id:"dns",label:x||"Application domain",kind:"dns",layer:1,status:x?"ok":"unknown",sub:"DNS & certificates",facts:[{label:"Endpoint",value:E||"not resolved"}],external:!0});let N=e.waf;if(N)r.push({id:"waf",label:"WAF",kind:"waf",layer:2,status:qn(N.status??"active"),sub:Be(N.scope,"Managed rules"),facts:[{label:"Web ACL",value:Be(N.name,"unnamed")},...N.blocked!=null?[{label:"Blocked (24h)",value:String(N.blocked)}]:[],{label:"Rules",value:String(qw(e.wafRules))}],href:"/serverless/firewall"});let F=e.assetsInfo;if(F)r.push({id:"cdn",label:"Asset CDN",kind:"cdn",layer:2,status:"ok",sub:Be(F.cdn,"CloudFront"),facts:[{label:"Distribution",value:Be(F.cdn,"unknown")},{label:"Custom domain",value:Be(F.customDomain,"none")}],href:"/serverless/assets"}),r.push({id:"assets",label:"Asset bucket",kind:"storage",layer:6,status:"ok",sub:Be(F.bucket,"S3"),facts:[{label:"Bucket",value:Be(F.bucket,"unknown")},...F.files?[{label:"Objects",value:String(F.files)}]:[],...F.sizeMb?[{label:"Size",value:`${F.sizeMb} MB`}]:[]],href:"/serverless/assets"});let z=I.find((me)=>Be(me.key).startsWith("http"));r.push({id:"gateway",label:"HTTP entry point",kind:"gateway",layer:3,status:z?"ok":"unknown",sub:"Function URL / API Gateway",facts:[{label:"Endpoint",value:E||"not resolved"},{label:"Invocations (24h)",value:String(A.invocations??0)},...A.errorRatePct!=null?[{label:"Error rate",value:`${A.errorRatePct}%`}]:[]],href:"/serverless/metrics"});for(let me of I){let He=`fn:${Be(me.name)}`;if(!Be(me.name))continue;let nt=Number(me.errors??0),wt=Number(me.invocations??0);r.push({id:He,label:Be(me.key,Be(me.name)),kind:"function",layer:4,status:nt>0?wt&&nt/wt>0.02?"bad":"warn":wt?"ok":"idle",sub:Be(me.runtime,"lambda"),facts:[{label:"Function",value:Be(me.name)},{label:"Memory",value:`${me.memory??0} MB`},{label:"Timeout",value:`${me.timeout??0}s`},{label:"Invocations (24h)",value:String(wt)},{label:"Errors (24h)",value:String(nt)},{label:"p95",value:`${me.p95??0} ms`},...me.provisioned?[{label:"Provisioned",value:Be(me.provisioned)}]:[]],href:"/serverless/functions"})}for(let me of R){let He=`queue:${Be(me.name)}`;if(!Be(me.name))continue;let nt=Number(me.dlq??0);r.push({id:He,label:Be(me.name),kind:"queue",layer:5,status:nt>0?"bad":Number(me.visible??0)>0?"warn":"ok",sub:"SQS",facts:[{label:"Visible",value:String(me.visible??0)},{label:"In flight",value:String(me.inFlight??0)},{label:"Processed (24h)",value:String(me.processed??0)},{label:"Dead letter",value:String(nt)}],href:"/serverless/queues"})}let H=e.aurora;if(H)r.push({id:"database",label:"Aurora Serverless",kind:"database",layer:6,status:qn(H.status),sub:Be(H.engine,"aurora"),facts:[{label:"Cluster",value:Be(H.id,"unknown")},{label:"Capacity",value:`${H.currentAcu??0} ACU (${H.minAcu??0}–${H.maxAcu??0})`},{label:"Connections",value:String(H.connections??0)}],href:"/serverless/data"});let K=e.proxy;if(K)r.push({id:"rds-proxy",label:"RDS Proxy",kind:"database",layer:5,status:qn(K.status),sub:"Connection pooling",facts:[{label:"Proxy",value:Be(K.name,"unknown")},{label:"Endpoint",value:Be(K.endpoint,"unknown")},{label:"Pooled",value:String(K.pooledConns??0)}],href:"/serverless/data"});let X=e.redis;if(X)r.push({id:"cache",label:"ElastiCache",kind:"cache",layer:6,status:qn(X.status),sub:Be(X.node,"redis"),facts:[{label:"Group",value:Be(X.id,"unknown")},{label:"Hit rate",value:`${X.hitRate??0}%`}],href:"/serverless/data"});let oe=e.efs;if(oe)r.push({id:"efs",label:"EFS",kind:"filesystem",layer:6,status:qn(oe.status),sub:Be(oe.mount,"/mnt/local"),facts:[{label:"File system",value:Be(oe.id,"unknown")},{label:"Mount",value:Be(oe.mount,"unknown")},{label:"Size",value:`${oe.sizeMb??0} MB`}],href:"/data/volumes"});let ye=e.scheduler??{};if(ye.enabled)r.push({id:"scheduler",label:"Scheduler",kind:"scheduler",layer:3,status:"ok",sub:Be(ye.expression,"rate(1 minute)"),facts:[{label:"Expression",value:Be(ye.expression,"unknown")},{label:"Last run",value:Be(ye.lastRun,"unknown")}],href:"/operations/jobs"});let ne=new Set(r.map((me)=>me.id)),fe=ne.has("waf")?"waf":"gateway";fr(o,{source:"internet",target:"dns",flow:"request",label:"https"},ne),fr(o,{source:"dns",target:fe,flow:"request"},ne),fr(o,{source:"dns",target:"cdn",flow:"request",label:"assets"},ne),fr(o,{source:"waf",target:"gateway",flow:"request",label:"allowed"},ne),fr(o,{source:"cdn",target:"assets",flow:"data",label:"origin"},ne);let Ce=I.filter((me)=>Be(me.key).startsWith("http")),xe=I.filter((me)=>Be(me.key).startsWith("queue")),he=I.filter((me)=>Be(me.key).startsWith("cli"));for(let me of Ce)fr(o,{source:"gateway",target:`fn:${Be(me.name)}`,flow:"request",label:"invoke"},ne);for(let me of he)fr(o,{source:"scheduler",target:`fn:${Be(me.name)}`,flow:"async",label:"schedule"},ne);for(let me of R){for(let He of Ce)fr(o,{source:`fn:${Be(He.name)}`,target:`queue:${Be(me.name)}`,flow:"async",label:"publish"},ne);for(let He of xe)fr(o,{source:`queue:${Be(me.name)}`,target:`fn:${Be(He.name)}`,flow:"async",label:"consume"},ne)}let Ue=["rds-proxy","database","cache","efs","assets"];for(let me of I){let He=`fn:${Be(me.name)}`;if(ne.has("rds-proxy"))fr(o,{source:He,target:"rds-proxy",flow:"data",label:"pooled"},ne);else fr(o,{source:He,target:"database",flow:"data",label:"sql"},ne);for(let nt of Ue.filter((wt)=>wt!=="rds-proxy"&&wt!=="database"))fr(o,{source:He,target:nt,flow:"data"},ne)}return fr(o,{source:"rds-proxy",target:"database",flow:"data",label:"sql"},ne),{mode:"serverless",project:Be(t.project)||Be(h.name,"application"),environment:Be(t.environment)||Be(h.env,"production"),provider:"aws",region:Be(h.region,"unknown"),generatedAt:new Date().toISOString(),layers:Fw,groups:[],nodes:r,links:o,notes:m}}function bm(e,t,r={}){return e==="serverless"?$i(t,r):ft(t,r)}function jf(e){return String(e).padStart(2,"0")}function ha(e){return`${e.getUTCFullYear()}-${jf(e.getUTCMonth()+1)}-${jf(e.getUTCDate())}`}function Vw(e){let t=Math.max(0,Math.round((Date.now()-e)/1000));if(t<60)return`${t}s ago`;let r=Math.round(t/60);if(r<60)return`${r}m ago`;let o=Math.round(r/60);if(o<48)return`${o}h ago`;return`${Math.round(o/24)}d ago`}async function Xa(e,t,r,o,m,h){let I=await e.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:r,Dimensions:[{Name:"FunctionName",Value:t}],StartTime:m,EndTime:h,Period:86400,Statistics:[o]}).catch(()=>[]);if(!I.length)return 0;if(o==="Sum")return I.reduce((R,A)=>R+(A.Sum??0),0);if(o==="Maximum")return Math.max(...I.map((R)=>R.Maximum??0));return I.reduce((R,A)=>R+(A.Average??0),0)/I.length}async function ec(e,t,r,o,m,h,I){let R=await e.getMetricStatistics({Namespace:t,MetricName:r,Dimensions:o,StartTime:h,EndTime:I,Period:86400,Statistics:[m]}).catch(()=>[]);if(!R.length)return 0;if(m==="Sum")return R.reduce((A,E)=>A+(E.Sum??0),0);if(m==="Maximum")return Math.max(...R.map((A)=>A.Maximum??0));return R.reduce((A,E)=>A+(E.Average??0),0)/R.length}async function ep(e,t,r,o,m){let h=await e.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:[{Name:"FunctionName",Value:t}],StartTime:o,EndTime:m,Period:86400,ExtendedStatistics:[r]}).catch(()=>[]);return Math.round(h.reduce((I,R)=>I+(R.Percentiles?.[r]??0),0))}async function Jr(e,t){let r=await Nr(e,t),o=r.region,m=new hi(o),h=new C(o),I=new pe(o),R=new Date,A=new Date(R.getTime()-86400000),E=e.environments?.[t]?.app,x={};x.app={name:r.slug,env:t,region:o,runtime:E?.kind==="php"?`php-${E?.phpVersion??"8.3"} (fpm)`:E?.kind??"node",url:r.endpoint??"",build:r.lastRelease?.sha?.slice(0,7)??"—",deployedAt:r.lastRelease?.timestamp??"—"},x.maintenance={enabled:!1},x.scheduler={enabled:r.scheduler!=="off",expression:r.scheduler==="sub-minute"?"rate(1 minute) · sub-minute":"rate(1 minute)",lastRun:"—"};let N=0,F=0,z=0,H=[],K=[],X=[];for(let fe of r.functions){let[Ce,xe,he,Ue,me,He,nt,wt,cr]=await Promise.all([Xa(m,fe.name,"Invocations","Sum",A,R),Xa(m,fe.name,"Errors","Sum",A,R),Xa(m,fe.name,"Throttles","Sum",A,R),Xa(m,fe.name,"Duration","Average",A,R),h.getFunction(fe.name).catch(()=>null),ep(m,fe.name,"p50",A,R),ep(m,fe.name,"p95",A,R),ep(m,fe.name,"p99",A,R),m.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:fe.name}],StartTime:new Date(R.getTime()-43200000),EndTime:R,Period:3600,Stat:"Sum"}).catch(()=>[])]);N+=Ce,F+=xe,z=Math.max(z,Ue);let st=me?.Configuration?.MemorySize??0,Ft=Object.keys(me?.Configuration?.Environment?.Variables??{}),dr=[],vt=0;try{let{events:be=[]}=await I.filterLogEvents({logGroupName:`/aws/lambda/${fe.name}`,startTime:A.getTime(),limit:120});for(let Ee of be){let Ne=(Ee.message??"").trim(),It=/Max Memory Used:\s*(\d+)\s*MB/.exec(Ne);if(It)vt=Math.max(vt,Number(It[1]));if(Ne&&!/^(?:START|END|REPORT|INIT_START)/.test(Ne))X.push({source:fe.mode||fe.name,timestamp:new Date(Ee.timestamp??0).toISOString(),when:Vw(Ee.timestamp??0),message:Ne.slice(0,400),level:/error|exception|fatal|panic|traceback/i.test(Ne)?"error":/warn|warning|timeout|retr(?:y|ies)|throttl/i.test(Ne)?"warn":"info"})}dr=be.filter((Ee)=>!/^(?:START|END|REPORT|INIT_START)/.test((Ee.message??"").trim())).slice(-6).map((Ee)=>({ts:new Date(Ee.timestamp??0).toISOString().slice(11,19),msg:(Ee.message??"").trim().slice(0,120),err:/error|exception|fatal/i.test(Ee.message??"")}))}catch{}let Y=Math.max(1,...cr);H.push({key:fe.mode,name:fe.name,version:fe.version,memory:st,timeout:me?.Configuration?.Timeout??0,runtime:me?.Configuration?.Runtime??"provided.al2023",invocations:Math.round(Ce),errors:Math.round(xe),p95:nt||Math.round(Ue),status:"active",provisioned:fe.provisioned?`${fe.provisioned.allocated}/${fe.provisioned.requested}`:void 0}),K.push({key:fe.mode,name:fe.name,runtime:me?.Configuration?.Runtime??"provided.al2023",arch:me?.Configuration?.Architectures?.[0]??"x86_64",memory:st,timeout:me?.Configuration?.Timeout??0,ephemeral:me?.Configuration?.EphemeralStorage?.Size??512,version:fe.version,concurrency:E?.concurrency??"—",invocations:Math.round(Ce),errors:Math.round(xe),throttles:Math.round(he),p50:He||Math.round(Ue),p95:nt||Math.round(Ue),p99:wt||Math.round(Ue),maxMem:vt,spark:cr.length?cr.map((be)=>Math.round(be/Y*100)):[0],env:Ft.length?Ft:["(none)"],recent:dr.length?dr:[{ts:"—",msg:"no recent events",err:!1}]})}x.functions=H,x.functionsDetail=K,x.serverlessLogs=X.sort((fe,Ce)=>String(Ce.timestamp).localeCompare(String(fe.timestamp))).slice(0,600),x.serverlessLogsEmptyReason=X.length?void 0:"No recent function logs were found in CloudWatch for this environment.";let oe=N?Number((F/N*100).toFixed(2)):0,ye=Math.round(await Xa(m,r.functions[0]?.name??"","ConcurrentExecutions","Maximum",A,R));x.metrics={invocations:Math.round(N),errorRatePct:oe,p95Ms:Math.round(z),coldStartPct:void 0,concurrency:ye,estCostUsd:void 0};try{let fe=new re(o),Ce=[],xe=[],he=0;try{let{QueueUrl:me}=await fe.getQueueUrl(`${r.slug}-${t}-dlq`),{Attributes:He}=await fe.getQueueAttributes(me);he=Number(He.ApproximateNumberOfMessages??0)}catch{}let Ue=E?Gt(E,r.slug,t):[];for(let me of Ue){let He=me.name.replace(`${r.slug}-${t}-`,""),nt=0,wt=0;try{let{QueueUrl:st}=await fe.getQueueUrl(me.name),{Attributes:Ft}=await fe.getQueueAttributes(st);nt=Number(Ft.ApproximateNumberOfMessages??0),wt=Number(Ft.ApproximateNumberOfMessagesNotVisible??0)}catch{}let cr=Math.round(await ec(m,"AWS/SQS","NumberOfMessagesDeleted",[{Name:"QueueName",Value:me.name}],"Sum",A,R));Ce.push({name:He,visible:nt,inFlight:wt,processed:cr,dlq:he}),xe.push({name:me.name,short:He,visible:nt,inFlight:wt,delayed:0,processed:cr,oldestSec:0,concurrency:me.concurrency??E?.queueConcurrency??"—",tries:E?.queueTries??3,visTimeout:(E?.queueTimeout??120)*6,dlq:he})}if(Ce.length)x.queues=Ce;if(xe.length)x.queuesDetail=xe;x.dlqItems=[]}catch{}try{let fe=new f(o),{Stacks:Ce}=await fe.describeStacks({stackName:Mt(e,t)}),xe={};for(let he of Ce?.[0]?.Outputs??[])if(he.OutputKey)xe[he.OutputKey]=he.OutputValue??"";if(E?.database?.connection==="aurora-serverless"){let he=`${r.slug}-${t}-db`,Ue=[{Name:"DBClusterIdentifier",Value:he}],[me,He]=await Promise.all([ec(m,"AWS/RDS","ServerlessDatabaseCapacity",Ue,"Average",A,R),ec(m,"AWS/RDS","DatabaseConnections",Ue,"Maximum",A,R)]);if(x.aurora={id:he,engine:"aurora-mysql",minAcu:E?.database?.minCapacity??0.5,maxAcu:E?.database?.maxCapacity??4,currentAcu:me?Number(me.toFixed(1)):E?.database?.minCapacity??0.5,database:"app",connections:Math.round(He),status:xe.DbEndpoint?"available":"creating"},E?.rdsProxy)x.proxy={name:`${r.slug}-${t}-proxy`,endpoint:xe.DbProxyEndpoint??"—",pooledConns:Math.round(He),status:"available"}}if(E?.cache?.driver==="elasticache"){let he=`${r.slug}-${t}-cache`,Ue=[{Name:"CacheClusterId",Value:`${he}-001`}],[me,He]=await Promise.all([ec(m,"AWS/ElastiCache","CacheHits",Ue,"Sum",A,R),ec(m,"AWS/ElastiCache","CacheMisses",Ue,"Sum",A,R)]),nt=me+He>0?Number((me/(me+He)*100).toFixed(1)):0;x.redis={id:he,node:"cache.t4g.micro",engine:"redis",hitRate:nt,status:xe.CacheEndpoint?"available":"creating"}}if(E?.efs){let he=0;try{if(xe.EfsFileSystemId){let Ue=new tr(o),{FileSystems:me}=await Ue.describeFileSystems({FileSystemId:xe.EfsFileSystemId});he=Number(((me?.[0]?.SizeInBytes?.Value??0)/1048576).toFixed(1))}}catch{}x.efs={id:xe.EfsFileSystemId??"efs",mount:"/mnt/local",sizeMb:he,status:"available"}}x.assetsInfo=xe.AssetsCdnDomain?{bucket:xe.AssetsBucketName??`${r.slug}-${t}-assets`,cdn:xe.AssetsCdnDomain,customDomain:E?.assetDomain??"—",assetUrl:r.assetUrl??"—",files:0,sizeMb:0,cacheHitPct:0,build:x.app.build}:void 0}catch{}if(x.assetsInfo)try{let Ce=await new a(o).list({bucket:x.assetsInfo.bucket,maxKeys:1000});x.assetsInfo.files=Ce.length,x.assetsInfo.sizeMb=Number((Ce.reduce((xe,he)=>xe+(he.Size??0),0)/1048576).toFixed(1)),x.assetsRecent=Ce.slice(0,8).map((xe)=>({path:`/${xe.Key}`,size:`${Math.max(1,Math.round((xe.Size??0)/1024))} KB`,type:xe.Key.split(".").pop()??""}))}catch{}try{if(E?.secrets){let fe=Array.isArray(E.secrets)?E.secrets.map((Ce)=>({key:Ce.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),source:Ce})):Object.entries(E.secrets).map(([Ce,xe])=>({key:Ce,source:String(xe)}));x.secretsList=fe.map((Ce)=>({...Ce,updated:"—"}))}}catch{}try{let fe=new a(o),Ce=`${r.slug}-${t}-deployments`,xe=await fe.getObjectJson(Ce,`deployments/${r.slug}/${t}/history.json`).catch(()=>null);if(xe?.records?.length)x.deploymentsDetail=xe.records.slice(-12).reverse().map((he)=>({sha:(he.sha??"").slice(0,7),status:he.status??"success",when:he.timestamp??"—",took:he.took??"—",by:he.by??"—",version:he.version??"—",hooks:he.hooks??[]}))}catch{}x.metricsTotals={invocations:x.metrics.invocations,errors:Math.round(F),errorRatePct:oe,p95Ms:x.metrics.p95Ms,throttles:K.reduce((fe,Ce)=>fe+Ce.throttles,0),coldStartPct:void 0,estCostUsd:void 0,concurrency:ye},x.metricsPerFn=K.map((fe)=>({key:fe.key,invocations:fe.invocations,errors:fe.errors,throttles:fe.throttles,avgMs:fe.p50,maxMs:fe.p99,costUsd:void 0}));try{x.invSpark=await m.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:r.functions.find((fe)=>fe.mode==="http")?.name??""}],StartTime:new Date(R.getTime()-86400000),EndTime:R,Period:3600,Stat:"Sum"})}catch{}try{let fe=new Ji,Ce=R,xe=new Date(Date.UTC(Ce.getUTCFullYear(),Ce.getUTCMonth(),1)),he=new Date(Date.UTC(Ce.getUTCFullYear(),Ce.getUTCMonth()-1,1)),[Ue,me]=await Promise.all([fe.getCostByService({start:ha(xe),end:ha(Ce),granularity:"MONTHLY"}).catch(()=>[]),fe.getCostByService({start:ha(he),end:ha(xe),granularity:"MONTHLY"}).catch(()=>[])]);if(Ue.length){let He=Ue.reduce((vt,Y)=>vt+Y.amount,0),nt=me.reduce((vt,Y)=>vt+Y.amount,0),wt=Ce.getUTCDate(),cr=new Date(Date.UTC(Ce.getUTCFullYear(),Ce.getUTCMonth()+1,0)).getUTCDate();x.costSummary={monthToDateUsd:Number(He.toFixed(2)),projectedUsd:Number((He/wt*cr).toFixed(2)),lastMonthUsd:Number(nt.toFixed(2)),dailyAvgUsd:Number((He/wt).toFixed(2))},x.costServices=Ue.filter((vt)=>vt.amount>0).sort((vt,Y)=>Y.amount-vt.amount).slice(0,12).map((vt)=>({name:vt.service,usd:Number(vt.amount.toFixed(2)),note:""})),x.metrics.estCostUsd=Number((He/wt).toFixed(2)),x.metricsTotals.estCostUsd=x.metrics.estCostUsd,x.costTrend=await fe.getDailyTotals({start:ha(xe),end:ha(Ce)}).catch(()=>[]);let st=Ue.find((vt)=>/lambda/i.test(vt.service))?.amount??0,Ft=(vt)=>vt.invocations*(vt.p50/1000)*(vt.memory/1024),dr=K.reduce((vt,Y)=>vt+Ft(Y),0)||1;x.costPerFn=K.map((vt)=>({key:vt.key,requests:vt.invocations,gbSec:Math.round(Ft(vt)),usd:Number((st*(Ft(vt)/dr)).toFixed(2))}))}}catch{}if(E?.firewall)try{let fe=await m.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"BlockedRequests",StartTime:A,EndTime:R,Period:86400,Statistics:["Sum"]}).catch(()=>[]),Ce=await m.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"AllowedRequests",StartTime:A,EndTime:R,Period:86400,Statistics:["Sum"]}).catch(()=>[]);x.waf={enabled:!0,scope:"REGIONAL",acl:`${r.slug}-${t}-waf`,allowed24h:Math.round(Ce.reduce((xe,he)=>xe+(he.Sum??0),0)),blocked24h:Math.round(fe.reduce((xe,he)=>xe+(he.Sum??0),0))};try{let xe=new Xu(o),he=await xe.listWebACLs("REGIONAL"),Ue=he.find((me)=>me.Name?.includes(`${r.slug}-${t}`))??he[0];if(Ue?.Name&&Ue.Id){x.waf.acl=Ue.Name;let me=await xe.getWebACLRules(Ue.Name,Ue.Id,"REGIONAL");if(me.length)x.wafRules=me.map((He)=>({name:He.Name??"—",detail:`priority ${He.Priority??0}`,action:He.Action??"count",blocked24h:0}))}}catch{}}catch{}let ne=[];if(x.aurora)ne.push({name:"Aurora Serverless v2",detail:`${x.aurora.id} · ${x.aurora.minAcu}-${x.aurora.maxAcu} ACU`,status:x.aurora.status});if(x.proxy)ne.push({name:"RDS Proxy",detail:x.proxy.name,status:x.proxy.status});if(x.redis)ne.push({name:`ElastiCache (${x.redis.engine})`,detail:`${x.redis.node} · ${x.redis.hitRate}% hit rate`,status:x.redis.status});if(x.efs)ne.push({name:"EFS",detail:`${x.efs.mount} · ${x.efs.sizeMb} MB`,status:x.efs.status});if(ne.length)x.dataServices=ne;if(r.scheduler!=="off"&&E?.kind==="php")try{let fe=await Ke(e,t,"schedule:list"),Ce=[];for(let xe of(fe||"").split(`
41
+ `)){let he=/^\s*([\d*/,\-\s]+?)\s{2,}(.+?)(?:\s{2,}Next Due.*)?$/.exec(xe);if(he&&/[*\d]/.test(he[1])&&he[1].trim().split(/\s+/).length===5)Ce.push({command:he[2].trim().replace(/^php artisan /,""),cron:he[1].trim(),desc:"",lastRun:"—",lastStatus:"ok"})}if(Ce.length)x.schedulerTasks=Ce}catch{}return x.topology=$i(x,{project:e.project.name,environment:t}),x}function es(e){let t=Number(e);return Number.isFinite(t)&&t>=0?t:null}function Ww(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return null;let t=Date.parse(`${e}T12:00:00.000Z`);return Number.isFinite(t)?new Date(t).toISOString():null}function kl(e,t){if(!e||typeof e!=="object")return[];let r={source:t.name},o=[],m=t.now,h=(E,x,N,F=m)=>{if(x!==null)o.push({name:E,value:x,unit:N,timestamp:F,attributes:r})};h("storage.egress.month",es(e.monthBytes),"bytes"),h("storage.egress.today",es(e.todayBytes),"bytes"),h("storage.egress.projected_month",es(e.projectedMonthBytes),"bytes");let I=es(e.budgetBytes);if(I!==null&&I>0){h("storage.egress.budget",I,"bytes");let E=e.budgetUsedPercent,x=typeof E==="number"&&Number.isFinite(E)?E:es(e.monthBytes)!==null?Math.round(es(e.monthBytes)/I*1000)/10:null;h("storage.egress.budget_used_percent",x,"percent")}let R=t.maxReplayDays??45,A=Array.isArray(e.days)?e.days.slice(-R):[];for(let E of A){let x=Ww(String(E?.date??"")),N=es(E?.bytes);if(!x||N===null)continue;o.push({name:"storage.egress.day",value:N,unit:"bytes",timestamp:x,attributes:r});let F=es(E?.downloads);if(F!==null)o.push({name:"storage.egress.day_downloads",value:F,unit:"count",timestamp:x,attributes:r})}return o}async function Bl(e,t=process.env,r=fetch){let o=e.tokenEnv?t[e.tokenEnv]:void 0,m=await r(e.url,{headers:o?{Authorization:`Bearer ${o}`}:{},signal:AbortSignal.timeout(1e4)});if(!m.ok)throw Error(`HTTP ${m.status}`);return await m.json()}async function Zo(e,t){let r=[],o=[];if(!Array.isArray(e)||e.length===0)return{metrics:r,errors:o};let m=await Promise.all(e.map(async(h)=>{if(!h?.name||!h?.url)return{endpoint:h,error:"egress endpoint needs both a name and a url"};try{let I=await Bl(h,t.env,t.fetchImpl);return{endpoint:h,report:I}}catch(I){return{endpoint:h,error:I instanceof Error?I.message:String(I)}}}));for(let h of m){let I=`egress:${h.endpoint?.name??"unnamed"}`;if("error"in h&&h.error){o.push({source:I,message:h.error});continue}r.push(...kl(h.report,{name:h.endpoint.name,now:t.now}))}return{metrics:r,errors:o}}import{createHash as R_}from"node:crypto";import{existsSync as Zi,mkdtempSync as Gg,readdirSync as AS,rmSync as Gs,statSync as MS}from"node:fs";import{readFile as pi,writeFile as Ws}from"node:fs/promises";import{tmpdir as Lu}from"node:os";import{dirname as A_,extname as _c,join as rr,normalize as C_,relative as P_,resolve as __,sep as T_}from"node:path";import{fileURLToPath as x_}from"node:url";class ho extends Error{status;code;requestId;constructor(e,t,r,o){super(r);this.status=e;this.code=t;this.requestId=o}}class Ld{options;baseUrl;fetchFn;constructor(e){this.options=e;this.baseUrl=e.baseUrl.replace(/\/$/,""),this.fetchFn=e.fetch??fetch}async request(e,t={}){let r=await this.fetchFn(`${this.baseUrl}${e}`,{...t,headers:{accept:"application/json",authorization:`Bearer ${this.options.token}`,...t.headers}}),o=await r.json().catch(()=>({}));if(!r.ok)throw new ho(r.status,o.error?.code??"api_error",o.error?.message??"API request failed.",o.error?.requestId??r.headers.get("x-request-id")??void 0);return o}listProjects(e={}){return this.request(`/api/v1/projects?${new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).map(([t,r])=>[t,String(r)])))}`)}listEnvironments(e,t={}){return this.request(`/api/v1/projects/${encodeURIComponent(e)}/environments?${new URLSearchParams(Object.fromEntries(Object.entries(t).filter(([,r])=>r!==void 0).map(([r,o])=>[r,String(o)])))}`)}listServices(e,t){return this.request(`/api/v1/services?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}listOperations(e){return this.request(`/api/v1/operations${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listComposeTemplates(){return this.request("/api/v1/compose-templates")}listComposeApplications(e,t){return this.request(`/api/v1/compose-applications?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}previewCompose(e){return this.request("/api/v1/compose-applications/preview",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createComposeApplication(e){return this.request("/api/v1/compose-applications",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}composeServices(e){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/services`)}composeAction(e,t,r={}){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}releaseCapabilities(e,t={}){return this.request(`/api/v1/releases/capabilities?${new URLSearchParams({kind:e,health:String(!!t.health),replicas:String(t.replicas??1)})}`)}listReleases(e,t={}){return this.request(`/api/v1/releases?${new URLSearchParams({projectId:e,...t})}`)}createReleaseArtifact(e){return this.request("/api/v1/release-artifacts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createRelease(e){return this.request("/api/v1/releases",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}releaseAction(e,t,r={}){return this.request(`/api/v1/releases/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}createDeployment(e,t){return this.request("/api/v1/deployments",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}detectApplication(e){return this.request("/api/v1/application-detections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}planApplication(e){return this.request("/api/v1/application-plans",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}listApplicationDrafts(e){return this.request(`/api/v1/application-drafts?projectId=${encodeURIComponent(e)}`)}createApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createApplication(e,t){return this.request("/api/v1/applications",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}uploadApplicationArtifact(e,t,r){return this.request("/api/v1/application-artifacts",{method:"POST",headers:{"content-type":"application/octet-stream","x-project-id":e,"x-artifact-filename":t},body:r})}listRegistryConnections(){return this.request("/api/v1/registry-connections")}createRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}disconnectRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({id:e})})}listQueue(e={}){let t=new URLSearchParams(Object.entries(e).filter(([,r])=>r!==void 0).map(([r,o])=>[r,String(o)]));return this.request(`/api/v1/queue?${t}`)}operationLogs(e,t={}){let r=new URLSearchParams(Object.entries(t).filter(([,o])=>o!==void 0).map(([o,m])=>[o,String(m)]));return this.request(`/api/v1/operations/${encodeURIComponent(e)}/logs?${r}`)}streamOperationLogs(e,t=0){return this.fetchFn(`${this.baseUrl}/api/v1/operations/${encodeURIComponent(e)}/logs/stream`,{headers:{accept:"text/event-stream",authorization:`Bearer ${this.options.token}`,"last-event-id":String(t)}})}cancelOperation(e){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/cancel`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}retryOperation(e,t,r=0){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/retry`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({errorClass:t,delayMs:r})})}queueSettings(){return this.request("/api/v1/queue/settings")}updateQueueSettings(e){return this.request("/api/v1/queue/settings",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:"update queue limits",concurrency:e})})}listPreviews(e){return this.request(`/api/v1/previews${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listPreviewDefinitions(e){return this.request(`/api/v1/preview-definitions?projectId=${encodeURIComponent(e)}`)}createPreviewDefinition(e){return this.request("/api/v1/preview-definitions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createPreview(e){return this.request("/api/v1/previews",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}destroyPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/destroy`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:t})})}extendPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/extend`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hours:t})})}rebuildPreview(e){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/rebuild`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}usage(e={}){let t=new URLSearchParams;for(let[r,o]of Object.entries(e))if(o)t.set(r,String(o));return this.request(`/api/v1/usage${t.size>0?`?${t}`:""}`)}usageRollups(e){let t=new URLSearchParams({from:e.from,to:e.to});if(e.projectId)t.set("projectId",e.projectId);if(e.environmentId)t.set("environmentId",e.environmentId);if(e.limit)t.set("limit",String(e.limit));for(let r of e.meters??[])t.append("meter",r);return this.request(`/api/v1/usage/rollups?${t}`)}allowance(e="deploy",t={}){let r=new URLSearchParams({operation:e});if(t.projectId)r.set("projectId",t.projectId);if(t.environmentId)r.set("environmentId",t.environmentId);return this.request(`/api/v1/spend/allowance?${r}`)}budgets(e={}){let t=new URLSearchParams;for(let[r,o]of Object.entries(e))if(o)t.set(r,String(o));return this.request(`/api/v1/spend/budgets${t.size>0?`?${t}`:""}`)}anomalies(e={}){let t=new URLSearchParams;if(e.projectId)t.set("projectId",e.projectId);if(e.since)t.set("since",e.since);if(e.unacknowledged)t.set("unacknowledged","true");return this.request(`/api/v1/spend/anomalies${t.size>0?`?${t}`:""}`)}}import{createHash as $k}from"node:crypto";import{lstatSync as Hw,readdirSync as Kw,readFileSync as Jw}from"node:fs";import{relative as Gw,resolve as Mf,sep as Qw}from"node:path";function Yw(e){return new Map(e.map((t)=>[t.path.replace(/^\.\//,"").replace(/\\/g,"/"),t]))}function Rs(e,t,r){return{path:e,reason:t,weight:r}}function Bf(e){try{return e?.content?JSON.parse(e.content):{}}catch{return{}}}function ya(e,t,r,o,m,h){return{framework:e,strategy:t,confidence:r,evidence:o,defaults:{build:m,runtime:{target:t==="static"?"serverless":t==="serverless"?"serverless":t==="dockerfile"||t==="prebuilt_image"?"container":"server",architecture:"x86_64",port:t==="static"||t==="serverless"?void 0:3000,healthCheck:t==="static"?void 0:{protocol:"http",path:"/health"}}},description:h}}function va(e){let t=Yw(e.slice(0,1e4)),r=[];if(t.has("Dockerfile"))r.push(ya("dockerfile","dockerfile",0.99,[Rs("Dockerfile","A root Dockerfile defines an explicit reproducible build.",1)],{kind:"dockerfile",context:".",dockerfile:"Dockerfile"},"Build the repository with its Dockerfile and run the resulting OCI image."));let o=Bf(t.get("composer.json"));if(t.has("artisan")&&o.require?.["laravel/framework"])r.push(ya("laravel","server",0.98,[Rs("artisan","Laravel Artisan entrypoint is present.",0.45),Rs("composer.json","Requires laravel/framework.",0.55)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",buildCommand:"php artisan config:cache && php artisan route:cache && php artisan view:cache",startCommand:"php artisan serve --host=0.0.0.0 --port=$PORT"},"Install a production Composer tree, warm Laravel caches, and run the HTTP application."));else if(t.has("composer.json"))r.push(ya("php","server",0.82,[Rs("composer.json","Composer metadata identifies a PHP application.",0.8)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",startCommand:"php -S 0.0.0.0:$PORT -t public"},"Install Composer dependencies and run the configured PHP document root."));let m=Bf(t.get("package.json"));if(t.has("package.json")){let h=t.has("bun.lock")||t.has("bun.lockb")||m.engines?.bun,I=h?"bun":"node",R=h?"bun":"node",A=[Rs("package.json",`Defines ${m.scripts?.build?"build and ":""}${m.scripts?.start?"start ":""}scripts.`,0.55)];if(h)A.push(Rs(t.has("bun.lock")?"bun.lock":t.has("bun.lockb")?"bun.lockb":"package.json","Pins the Bun package manager/runtime.",0.35));let E=!!(m.dependencies?.vite||m.devDependencies?.vite||m.dependencies?.["@stacksjs/bunpress"]||m.devDependencies?.["@stacksjs/bunpress"])&&!m.scripts?.start,x=E?{kind:"static",installCommand:`${I} install --frozen-lockfile`,buildCommand:`${I} run build`,publishDirectory:"dist"}:{kind:"server",runtime:I,installCommand:`${I} install --frozen-lockfile`,buildCommand:m.scripts?.build?`${I} run build`:void 0,startCommand:m.scripts?.start?`${I} run start`:I==="bun"?"bun run index.ts":"node index.js"};r.push(ya(R,x.kind,Math.min(0.94,A.reduce((N,F)=>N+F.weight,0)),A,x,E?"Install dependencies, build static assets, and publish the output directory.":`Install dependencies, build if configured, and start the ${I} server.`))}if(!r.length&&(t.has("index.html")||t.has("public/index.html")))r.push(ya("static","static",0.78,[Rs(t.has("index.html")?"index.html":"public/index.html","A static HTML entrypoint is present.",0.78)],{kind:"static",publishDirectory:t.has("index.html")?".":"public"},"Publish the static directory without a runtime process."));if(!r.length)r.push(ya("unknown","buildpack",0.2,[],{kind:"buildpack",runtime:"node"},"No supported framework signature was conclusive; choose commands and runtime manually."));return r.sort((h,I)=>I.confidence-h.confidence||h.framework.localeCompare(I.framework))}function tp(e,t={}){let r=Mf(e),o=t.maxFiles??1e4,m=t.maxContentBytes??262144,h=[],I=new Set(["Dockerfile","package.json","composer.json","index.html","public/index.html","bun.lock","bun.lockb","artisan"]),R=new Set([".git",".ts-cloud",".cache",".next",".nuxt",".output",".turbo",".bun","node_modules","vendor","pantry","dist","build","coverage"]),A=(E)=>{for(let x of Kw(E).sort()){if(R.has(x))continue;let N=Mf(E,x),F=Gw(r,N).split(Qw).join("/");if(!F||F.startsWith("../"))throw Error("Detection path escaped the application root");let z=Hw(N);if(z.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${F}`);if(z.isDirectory())A(N);else if(z.isFile()){if(h.length>=o)throw Error("Application file-count limit exceeded");let H={path:F,size:z.size};if(I.has(F)&&z.size<=m)H.content=Jw(N,"utf8");h.push(H)}}};return A(r),h}function np(e){if(Array.isArray(e))return`[${e.map(np).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${np(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function tc(e){return!!e&&!e.startsWith("/")&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function An(e,t,r,o){return{path:e,code:t,message:r,alternatives:o}}function rp(e){return JSON.parse(JSON.stringify(e))}function Zw(e){let t=Object.fromEntries(Object.entries(e.environment??{}).map(([r,o])=>[r,typeof o==="string"?o:`\${${o.secretRef}}`]));if(e.build.kind==="prebuilt_image"||e.build.kind==="dockerfile")return rp({infrastructure:{containers:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,cpu:e.runtime.cpu,memory:e.runtime.memoryMb,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,environment:t}}}});if(e.runtime.target==="serverless"||e.build.kind==="serverless")return rp({serverless:{apps:{[e.slug]:{source:e.source,build:e.build,architecture:e.runtime.architecture,environment:t,domain:e.domain}}}});return rp({sites:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,env:t,domain:e.domain?.hostname}}})}function Vn(e,t=[]){let r=[],o=(H)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(H),m=Object.fromEntries(Object.entries(e.environment??{}).map(([H,K])=>{if(typeof K==="string"&&o(H))return r.push(An(`environment.${H}`,"write_only_secret_required",`${H} must be supplied through the write-only secrets boundary.`)),[H,{secretRef:H}];return[H,K]})),h=e.build;if(e.build.kind==="dockerfile"&&e.build.buildArgs){let H=Object.fromEntries(Object.entries(e.build.buildArgs).map(([K,X])=>{if(o(K))return r.push(An(`build.buildArgs.${K}`,"write_only_build_secret_required",`${K} must be declared in secretNames instead of buildArgs.`)),[K,"[REDACTED]"];return[K,X]}));h={...e.build,buildArgs:H}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.slug))r.push(An("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!tc((e.source.kind==="git"?e.source.monorepoRoot:e.source.kind==="local"?e.source.root:".")??"."))r.push(An("source","unsafe_source_root","Source root must stay inside the source tree."));if(e.source.kind==="git"&&e.source.sparsePaths?.some((H)=>!tc(H)))r.push(An("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(e.build.kind==="dockerfile"&&(!tc(e.build.context)||!tc(e.build.dockerfile)))r.push(An("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(e.build.kind==="static"&&!tc(e.build.publishDirectory))r.push(An("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(e.build.kind==="server"&&!e.build.startCommand.trim())r.push(An("build.startCommand","missing_start_command","A server start command is required.",["Use static output","Use a Dockerfile"]));if(e.source.kind==="image"&&e.build.kind!=="prebuilt_image")r.push(An("build.kind","image_requires_prebuilt","An OCI image source must use the prebuilt-image strategy.",["Select prebuilt image"]));if(e.build.kind==="prebuilt_image"&&e.runtime.target!=="container")r.push(An("runtime.target","image_requires_container","Prebuilt images require the container runtime target.",["Select container target"]));if(e.runtime.target==="serverless"&&e.build.kind==="dockerfile")r.push(An("runtime.target","unsupported_serverless_dockerfile","Dockerfile builds currently target the container service path.",["Select container target","Select serverless package"]));if(e.runtime.port!==void 0&&(!Number.isInteger(e.runtime.port)||e.runtime.port<1||e.runtime.port>65535))r.push(An("runtime.port","invalid_port","Port must be an integer from 1 to 65535."));let I=e.runtime.healthCheck;if(I&&I.protocol!=="tcp"&&(!I.path||!I.path.startsWith("/")||/[\r\n]/.test(I.path)))r.push(An("runtime.healthCheck.path","invalid_health_path","HTTP health checks require a path beginning with /."));if(e.domain?.hostname&&(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i.test(e.domain.hostname)||e.domain.hostname.includes("..")))r.push(An("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let R=Object.values(m).flatMap((H)=>typeof H==="object"?[H.secretRef]:[]),A=[...new Set([...e.requiredSecretNames??[],...e.build.kind==="dockerfile"?e.build.secretNames??[]:[],...R])].sort(),E=new Set(t),x=A.filter((H)=>!E.has(H)),N={apiVersion:"ts-cloud.dev/v1",kind:"Application",metadata:{name:e.name,slug:e.slug,projectId:e.projectId,environmentId:e.environmentId},spec:{source:e.source,build:h,runtime:e.runtime,environment:m,domain:e.domain}},F=[...new Set([e.source.kind==="git"?"git:read":e.source.kind==="image"?"registry:pull":e.source.kind==="artifact"?"artifact:inspect":"filesystem:read",e.runtime.target==="container"?"containers":e.runtime.target==="serverless"?"serverless":"servers",e.domain?"dns":""])].filter(Boolean).sort(),z=[...new Set([e.runtime.target,e.runtime.cpu?`${e.runtime.cpu} vCPU`:"",e.runtime.memoryMb?`${e.runtime.memoryMb} MB memory`:"",(e.runtime.minInstances??0)>0?`${e.runtime.minInstances} minimum instances`:"scales from zero where supported",e.domain?"managed DNS/TLS":""])].filter(Boolean);return{valid:r.length===0&&x.length===0,issues:r,missingSecrets:x,manifest:N,configPatch:Zw({...e,build:h,environment:m}),capabilityRequirements:F,costDrivers:z,serializedManifest:`${np(N)}
42
42
  `}}function Lf(e){let t=e.replace(/\\/g,"/");return!!t&&!t.startsWith("/")&&!/^[A-Za-z]:\//.test(t)&&!t.split("/").includes("..")&&!/[\0\r\n]/.test(t)}function Ff(e,t,r={}){let o=r.maxBytes??104857600,m=r.maxEntries??1e4,h=r.maxExpandedBytes??524288000;if(e.byteLength>o)throw Error("Archive exceeds the compressed size limit");let I=new DataView(e.buffer,e.byteOffset,e.byteLength),R=[],A=0;if(t.toLowerCase().endsWith(".zip")||e[0]===80&&e[1]===75){let x=0;while(x+30<=e.length){let N=I.getUint32(x,!0);if(N===33639248||N===101010256)break;if(N!==67324752)throw Error("Malformed ZIP local header");let F=I.getUint16(x+6,!0),z=I.getUint32(x+18,!0),H=I.getUint32(x+22,!0),K=I.getUint16(x+26,!0),X=I.getUint16(x+28,!0);if(F&8)throw Error("ZIP data descriptors are not accepted for uploaded artifacts");let oe=new TextDecoder().decode(e.subarray(x+30,x+30+K));if(!Lf(oe))throw Error(`Unsafe archive path: ${oe}`);if(R.push(oe),A+=H,R.length>m||A>h)throw Error("Archive expansion limit exceeded");x+=30+K+X+z}return{format:"zip",entries:R.length,expandedBytes:A,paths:R}}if(!t.toLowerCase().match(/\.(?:tar|tar\.gz|tgz)$/))throw Error("Only ZIP and uncompressed TAR artifacts are supported");let E=0;while(E+512<=e.length){let x=e.subarray(E,E+512);if(x.every((K)=>K===0))break;let N=(K,X)=>new TextDecoder().decode(x.subarray(K,K+X)).replace(/\0.*$/,""),F=`${N(345,155)}${N(345,155)?"/":""}${N(0,100)}`,z=Number.parseInt(N(124,12).trim()||"0",8),H=String.fromCharCode(x[156]??0);if(!Lf(F))throw Error(`Unsafe archive path: ${F}`);if(H==="1"||H==="2")throw Error(`Archive links are not accepted: ${F}`);if(!Number.isFinite(z)||z<0)throw Error("Malformed TAR entry size");if(R.push(F),A+=z,R.length>m||A>h)throw Error("Archive expansion limit exceeded");E+=512+Math.ceil(z/512)*512}return{format:"tar",entries:R.length,expandedBytes:A,paths:R}}var zf=new Set(["source","build","runtime","environment","domain","review"]);function Uf(e,t){try{return typeof e==="string"?JSON.parse(e):t}catch{return t}}function qf(e){return/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(e)}function Vf(e){for(let[r,o]of Object.entries(e.environment??{}))if(typeof o==="string"&&qf(r)&&o)throw Error(`${r} must be stored through the write-only secrets boundary`);if(e.build.kind==="dockerfile"){for(let[r,o]of Object.entries(e.build.buildArgs??{}))if(qf(r)&&o)throw Error(`${r} must be declared as a build secret name`)}let t=JSON.stringify(e);if(/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(t))throw Error("Drafts cannot contain credential-bearing URLs")}function Wf(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),schemaVersion:Number(e.schema_version),name:String(e.name),step:String(e.step),input:Uf(e.input,{}),suppliedSecretNames:Uf(e.supplied_secret_names,[]),status:String(e.status),version:Number(e.version),createdByActorId:e.created_by_actor_id?String(e.created_by_actor_id):void 0,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class ip{controlPlane;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}create(e){if(Vf(e.draft),e.draft.projectId!==e.projectId)throw Error("Draft project does not match its storage scope");let t=this.controlPlane.getProject(e.projectId);if(!t||t.organizationId!==e.organizationId)throw Error("Draft project was not found");let r=this.idFn(),o=this.now(),m=e.step??"source";if(!zf.has(m))throw Error("Invalid draft step");let h=[...new Set(e.suppliedSecretNames??[])].sort(),I=Vn(e.draft,h).valid?"ready":"draft";return this.controlPlane.database.run("INSERT INTO application_drafts (id, organization_id, project_id, schema_version, name, step, input, supplied_secret_names, status, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.organizationId,e.projectId,e.name.trim().slice(0,100),m,JSON.stringify(e.draft),JSON.stringify(h),I,e.actorId??null,o,o]),this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,actorId:e.actorId,type:"application.draft.created",payload:{draftId:r,step:m,status:I,requiredSecretNames:e.draft.requiredSecretNames??[]}}),this.get(r)}get(e){let t=this.controlPlane.database.query("SELECT * FROM application_drafts WHERE id=?").get(e);return t?Wf(t):void 0}list(e){return this.controlPlane.database.query("SELECT * FROM application_drafts WHERE project_id=? ORDER BY updated_at DESC").all(e).map(Wf)}update(e,t,r){let o=this.get(e);if(!o||o.version!==t)throw Error(`Application draft ${e} changed since version ${t}`);if(!zf.has(r.step))throw Error("Invalid draft step");if(r.draft.projectId!==o.projectId)throw Error("Draft project cannot be changed");Vf(r.draft);let m=[...new Set(r.suppliedSecretNames??o.suppliedSecretNames)].sort(),h=Vn(r.draft,m).valid?"ready":"draft",I=this.now();if(this.controlPlane.database.run("UPDATE application_drafts SET name=?, step=?, input=?, supplied_secret_names=?, status=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.draft.name.slice(0,100),r.step,JSON.stringify(r.draft),JSON.stringify(m),h,I,e,t]).changes!==1)throw Error(`Application draft ${e} changed since version ${t}`);return this.controlPlane.appendEvent({organizationId:o.organizationId,projectId:o.projectId,actorId:r.actorId,type:"application.draft.updated",payload:{draftId:e,fromVersion:t,toVersion:t+1,step:r.step,status:h}}),this.get(e)}markApplied(e,t,r){let o=this.get(e);if(!o||o.version!==t)throw Error(`Application draft ${e} changed since version ${t}`);let m=Vn(o.input,o.suppliedSecretNames);if(!m.valid)throw Error(`Draft is not deployable: ${[...m.issues.map((I)=>I.message),...m.missingSecrets.map((I)=>`Missing secret ${I}`)].join("; ")}`);let h=this.now();return this.controlPlane.database.run("UPDATE application_drafts SET status='applied', step='review', version=version+1, updated_at=? WHERE id=? AND version=?",[h,e,t]),this.controlPlane.appendEvent({organizationId:o.organizationId,projectId:o.projectId,actorId:r,type:"application.draft.applied",payload:s({draftId:e,manifest:m.manifest})}),this.get(e)}}import{createCipheriv as Xw,createDecipheriv as ek,createHash as Jf,randomBytes as tk}from"node:crypto";function rc(e){return typeof e==="string"&&e?e:void 0}function op(e){return Jf("sha256").update(e).digest("hex").slice(0,16)}function Hf(e){let t=new URL(e.includes("://")?e:`https://${e}`);if(t.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(t.hostname))throw Error("Registry host must use HTTPS");if(t.username||t.password||t.search||t.hash)throw Error("Registry host cannot contain credentials");return`${t.protocol}//${t.host}`}function rk(e){return{id:String(e.id),organizationId:String(e.organization_id),provider:String(e.provider),name:String(e.name),host:String(e.host),credentialConfigured:!!e.credential_ciphertext,credentialFingerprint:rc(e.credential_fingerprint),credentialExpiresAt:rc(e.credential_expires_at),status:String(e.status),healthMessage:rc(e.health_message),lastTestedAt:rc(e.last_tested_at),version:Number(e.version),createdByActorId:rc(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class sp{controlPlane;key;nowFn;idFn;constructor(e,t){this.controlPlane=e;if(!t.encryptionKey)throw Error("Registry encryption key is required");this.key=Jf("sha256").update(`ts-cloud:registry:${t.encryptionKey}`).digest(),this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}encrypt(e){let t=tk(12),r=Xw("aes-256-gcm",this.key,t),o=Buffer.concat([r.update(e,"utf8"),r.final()]);return`v1.${t.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${o.toString("base64url")}`}decrypt(e){let[t,r,o,m]=e.split(".");if(t!=="v1"||!r||!o||!m)throw Error("Registry credential envelope is invalid");let h=ek("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return h.setAuthTag(Buffer.from(o,"base64url")),Buffer.concat([h.update(Buffer.from(m,"base64url")),h.final()]).toString("utf8")}current(e){let t=rk(e);return t.status!=="disconnected"&&t.credentialExpiresAt&&new Date(t.credentialExpiresAt).getTime()<=this.nowFn().getTime()?{...t,status:"expired",healthMessage:"Registry credential expired; rotate it before pulling images."}:t}create(e){if(!["docker_hub","ghcr","ecr","gcr","generic"].includes(e.provider))throw Error("A supported registry provider is required");let t=e.credential?JSON.stringify(e.credential):void 0,r=this.idFn(),o=this.now();return this.controlPlane.database.run("INSERT INTO registry_connections (id, organization_id, provider, name, host, credential_ciphertext, credential_fingerprint, credential_expires_at, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.organizationId,e.provider,e.name.trim().slice(0,80),Hf(e.host),t?this.encrypt(t):null,t?op(t):null,e.credentialExpiresAt??null,e.actorId??null,o,o]),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.actorId,type:"registry.connection.created",payload:{connectionId:r,provider:e.provider,host:Hf(e.host),credentialConfigured:!!t}}),this.get(r)}get(e){let t=this.controlPlane.database.query("SELECT * FROM registry_connections WHERE id=?").get(e);return t?this.current(t):void 0}list(e){return this.controlPlane.database.query("SELECT * FROM registry_connections WHERE organization_id=? ORDER BY name").all(e).map((t)=>this.current(t))}credential(e){let t=this.controlPlane.database.query("SELECT credential_ciphertext FROM registry_connections WHERE id=?").get(e);return t?.credential_ciphertext?JSON.parse(this.decrypt(String(t.credential_ciphertext))):void 0}rotate(e,t,r={}){let o=this.get(e);if(!o||o.status==="disconnected")throw Error("Registry connection was not found");let m=JSON.stringify(t);return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=?, credential_fingerprint=?, credential_expires_at=?, status='pending', health_message=NULL, version=version+1, updated_at=? WHERE id=?",[this.encrypt(m),op(m),r.expiresAt??null,this.now(),e]),this.controlPlane.appendEvent({organizationId:o.organizationId,actorId:r.actorId,type:"registry.credential.rotated",payload:{connectionId:e,fingerprint:op(m),expiresAt:r.expiresAt??null}}),this.get(e)}disconnect(e,t){let r=this.get(e);if(!r)throw Error("Registry connection was not found");return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=NULL, credential_fingerprint=NULL, status='disconnected', health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[this.now(),e]),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"registry.connection.disconnected",level:"warning",payload:{connectionId:e}}),this.get(e)}async test(e,t={}){let r=this.get(e);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active registry connection was not found");let o=this.credential(e),m=t.fetch??fetch,h=new AbortController,I=setTimeout(()=>h.abort(),t.timeoutMs??15000),R=o?.token?`Bearer ${o.token}`:o?.username||o?.password?`Basic ${Buffer.from(`${o.username??""}:${o.password??""}`).toString("base64")}`:void 0;try{let A=await m(`${r.host}/v2/`,{method:"GET",redirect:"error",signal:h.signal,headers:R?{Authorization:R}:void 0}),E=A.headers.get("www-authenticate")??"";if(A.status===401&&E.startsWith("Bearer ")&&o){let F=Object.fromEntries([...E.slice(7).matchAll(/(\w+)="([^"]+)"/g)].map((oe)=>[oe[1],oe[2]])),z=new URL(F.realm??"");if(z.protocol!=="https:")throw Error("Registry authentication realm must use HTTPS");if(F.service)z.searchParams.set("service",F.service);if(t.image)z.searchParams.set("scope",`repository:${Gf(t.image).repository}:pull`);let H=await m(z,{signal:h.signal,redirect:"error",headers:R?{Authorization:R}:void 0});if(!H.ok)throw Error(`Registry authentication failed (${H.status})`);let K=await H.json(),X=K.token??K.access_token;if(!X)throw Error("Registry did not return an access token");A=t.image?await Kf(m,r.host,t.image,X,h.signal):await m(`${r.host}/v2/`,{signal:h.signal,redirect:"error",headers:{Authorization:`Bearer ${X}`}})}else if(A.ok&&t.image)A=await Kf(m,r.host,t.image,o?.token,h.signal,R);let x=A.ok?"healthy":"degraded",N=A.ok?t.image?"Registry image is readable.":"Registry connection is healthy.":`Registry request failed (${A.status})`;return this.controlPlane.database.run("UPDATE registry_connections SET status=?, health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[x,N,this.now(),this.now(),e]),this.get(e)}catch(A){let E=h.signal.aborted?"Registry request timed out.":A instanceof Error?A.message:"Registry test failed";return this.controlPlane.database.run("UPDATE registry_connections SET status='degraded', health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[E.slice(0,1000),this.now(),this.now(),e]),this.get(e)}finally{clearTimeout(I)}}}function Gf(e){let t=e.replace(/^https?:\/\//,""),r=t.indexOf("/");if(r<1)throw Error("Image must include registry/repository");let o=t.slice(r+1),m=o.lastIndexOf("@"),h=o.lastIndexOf(":"),I=m>=0?m:h>o.lastIndexOf("/")?h:-1,R=I>=0?o.slice(0,I):o,A=I>=0?o.slice(I+1):"latest";if(!/^[A-Za-z0-9_.\/-]+$/.test(R)||!/^[A-Za-z0-9_.:+-]+$/.test(A))throw Error("Image reference is invalid");return{repository:R,reference:A}}async function Kf(e,t,r,o,m,h){let I=Gf(r);return e(`${t}/v2/${I.repository}/manifests/${encodeURIComponent(I.reference)}`,{method:"HEAD",redirect:"error",signal:m,headers:{Accept:"application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json",...o?{Authorization:`Bearer ${o}`}:h?{Authorization:h}:{}}})}import{createHash as nk}from"node:crypto";import{chmodSync as Qf,existsSync as Yf,mkdirSync as ik,renameSync as ok,unlinkSync as Zf,writeFileSync as sk}from"node:fs";import{basename as ak,join as ck}from"node:path";function ap(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),filename:String(e.filename),sha256:String(e.sha256),size:Number(e.size),format:String(e.format),entryCount:Number(e.entry_count),expandedBytes:Number(e.expanded_bytes),createdByActorId:e.created_by_actor_id?String(e.created_by_actor_id):void 0,createdAt:String(e.created_at)}}class cp{controlPlane;root;idFn;nowFn;constructor(e,t){this.controlPlane=e;this.root=d(t.cwd,"artifacts"),this.idFn=t.id??(()=>crypto.randomUUID()),this.nowFn=t.now??(()=>new Date)}create(e){let t=this.controlPlane.getProject(e.projectId);if(!t||t.organizationId!==e.organizationId)throw Error("Artifact project was not found");let r=ak(e.filename).slice(0,200);if(!r||r!==e.filename)throw Error("Artifact filename must not contain a path");let o=Ff(e.bytes,r),m=nk("sha256").update(e.bytes).digest("hex"),h=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? AND sha256=?").get(e.projectId,m);if(h)return ap(h);let I=this.idFn();ik(this.root,{recursive:!0,mode:448}),Qf(this.root,448);let R=ck(this.root,`${I}.archive`),A=`${R}.partial`;try{sk(A,e.bytes,{mode:384,flag:"wx"}),ok(A,R),Qf(R,384),this.controlPlane.database.run("INSERT INTO application_artifacts (id, organization_id, project_id, filename, storage_path, sha256, size, format, entry_count, expanded_bytes, created_by_actor_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[I,e.organizationId,e.projectId,r,R,m,e.bytes.byteLength,o.format,o.entries,o.expandedBytes,e.actorId??null,this.nowFn().toISOString()])}catch(E){if(Yf(A))Zf(A);if(Yf(R))Zf(R);throw E}return this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,actorId:e.actorId,type:"application.artifact.created",payload:{artifactId:I,filename:r,sha256:m,size:e.bytes.byteLength,entries:o.entries}}),this.get(I)}get(e){let t=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE id=?").get(e);return t?ap(t):void 0}list(e){return this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? ORDER BY created_at DESC").all(e).map(ap)}}function Fc(e){let t=e.drafts.get(e.draftId);if(!t||t.version!==e.expectedVersion)throw Error(`Application draft ${e.draftId} changed since version ${e.expectedVersion}`);if(t.status==="applied")throw Error("Application draft was already applied");let r=e.controlPlane.getProject(t.projectId),o=r?e.controlPlane.listEnvironments(r.id).find((E)=>E.id===t.input.environmentId):void 0;if(!r||!o||o.projectId!==r.id||r.organizationId!==t.organizationId)throw Error("Draft deployment scope was not found");if(e.confirmEnvironment!==o.slug)throw Error(`Type ${o.slug} to confirm this deployment target`);let m=Vn(t.input,t.suppliedSecretNames);if(!m.valid)throw Error(`Application plan is invalid: ${[...m.issues.map((E)=>E.message),...m.missingSecrets.map((E)=>`Missing secret ${E}`)].join("; ")}`);let h=e.controlPlane.listResources(r.id,o.id).find((E)=>E.kind==="application"&&E.slug===t.input.slug),I=JSON.parse(JSON.stringify({manifest:m.manifest,configPatch:m.configPatch})),R=h?e.controlPlane.updateResource(h.id,h.version,{name:t.input.name,desiredState:I}):e.controlPlane.createResource({projectId:r.id,environmentId:o.id,kind:"application",slug:t.input.slug,name:t.input.name,desiredState:I,metadata:{source:"application-onboarding",draftId:t.id}}),A=new c(e.controlPlane).enqueue({projectId:r.id,environmentId:o.id,resourceId:R.id,actorId:e.actorId,kind:"application.create",idempotencyKey:`application-draft:${t.id}:v${t.version}`,correlationId:`application-draft:${t.id}`,input:I,lockKey:`resource:${R.id}`,providerKey:R.provider??"default",buildSlot:t.input.build.kind!=="prebuilt_image",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return e.drafts.markApplied(t.id,t.version,e.actorId),e.controlPlane.appendEvent({organizationId:t.organizationId,projectId:r.id,resourceId:R.id,operationId:A.id,actorId:e.actorId,type:"application.create.queued",payload:{draftId:t.id,environment:o.slug,strategy:t.input.build.kind,costDrivers:m.costDrivers}}),{plan:m,resource:R,operation:A}}function $r(e){let t=["static","compute","serverless_zip","serverless_image"].includes(e.kind),r=["container","compose"].includes(e.kind)&&(e.replicas??1)>1,o=e.kind==="container"||e.kind==="serverless_zip"||e.kind==="serverless_image",m=(h,I)=>I&&(h==="atomic"?e.kind==="static"||e.hasHealthGate:e.hasHealthGate);return[{strategy:"atomic",supported:m("atomic",t),explanation:t?e.hasHealthGate||e.kind==="static"?"Activate an immutable version with an atomic pointer/alias switch.":"Atomic activation needs a readiness gate for this runtime.":"This driver has no atomic pointer or alias primitive.",capacityMultiplier:1,costImpact:"none",rollback:"Switch the pointer/alias back to the previous immutable release."},{strategy:"rolling",supported:m("rolling",r),explanation:r?e.hasHealthGate?"Replace healthy replicas within the configured capacity envelope.":"Rolling activation requires a health/readiness gate.":"Rolling activation requires a capable container/Compose driver and at least two replicas.",capacityMultiplier:1.5,costImpact:"temporary",rollback:"Stop replacement and restore the prior task/service definition."},{strategy:"blue_green",supported:m("blue_green",o),explanation:o?e.hasHealthGate?"Provision a complete green target and switch traffic after health passes.":"Blue-green requires a health gate before traffic can switch.":"The provider does not expose two traffic-addressable revisions.",capacityMultiplier:2,costImpact:"temporary",rollback:"Return all traffic to the preserved blue target."},{strategy:"canary",supported:m("canary",o),explanation:o?e.hasHealthGate?"Shift bounded traffic steps while evaluating health.":"Canary requires a health gate and measurable traffic target.":"The provider does not expose weighted traffic primitives.",capacityMultiplier:1.25,costImpact:"temporary",rollback:"Set canary weight to zero and preserve its diagnostics."}]}function vi(e,t){let r=$r(e).find((o)=>o.strategy===t);if(!r.supported)throw Error(`${t} is unavailable: ${r.explanation}`);return r}import{createHash as dk}from"node:crypto";var lk=/^sha256:[a-f0-9]{64}$/,uk=/^[a-f0-9]{40,64}$/i;function ri(e){return typeof e==="string"&&e?e:void 0}function As(e,t){try{return JSON.parse(String(e))}catch{return t}}function Xf(e){return{id:String(e.id),organizationId:String(e.organization_id),digest:String(e.digest),kind:String(e.kind),uri:String(e.uri),size:Number(e.size),mediaType:String(e.media_type),provenance:As(e.provenance,{}),attestation:As(e.attestation,{}),verifiedAt:String(e.verified_at),createdAt:String(e.created_at)}}function eh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:String(e.environment_id),resourceId:String(e.resource_id),artifactId:String(e.artifact_id),kind:String(e.kind),sourceSha:ri(e.source_sha),configHash:String(e.config_hash),manifest:As(e.manifest,{}),provenance:As(e.provenance,{}),strategy:String(e.strategy),status:String(e.status),healthGate:e.health_gate==null?void 0:As(e.health_gate,void 0),hooks:As(e.hooks,{migrations:"none",preActivate:[],postActivate:[]}),drainSeconds:Number(e.drain_seconds),graceSeconds:Number(e.grace_seconds),automaticRollback:Number(e.automatic_rollback)===1,rollbackAttempts:Number(e.rollback_attempts),previousReleaseId:ri(e.previous_release_id),promotedFromReleaseId:ri(e.promoted_from_release_id),actorId:ri(e.actor_id),trigger:String(e.trigger),pinned:Number(e.pinned)===1,pinReason:ri(e.pin_reason),activatedAt:ri(e.activated_at),failedAt:ri(e.failed_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function pk(e){return{sequence:Number(e.sequence),id:String(e.id),releaseId:String(e.release_id),fromStatus:ri(e.from_status),toStatus:String(e.to_status),trafficPercent:e.traffic_percent==null?void 0:Number(e.traffic_percent),health:As(e.health,{}),message:String(e.message),operationId:ri(e.operation_id),createdAt:String(e.created_at)}}function mk(e,t){let r=[],o=(m,h,I)=>{if(JSON.stringify(h)===JSON.stringify(I))return;if(h&&I&&typeof h==="object"&&typeof I==="object"&&!Array.isArray(h)&&!Array.isArray(I)){for(let R of[...new Set([...Object.keys(h),...Object.keys(I)])].sort())o(m?`${m}.${R}`:R,h[R],I[R]);return}r.push({path:m,...h!==void 0?{before:h}:{},...I!==void 0?{after:I}:{}})};return o("",e,t),r}class fo{controlPlane;now;id;constructor(e,t={}){this.controlPlane=e;this.now=t.now??(()=>new Date),this.id=t.id??(()=>crypto.randomUUID())}registerArtifact(e){if(!lk.test(e.digest)||!/^(?:s3|https|oci|file):/.test(e.uri)||!Number.isInteger(e.size)||e.size<0)throw Error("Artifact requires a SHA-256 digest, supported immutable URI, and non-negative byte size");let t=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE organization_id=? AND digest=?").get(e.organizationId,e.digest);if(t)return Xf(t);let r=this.id(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_artifacts (id, organization_id, digest, kind, uri, size, media_type, provenance, attestation, verified_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.organizationId,e.digest,e.kind,e.uri,e.size,e.mediaType??"application/octet-stream",JSON.stringify(s(e.provenance??{})),JSON.stringify(s(e.attestation??{})),o,o]),this.getArtifact(r)}getArtifact(e){let t=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE id=?").get(e);return t?Xf(t):void 0}create(e){let t=this.getArtifact(e.artifactId),r=this.controlPlane.getResource(e.resourceId),o=this.controlPlane.listEnvironments(e.projectId).find((N)=>N.id===e.environmentId);if(!t||t.organizationId!==e.organizationId||t.kind!==e.kind)throw Error("Release artifact does not match the organization and deployable kind");if(!r||r.projectId!==e.projectId||r.environmentId!==e.environmentId||!o)throw Error("Release target scope does not match the resource");if(e.sourceSha&&!uk.test(e.sourceSha))throw Error("Release source must be an immutable commit SHA");vi({kind:e.kind,provider:r.provider,hasHealthGate:!!e.healthGate,replicas:e.replicas},e.strategy);let m=s(e.config),h=dk("sha256").update(JSON.stringify(m)).digest("hex"),I=this.active(e.resourceId),R=this.id(),A=this.now().toISOString(),E=e.approvalRequired?"awaiting_approval":"built",x=e.hooks??{migrations:"none",preActivate:[],postActivate:[]};return this.controlPlane.database.run("INSERT INTO releases (id, organization_id, project_id, environment_id, resource_id, artifact_id, kind, source_sha, config_hash, manifest, provenance, strategy, status, health_gate, hooks, drain_seconds, grace_seconds, automatic_rollback, previous_release_id, promoted_from_release_id, actor_id, trigger, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[R,e.organizationId,e.projectId,e.environmentId,e.resourceId,e.artifactId,e.kind,e.sourceSha??null,h,JSON.stringify(s(e.manifest)),JSON.stringify(s(e.provenance??{})),e.strategy,E,e.healthGate?JSON.stringify(e.healthGate):null,JSON.stringify(x),Math.max(0,Math.min(3600,Math.floor(e.drainSeconds??30))),Math.max(0,Math.min(3600,Math.floor(e.graceSeconds??30))),e.automaticRollback===!1?0:1,I?.id??null,e.promotedFromReleaseId??null,e.actorId??null,e.trigger??"manual",A,A]),this.recordTransition(R,void 0,E,{message:e.promotedFromReleaseId?"Immutable artifact promoted without rebuild.":"Immutable release record created."}),this.get(R)}get(e){let t=this.controlPlane.database.query("SELECT * FROM releases WHERE id=?").get(e);return t?eh(t):void 0}list(e={}){return this.controlPlane.database.query("SELECT * FROM releases ORDER BY created_at DESC, rowid DESC").all().map(eh).filter((t)=>(!e.projectId||t.projectId===e.projectId)&&(!e.environmentId||t.environmentId===e.environmentId)&&(!e.resourceId||t.resourceId===e.resourceId)&&(!e.status||t.status===e.status))}active(e){return this.list({resourceId:e,status:"active"})[0]}transitions(e){return this.controlPlane.database.query("SELECT * FROM release_transitions WHERE release_id=? ORDER BY sequence").all(e).map(pk)}recordTransition(e,t,r,o){this.controlPlane.database.run("INSERT INTO release_transitions (id, release_id, from_status, to_status, traffic_percent, health, message, operation_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",[this.id(),e,t??null,r,o.trafficPercent??null,JSON.stringify(s(o.health??{})),o.message.slice(0,1000),o.operationId??null,this.now().toISOString()])}progress(e,t){let r=this.get(e);if(!r)throw Error(`Release ${e} was not found`);return this.recordTransition(e,r.status,r.status,t),this.transitions(e).at(-1)}transition(e,t,r){let o=this.get(e);if(!o)throw Error(`Release ${e} was not found`);if(!{built:["awaiting_approval","activating","failed"],awaiting_approval:["built","failed"],activating:["active","failed","rolled_back"],active:["superseded","failed","rolled_back"],failed:["activating","rolled_back"],rolled_back:["activating"],superseded:["activating"]}[o.status].includes(t))throw Error(`Invalid release transition ${o.status} → ${t}`);let h=this.now().toISOString();if(t==="active"){let I=this.active(o.resourceId);if(I&&I.id!==e)this.controlPlane.database.run("UPDATE releases SET status='superseded', updated_at=? WHERE id=?",[h,I.id]),this.recordTransition(I.id,"active","superseded",{message:`Superseded by ${e}.`,operationId:r.operationId})}return this.controlPlane.database.run("UPDATE releases SET status=?, rollback_attempts=rollback_attempts+?, activated_at=CASE WHEN ?='active' THEN ? ELSE activated_at END, failed_at=CASE WHEN ?='failed' THEN ? ELSE failed_at END, updated_at=? WHERE id=?",[t,t==="rolled_back"?1:0,t,h,t,h,h,e]),this.recordTransition(e,o.status,t,r),this.get(e)}approve(e,t){let r=this.get(e);if(!r||r.status!=="awaiting_approval")throw Error("Release is not awaiting approval");let o=this.id(),m=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_approvals (id, release_id, environment_id, decision, actor_id, comment, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[o,e,r.environmentId,t.decision,t.actorId,t.comment?.slice(0,1000)??null,m]),this.transition(e,t.decision==="approved"?"built":"failed",{message:t.decision==="approved"?"Environment gate approved.":"Environment gate rejected."})}approvals(e){return this.controlPlane.database.query("SELECT * FROM release_approvals WHERE release_id=? ORDER BY created_at").all(e).map((t)=>({id:String(t.id),releaseId:String(t.release_id),environmentId:String(t.environment_id),decision:String(t.decision),actorId:String(t.actor_id),comment:ri(t.comment),createdAt:String(t.created_at)}))}promote(e,t){let r=this.get(e);if(!r||!["active","superseded"].includes(r.status))throw Error("Only a tested active/superseded release can be promoted");return this.create({organizationId:r.organizationId,projectId:r.projectId,environmentId:t.targetEnvironmentId,resourceId:t.targetResourceId,artifactId:r.artifactId,kind:r.kind,sourceSha:r.sourceSha,config:t.config,manifest:r.manifest,provenance:r.provenance,strategy:t.strategy??r.strategy,healthGate:t.healthGate??r.healthGate,hooks:r.hooks,drainSeconds:r.drainSeconds,graceSeconds:r.graceSeconds,automaticRollback:r.automaticRollback,promotedFromReleaseId:r.id,actorId:t.actorId,trigger:"promotion",approvalRequired:t.approvalRequired})}compare(e,t){let r=this.get(e),o=this.get(t);if(!r||!o)throw Error("Both releases are required for comparison");return{artifactChanged:r.artifactId!==o.artifactId,sourceChanged:r.sourceSha!==o.sourceSha,configChanged:r.configHash!==o.configHash,manifestChanges:mk(r.manifest,o.manifest),dataCaveat:o.hooks.migrations==="none"?"No database migration is recorded.":`Database hooks are ${o.hooks.migrations}; release rollback does not roll back data.`}}pin(e,t,r){if(!this.get(e))throw Error("Release was not found");return this.controlPlane.database.run("UPDATE releases SET pinned=?, pin_reason=?, updated_at=? WHERE id=?",[t?1:0,t?r?.slice(0,500)??"operator":null,this.now().toISOString(),e]),this.get(e)}retentionCandidates(e){let t=Math.max(1,Math.min(100,Math.floor(e.keepPerResource??10))),r=new Map;for(let o of this.list()){let m=r.get(o.resourceId)??[];m.push(o),r.set(o.resourceId,m)}return[...r.values()].flatMap((o)=>o.slice(t)).filter((o)=>new Date(o.createdAt)<e.before&&!o.pinned&&!["active","activating","awaiting_approval"].includes(o.status)&&!this.list().some((m)=>m.previousReleaseId===o.id&&["active","activating"].includes(m.status)))}}class lt{controlPlane;releases;queue;constructor(e){this.controlPlane=e;this.releases=new fo(e),this.queue=new c(e)}enqueueActivation(e,t={}){let r=this.releases.get(e.id);if(!r)throw Error("Release was not found");if(!["built","failed","rolled_back","superseded"].includes(r.status))throw Error(`Release ${r.status} cannot be activated`);let o=t.action??"activate",m=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:t.actorId,kind:`release.${o}`,idempotencyKey:`release:${r.id}:${o}:${r.rollbackAttempts}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:t.targetReleaseId??null},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:r.automaticRollback?2:1,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return this.releases.transition(r.id,"activating",{message:`${o} queued.`,operationId:m.id,trafficPercent:0}),m}completeHealthGate(e,t){let r=this.releases.get(e);if(!r||r.status!=="activating")throw Error("Release is not activating");if(t.healthy)return{release:this.releases.transition(r.id,"active",{message:t.message??"Health gate passed; activation completed.",operationId:t.operationId,trafficPercent:100,health:t.health})};let o=this.releases.transition(r.id,"failed",{message:t.message??"Health gate failed.",operationId:t.operationId,trafficPercent:0,health:t.health}),m=r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!r.automaticRollback||r.rollbackAttempts>=1||!m)return{release:o};let h=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,kind:"release.rollback",idempotencyKey:`release:${r.id}:automatic-rollback`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:m.id,automatic:!0},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return{release:o,rollbackOperation:h}}enqueueRollback(e,t={}){let r=this.releases.get(e.id);if(!r||r.status!=="active")throw Error("Only the active release can be rolled back");let o=t.targetReleaseId?this.releases.get(t.targetReleaseId):r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!o||o.resourceId!==r.resourceId||!["superseded","active"].includes(o.status))throw Error("Rollback requires a preserved prior release for the same resource");return this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:t.actorId,kind:"release.rollback",idempotencyKey:`release:${r.id}:manual-rollback:${o.id}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:o.id,automatic:!1},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation}}function Kg(e){if(e.strategy==="canary")return[5,25,50,100].map((t,r)=>({step:`canary-${t}`,trafficPercent:t,waitSeconds:r===3?e.drainSeconds:e.graceSeconds,requiresHealth:!0}));if(e.strategy==="blue_green")return[{step:"green-health",trafficPercent:0,waitSeconds:e.graceSeconds,requiresHealth:!0},{step:"traffic-switch",trafficPercent:100,waitSeconds:e.drainSeconds,requiresHealth:!0}];if(e.strategy==="rolling")return[{step:"rolling-replacement",trafficPercent:50,waitSeconds:e.graceSeconds,requiresHealth:!0},{step:"rolling-complete",trafficPercent:100,waitSeconds:e.drainSeconds,requiresHealth:!0}];return[{step:"immutable-switch",trafficPercent:100,waitSeconds:e.drainSeconds,requiresHealth:!!e.healthGate}]}async function $d(e,t){if(t.release.artifactId!==t.artifact.id)throw Error("Release activation artifact identity changed");vi({kind:t.release.kind,hasHealthGate:!!t.release.healthGate,replicas:Number(t.release.manifest?.replicas)||void 0},t.release.strategy);let r=e.capability(t);if(!r.supported)throw Error(`${t.release.strategy} is unavailable in ${e.name}: ${r.explanation}`);return e.activate({...t,transitions:Kg(t.release)})}async function Md(e,t){if(!t.previous)throw Error("Rollback requires the preserved previous release");return e.rollback({...t,transitions:[{step:"rollback",trafficPercent:0,waitSeconds:t.release.drainSeconds,requiresHealth:!0}]})}var Wg=["release.activate","release.rollback"];function gk(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function Fd(e){let t=new lt(e.store),r=async(o)=>{let m=gk(o.operation.input),h=typeof m.releaseId==="string"?m.releaseId:"",I=t.releases.get(h);if(!I)throw Error(`Queued release ${h||"(missing)"} was not found`);if(I.projectId!==o.operation.projectId||I.environmentId!==o.operation.environmentId||I.resourceId!==o.operation.resourceId)throw Error("Queued release does not match the operation scope");let R=t.releases.getArtifact(I.artifactId);if(!R||R.digest!==t.releases.getArtifact(I.artifactId)?.digest)throw Error("Immutable release artifact is unavailable");let A=typeof m.targetReleaseId==="string"&&m.targetReleaseId?m.targetReleaseId:I.previousReleaseId,E=A?t.releases.get(A):void 0;if(E&&(E.resourceId!==I.resourceId||E.artifactId===I.artifactId&&E.id===I.id))throw Error("Rollback target does not match the release resource");let x=await e.resolveDriver(I);o.checkpoint("verify",`Verifying ${R.digest} and ${I.configHash} for ${x.name}.`),o.log(`Artifact ${R.digest}; source ${I.sourceSha??"not recorded"}; config ${I.configHash}.`,{stream:"system"}),o.throwIfCancellationRequested();let N;try{N=o.operation.kind==="release.rollback"?await Md(x,{release:I,artifact:R,previous:E}):await $d(x,{release:I,artifact:R,previous:E})}catch(F){if(o.operation.kind==="release.activate"&&t.releases.get(I.id)?.status==="activating")t.completeHealthGate(I.id,{healthy:!1,operationId:o.operation.id,message:F instanceof Error?F.message:String(F)});throw F}for(let F of N.transitions)t.releases.progress(I.id,{message:`${o.operation.kind==="release.rollback"?"Rollback":"Activation"} traffic at ${F.trafficPercent}%.`,trafficPercent:F.trafficPercent,health:F.observed,operationId:o.operation.id}),o.log(`Traffic ${F.trafficPercent}%: ${F.healthy?"healthy":"unhealthy"}.`,{stream:F.healthy?"step":"stderr",step:"health"});if(o.checkpoint("health","Evaluating the provider health result."),!N.activated||!N.healthy){if(o.operation.kind==="release.activate"&&t.releases.get(I.id)?.status==="activating")t.completeHealthGate(I.id,{healthy:!1,operationId:o.operation.id,health:{resourceVersions:N.resourceVersions},message:N.error??"Provider health gate failed."});throw Error(N.error??`${x.name} reported an unhealthy release`)}if(o.operation.kind==="release.activate"&&I.healthGate?.name){if(!e.resolveHealthGate)throw t.completeHealthGate(I.id,{healthy:!1,operationId:o.operation.id,message:`Named health gate ${I.healthGate.name} is not available to this worker.`}),Error(`Named health gate ${I.healthGate.name} is unavailable`);o.checkpoint("named-health-gate",`Waiting on ${I.healthGate.name}.`);let F=await e.resolveHealthGate(I.healthGate.name,I);if(o.log(`${I.healthGate.name}: ${F.healthy?"healthy":"unhealthy"}${F.message?` — ${F.message}`:""}.`,{stream:F.healthy?"step":"stderr",step:"health"}),!F.healthy)throw t.completeHealthGate(I.id,{healthy:!1,operationId:o.operation.id,health:F.evidence,message:F.message??`Named health gate ${I.healthGate.name} failed.`}),Error(F.message??`Named health gate ${I.healthGate.name} failed`)}if(o.operation.kind==="release.rollback"){let F=t.releases.get(I.id);if(F.status!=="rolled_back")t.releases.transition(F.id,"rolled_back",{message:`Traffic restored through ${x.name}.`,operationId:o.operation.id,trafficPercent:0,health:{resourceVersions:N.resourceVersions}});if(E&&E.status!=="active"){let z=E.status==="activating"?E:t.releases.transition(E.id,"activating",{message:"Rollback target restoring traffic.",operationId:o.operation.id,trafficPercent:0});t.releases.transition(z.id,"active",{message:"Previous immutable release restored.",operationId:o.operation.id,trafficPercent:100,health:{resourceVersions:N.resourceVersions}})}}else t.completeHealthGate(I.id,{healthy:!0,operationId:o.operation.id,health:{providerVersion:N.providerVersion??null,resourceVersions:N.resourceVersions},message:"Provider activation and health gates completed."});return o.checkpoint("finalize","Persisted the terminal release state."),{releaseId:I.id,artifactDigest:R.digest,provider:x.name,providerVersion:N.providerVersion??null,resourceVersions:N.resourceVersions,status:t.releases.get(I.id).status}};return Object.fromEntries(Wg.map((o)=>[o,r]))}import{createCipheriv as fk,createDecipheriv as hk,createHash as oh,randomBytes as dp}from"node:crypto";var sh={github:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitlab:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},bitbucket:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitea:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!1,deployKeys:!0},generic_https:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!1},generic_ssh:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!0}};function or(e){return typeof e==="string"&&e?e:void 0}function _s(e,t){try{return typeof e==="string"?JSON.parse(e):t}catch{return t}}function ni(e){return JSON.stringify(s(e))}function Ps(e){return oh("sha256").update(e).digest("hex")}function th(e){let t=e.trim().replace(/\/$/,""),r=new URL(t.includes("://")?t:`https://${t}`);if(r.username||r.password||r.search||r.hash)throw Error("Source host cannot contain credentials, a query, or a fragment");if(r.protocol!=="https:"&&!(r.protocol==="http:"&&["localhost","127.0.0.1","::1"].includes(r.hostname)))throw Error("Source host must use HTTPS");return`${r.protocol}//${r.host}${r.pathname.replace(/\/$/,"")}`}function rh(e){let t=e.trim();if(t.length<2||t.length>80)throw Error("Connection name must contain 2-80 characters");return t}function lp(e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t))throw Error("Repository must use owner/name format");return t}function nh(e){let t=e.trim()||".";if(t.startsWith("/")||t.split("/").includes("..")||/[\0\r\n]/.test(t))throw Error("Monorepo root must stay inside the repository");return t.replace(/^\.\//,"")||"."}function zc(e){return[...new Set((e??[]).map((t)=>t.trim()).filter(Boolean))].slice(0,100)}function yk(e){let t=e.trim();if(/\r|\n/.test(t)||/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(t))throw Error("Clone URL cannot contain credentials or control characters");if(!/^(?:https?:\/\/|ssh:\/\/|git@[A-Za-z0-9.-]+:)/.test(t))throw Error("Clone URL must use HTTPS or SSH");return t}function vk(e){return{id:String(e.id),organizationId:String(e.organization_id),provider:String(e.provider),name:String(e.name),host:String(e.host),owner:or(e.owner),authKind:String(e.auth_kind),credentialConfigured:!!e.credential_ciphertext,credentialFingerprint:or(e.credential_fingerprint),grantedScopes:_s(e.granted_scopes,[]),capabilities:_s(e.capabilities,sh[String(e.provider)]),status:String(e.status),healthMessage:or(e.health_message),lastTestedAt:or(e.last_tested_at),lastSyncedAt:or(e.last_synced_at),credentialExpiresAt:or(e.credential_expires_at),version:Number(e.version),createdByActorId:or(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function up(e){return{id:String(e.id),connectionId:String(e.connection_id),providerRepositoryId:String(e.provider_repository_id),fullName:String(e.full_name),cloneUrl:String(e.clone_url),defaultBranch:String(e.default_branch),visibility:String(e.visibility),archived:Number(e.archived)===1,metadata:_s(e.metadata,{}),syncedAt:String(e.synced_at)}}function ih(e){return{id:String(e.id),projectId:String(e.project_id),environmentId:or(e.environment_id),resourceId:or(e.resource_id),connectionId:String(e.connection_id),repositoryId:or(e.repository_id),repositoryFullName:String(e.repository_full_name),defaultBranch:String(e.default_branch),branchRule:or(e.branch_rule),tagRule:or(e.tag_rule),monorepoRoot:String(e.monorepo_root),includePaths:_s(e.include_paths,[]),excludePaths:_s(e.exclude_paths,[]),submodules:Number(e.submodules)===1,cloneDepth:e.clone_depth==null?void 0:Number(e.clone_depth),deployKeyId:or(e.deploy_key_id),autoDeploy:Number(e.auto_deploy)===1,pullRequestPreviews:Number(e.pull_request_previews)===1,status:String(e.status),disabledReason:or(e.disabled_reason),version:Number(e.version),createdByActorId:or(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function pp(e){return{id:String(e.id),connectionId:String(e.connection_id),name:String(e.name),publicKey:String(e.public_key),publicKeyFingerprint:String(e.public_key_fingerprint),host:String(e.host),hostKey:String(e.host_key),hostKeyFingerprint:String(e.host_key_fingerprint),createdByActorId:or(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function mp(e){return{id:String(e.id),connectionId:String(e.connection_id),repositoryId:or(e.repository_id),repositoryFullName:String(e.repository_full_name),providerWebhookId:or(e.provider_webhook_id),events:_s(e.events,[]),status:String(e.status),healthMessage:or(e.health_message),lastDeliveryAt:or(e.last_delivery_at),lastReconciledAt:or(e.last_reconciled_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function gp(e){return{id:String(e.id),connectionId:String(e.connection_id),webhookId:String(e.webhook_id),providerDeliveryId:String(e.provider_delivery_id),event:String(e.event),action:or(e.action),commitSha:or(e.commit_sha),signatureStatus:String(e.signature_status),status:String(e.status),payloadSummary:_s(e.payload_summary,{}),operationId:or(e.operation_id),error:or(e.error),receivedAt:String(e.received_at),processedAt:or(e.processed_at)}}class Ao{controlPlane;key;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.key=t.encryptionKey?oh("sha256").update(t.encryptionKey).digest():void 0,this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}encrypt(e){if(!this.key)throw Error("Source credential encryption key is not configured");let t=dp(12),r=fk("aes-256-gcm",this.key,t),o=Buffer.concat([r.update(e,"utf8"),r.final()]);return`v1.${t.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${o.toString("base64url")}`}decrypt(e){if(!this.key)throw Error("Source credential encryption key is not configured");let[t,r,o,m]=e.split(".");if(t!=="v1"||!r||!o||!m)throw Error("Encrypted source credential is unavailable");let h=hk("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return h.setAuthTag(Buffer.from(o,"base64url")),Buffer.concat([h.update(Buffer.from(m,"base64url")),h.final()]).toString("utf8")}createConnection(e){if(!this.controlPlane.getOrganization(e.organizationId))throw Error("Source connection organization was not found");let t=this.now(),r=this.idFn(),o=e.credential?JSON.stringify(e.credential):void 0;return this.run(`INSERT INTO source_connections (id, organization_id, provider, name, host, owner, auth_kind, credential_ciphertext, credential_fingerprint, granted_scopes, capabilities, status, credential_expires_at, created_by_actor_id, created_at, updated_at)
43
43
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?)`,[r,e.organizationId,e.provider,rh(e.name),th(e.host),e.owner?.trim()||null,e.authKind??(o?"access_token":"none"),o?this.encrypt(o):null,o?Ps(o).slice(0,16):null,ni([...new Set(e.grantedScopes??[])].sort()),ni(sh[e.provider]),e.credentialExpiresAt??null,e.createdByActorId??null,t,t]),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.createdByActorId,type:"source.connection.created",payload:{connectionId:r,provider:e.provider,host:th(e.host),owner:e.owner??null,scopes:e.grantedScopes??[]}}),this.getConnection(r)}getConnection(e){let t=this.controlPlane.database.query("SELECT * FROM source_connections WHERE id = ?").get(e);return t?this.currentConnection(t):void 0}listConnections(e){return this.controlPlane.database.query("SELECT * FROM source_connections WHERE organization_id = ? ORDER BY name").all(e).map((t)=>this.currentConnection(t))}currentConnection(e){let t=vk(e);if(t.status!=="disconnected"&&t.credentialExpiresAt&&new Date(t.credentialExpiresAt).getTime()<=this.nowFn().getTime())return{...t,status:"expired",healthMessage:"Source credential expired; rotate it before deploying."};return t}getCredential(e){let t=this.controlPlane.database.query("SELECT credential_ciphertext FROM source_connections WHERE id = ?").get(e);return t?.credential_ciphertext?JSON.parse(this.decrypt(String(t.credential_ciphertext))):void 0}rotateCredential(e,t,r={}){let o=this.getConnection(e);if(!o||o.status==="disconnected")throw Error("Active source connection was not found");let m=JSON.stringify(t);return this.run("UPDATE source_connections SET credential_ciphertext = ?, credential_fingerprint = ?, credential_expires_at = ?, status = 'pending', health_message = NULL, version = version + 1, updated_at = ? WHERE id = ?",[this.encrypt(m),Ps(m).slice(0,16),r.expiresAt??null,this.now(),e]),this.controlPlane.appendEvent({organizationId:o.organizationId,actorId:r.actorId,type:"source.credential.rotated",payload:{connectionId:e,fingerprint:Ps(m).slice(0,16),expiresAt:r.expiresAt??null}}),this.getConnection(e)}updateHealth(e,t){let r=this.getConnection(e);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active source connection was not found");let o=this.now(),m=t.grantedScopes?[...new Set(t.grantedScopes.map((h)=>h.trim()).filter(Boolean))].sort():void 0;if(this.run("UPDATE source_connections SET status = ?, health_message = ?, granted_scopes = COALESCE(?, granted_scopes), last_tested_at = COALESCE(?, last_tested_at), last_synced_at = COALESCE(?, last_synced_at), version = version + 1, updated_at = ? WHERE id = ?",[t.status,t.message?.slice(0,1000)??null,m?ni(m):null,t.tested?o:null,t.synced?o:null,o,e]),m&&JSON.stringify(m)!==JSON.stringify([...r.grantedScopes].sort()))this.controlPlane.appendEvent({organizationId:r.organizationId,type:"source.connection.scopes_updated",payload:{connectionId:e,grantedScopes:m}});return this.getConnection(e)}upsertRepository(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status))throw Error("Active source connection was not found");let r=this.now(),o=this.controlPlane.database.query("SELECT id FROM source_repositories WHERE connection_id = ? AND provider_repository_id = ?").get(e.connectionId,e.providerRepositoryId),m=o?String(o.id):this.idFn();return this.run(`INSERT INTO source_repositories (id, connection_id, provider_repository_id, full_name, clone_url, default_branch, visibility, archived, metadata, synced_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
44
44
  ON CONFLICT(connection_id, provider_repository_id) DO UPDATE SET full_name=excluded.full_name, clone_url=excluded.clone_url, default_branch=excluded.default_branch, visibility=excluded.visibility, archived=excluded.archived, metadata=excluded.metadata, synced_at=excluded.synced_at`,[m,e.connectionId,e.providerRepositoryId,lp(e.fullName),yk(e.cloneUrl),e.defaultBranch.trim()||"main",e.visibility,e.archived?1:0,ni(e.metadata),r]),up(this.controlPlane.database.query("SELECT * FROM source_repositories WHERE id = ?").get(m))}listRepositories(e,t,r=100){let o=t?.trim().toLowerCase();return(o?this.controlPlane.database.query("SELECT * FROM source_repositories WHERE connection_id = ? AND lower(full_name) LIKE ? ORDER BY full_name LIMIT ?").all(e,`%${o}%`,Math.min(500,r)):this.controlPlane.database.query("SELECT * FROM source_repositories WHERE connection_id = ? ORDER BY full_name LIMIT ?").all(e,Math.min(500,r))).map(up)}getRepository(e){let t=this.controlPlane.database.query("SELECT * FROM source_repositories WHERE id = ?").get(e);return t?up(t):void 0}createDeployKey(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status)||!t.capabilities.deployKeys)throw Error("An active deploy-key capable source connection is required");if(!/^ssh-(?:ed25519|rsa)\s+[A-Za-z0-9+/=]+/.test(e.publicKey.trim()))throw Error("A valid SSH public key is required");if(!/BEGIN (?:OPENSSH|RSA) PRIVATE KEY/.test(e.privateKey))throw Error("A valid SSH private key is required");if(!/^(?:ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp\d+)\s+[A-Za-z0-9+/=]+/.test(e.hostKey.trim()))throw Error("A pinned SSH host key is required");let r=this.idFn(),o=this.now(),m=`sha256:${Ps(e.publicKey.trim())}`,h=`sha256:${Ps(e.hostKey.trim())}`;return this.run("INSERT INTO source_deploy_keys (id, connection_id, name, public_key, public_key_fingerprint, private_key_ciphertext, host, host_key, host_key_fingerprint, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.connectionId,rh(e.name),e.publicKey.trim(),m,this.encrypt(e.privateKey),e.host.trim().toLowerCase(),e.hostKey.trim(),h,e.actorId??null,o,o]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:e.actorId,type:"source.deploy_key.created",payload:{connectionId:e.connectionId,deployKeyId:r,publicFingerprint:m,hostFingerprint:h}}),pp(this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE id = ?").get(r))}getDeployKey(e){let t=this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE id = ?").get(e);return t?pp(t):void 0}listDeployKeys(e){return this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE connection_id = ? ORDER BY name, created_at").all(e).map(pp)}revokeDeployKey(e,t){let r=this.getDeployKey(e),o=r?this.getConnection(r.connectionId):void 0;if(!r||!o)throw Error("Deploy key was not found");let m=this.listBindings({connectionId:o.id}).filter((I)=>I.deployKeyId===e),h=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_bindings SET deploy_key_id=NULL, status='disabled', auto_deploy=0, disabled_reason='Source deploy key was revoked', version=version+1, updated_at=? WHERE deploy_key_id=?",[h,e]),this.run("DELETE FROM source_deploy_keys WHERE id=?",[e])})(),this.controlPlane.appendEvent({organizationId:o.organizationId,actorId:t,type:"source.deploy_key.revoked",level:"warning",payload:{connectionId:o.id,deployKeyId:e,affectedBindingIds:m.map((I)=>I.id)}}),{affectedBindings:m}}getDeployPrivateKey(e){let t=this.controlPlane.database.query("SELECT private_key_ciphertext FROM source_deploy_keys WHERE id = ?").get(e);if(!t)throw Error("Deploy key was not found");return this.decrypt(String(t.private_key_ciphertext))}createBinding(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status))throw Error("Active source connection was not found");if(e.repositoryId&&this.getRepository(e.repositoryId)?.connectionId!==t.id)throw Error("Repository does not belong to this connection");if(e.deployKeyId&&this.getDeployKey(e.deployKeyId)?.connectionId!==t.id)throw Error("Deploy key does not belong to this connection");let r=this.idFn(),o=this.now();return this.run(`INSERT INTO source_bindings (id, project_id, environment_id, resource_id, connection_id, repository_id, repository_full_name, default_branch, branch_rule, tag_rule, monorepo_root, include_paths, exclude_paths, submodules, clone_depth, deploy_key_id, auto_deploy, pull_request_previews, status, created_by_actor_id, created_at, updated_at)
45
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?)`,[r,e.projectId,e.environmentId??null,e.resourceId??null,e.connectionId,e.repositoryId??null,lp(e.repositoryFullName),e.defaultBranch?.trim()||"main",e.branchRule?.trim()||null,e.tagRule?.trim()||null,nh(e.monorepoRoot??"."),ni(zc(e.includePaths)),ni(zc(e.excludePaths)),e.submodules?1:0,e.cloneDepth??null,e.deployKeyId??null,e.autoDeploy===!1?0:1,e.pullRequestPreviews===!1?0:1,e.actorId??null,o,o]),this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:e.projectId,actorId:e.actorId,type:"source.binding.created",payload:{bindingId:r,connectionId:e.connectionId,repository:e.repositoryFullName,branch:e.defaultBranch??"main"}}),this.getBinding(r)}getBinding(e){let t=this.controlPlane.database.query("SELECT * FROM source_bindings WHERE id = ?").get(e);return t?ih(t):void 0}listBindings(e={}){return this.controlPlane.database.query("SELECT * FROM source_bindings ORDER BY created_at DESC").all().map(ih).filter((r)=>(!e.connectionId||r.connectionId===e.connectionId)&&(!e.projectId||r.projectId===e.projectId)&&(!e.status||r.status===e.status))}updateBinding(e,t,r){let o=this.getBinding(e);if(!o||o.version!==t)throw Error(`Source binding ${e} changed since version ${t}`);let m=this.getConnection(o.connectionId);if((!m||["disconnected","expired"].includes(m.status))&&(r.status==="active"||r.autoDeploy===!0))throw Error("Rotate or reconnect the source credential before enabling this binding");if(r.deployKeyId&&this.getDeployKey(r.deployKeyId)?.connectionId!==o.connectionId)throw Error("Deploy key does not belong to this connection");let h=this.now();if(this.controlPlane.database.run("UPDATE source_bindings SET default_branch=?, branch_rule=?, tag_rule=?, monorepo_root=?, include_paths=?, exclude_paths=?, submodules=?, clone_depth=?, deploy_key_id=?, auto_deploy=?, pull_request_previews=?, status=?, disabled_reason=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.defaultBranch?.trim()||o.defaultBranch,r.branchRule===void 0?o.branchRule??null:r.branchRule.trim()||null,r.tagRule===void 0?o.tagRule??null:r.tagRule.trim()||null,r.monorepoRoot===void 0?o.monorepoRoot:nh(r.monorepoRoot),ni(r.includePaths===void 0?o.includePaths:zc(r.includePaths)),ni(r.excludePaths===void 0?o.excludePaths:zc(r.excludePaths)),r.submodules??o.submodules?1:0,r.cloneDepth===void 0?o.cloneDepth??null:r.cloneDepth,r.deployKeyId===void 0?o.deployKeyId??null:r.deployKeyId,r.autoDeploy??o.autoDeploy?1:0,r.pullRequestPreviews??o.pullRequestPreviews?1:0,r.status??o.status,r.disabledReason===void 0?o.disabledReason??null:r.disabledReason.slice(0,1000),h,e,t]).changes!==1)throw Error(`Source binding ${e} changed since version ${t}`);let R=this.getConnection(o.connectionId);return this.controlPlane.appendEvent({organizationId:R.organizationId,projectId:o.projectId,actorId:r.actorId,type:"source.binding.updated",payload:{bindingId:e,fromVersion:t,toVersion:t+1,status:r.status??o.status}}),this.getBinding(e)}createWebhook(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status))throw Error("Active source connection was not found");if(e.repositoryId&&this.getRepository(e.repositoryId)?.connectionId!==t.id)throw Error("Repository does not belong to this connection");let r=this.idFn(),o=this.now(),m=e.endpointToken??dp(24).toString("base64url"),h=e.secret??dp(32).toString("base64url"),I=[...new Set(e.events??["push","pull_request"])].filter((R)=>["push","pull_request"].includes(R));if(!I.length)throw Error("At least one supported webhook event is required");return this.run("INSERT INTO source_webhooks (id, connection_id, repository_id, repository_full_name, endpoint_token_hash, endpoint_token_ciphertext, secret_ciphertext, events, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?)",[r,e.connectionId,e.repositoryId??null,lp(e.repositoryFullName),Ps(m),this.encrypt(m),this.encrypt(h),ni(I),o,o]),this.controlPlane.appendEvent({organizationId:t.organizationId,type:"source.webhook.created",payload:{webhookId:r,connectionId:t.id,repository:e.repositoryFullName,events:I}}),{webhook:{...this.getWebhook(r),endpointToken:m},secret:h}}getWebhook(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE id = ?").get(e);return t?mp(t):void 0}getWebhookByEndpointToken(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE endpoint_token_hash = ?").get(Ps(e));return t?mp(t):void 0}getWebhookSecret(e){let t=this.controlPlane.database.query("SELECT secret_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t)throw Error("Source webhook was not found");return this.decrypt(String(t.secret_ciphertext))}getWebhookEndpointToken(e){let t=this.controlPlane.database.query("SELECT endpoint_token_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t?.endpoint_token_ciphertext)throw Error("Source webhook endpoint token is unavailable");return this.decrypt(String(t.endpoint_token_ciphertext))}listWebhooks(e){return this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE connection_id = ? ORDER BY repository_full_name").all(e).map(mp)}updateWebhookState(e,t){let r=this.getWebhook(e);if(!r)throw Error("Source webhook was not found");let o=this.now();this.run("UPDATE source_webhooks SET provider_webhook_id=COALESCE(?, provider_webhook_id), status=?, health_message=?, last_reconciled_at=COALESCE(?, last_reconciled_at), updated_at=? WHERE id=?",[t.providerWebhookId??null,t.status,t.healthMessage?.slice(0,1000)??null,t.reconciled?o:null,o,e]);let m=this.getConnection(r.connectionId);if(m)this.controlPlane.appendEvent({organizationId:m.organizationId,type:"source.webhook.updated",payload:{webhookId:e,connectionId:m.id,repository:r.repositoryFullName,status:t.status,reconciled:t.reconciled??!1,providerWebhookId:t.providerWebhookId??r.providerWebhookId??null}});return this.getWebhook(e)}getDeliveryByProviderId(e,t){let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE connection_id = ? AND provider_delivery_id = ?").get(e,t);return r?gp(r):void 0}recordDelivery(e){let t=this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId);if(t)return{delivery:t,duplicate:!0};let r=this.idFn(),o=this.now();return this.controlPlane.database.transaction(()=>{this.run("INSERT INTO source_webhook_deliveries (id, connection_id, webhook_id, provider_delivery_id, event, action, commit_sha, signature_status, status, payload_summary, operation_id, error, received_at, processed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.connectionId,e.webhookId,e.providerDeliveryId,e.event.slice(0,100),e.action?.slice(0,100)??null,e.commitSha?.slice(0,128)??null,e.signatureStatus,e.status,ni(e.payloadSummary??{}),e.operationId??null,e.error?.slice(0,2000)??null,o,["enqueued","ignored","rejected","failed"].includes(e.status)?o:null]),this.run("UPDATE source_webhooks SET last_delivery_at=?, updated_at=? WHERE id=?",[o,o,e.webhookId])})(),{delivery:this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId),duplicate:!1}}updateDelivery(e,t){this.run("UPDATE source_webhook_deliveries SET status=?, operation_id=?, error=?, processed_at=? WHERE id=?",[t.status,t.operationId??null,t.error?.slice(0,2000)??null,this.now(),e]);let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE id = ?").get(e);if(!r)throw Error("Source webhook delivery was not found");return gp(r)}listDeliveries(e,t=100){return this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE webhook_id = ? ORDER BY received_at DESC LIMIT ?").all(e,Math.min(500,Math.max(1,t))).map(gp)}disconnectConnection(e,t){let r=this.getConnection(e);if(!r)throw Error("Source connection was not found");let o=this.listBindings({connectionId:e,status:"active"}),m=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_connections SET status='disconnected', credential_ciphertext=NULL, health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[m,e]),this.run("UPDATE source_bindings SET status='disabled', auto_deploy=0, disabled_reason='Source connection was disconnected', version=version+1, updated_at=? WHERE connection_id=? AND status='active'",[m,e]),this.run("UPDATE source_webhooks SET status='disabled', health_message='Source connection was disconnected', updated_at=? WHERE connection_id=?",[m,e])})(),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"source.connection.disconnected",level:"warning",payload:{connectionId:e,affectedBindingIds:o.map((h)=>h.id),affectedRepositories:o.map((h)=>h.repositoryFullName)}}),{connection:this.getConnection(e),affectedBindings:o}}}import{createSign as bk}from"node:crypto";class qt extends Error{status;retryAfterSeconds;constructor(e,t,r){super(e);this.status=t;this.retryAfterSeconds=r;this.name="SourceProviderError"}}var ch={repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0};function ts(e){let t=Number(e??"1");return Number.isInteger(t)&&t>0?t:1}function rs(e){return Math.max(1,Math.min(100,e??50))}function Mn(e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t))throw Error("Repository must use owner/name format");return t}function nc(e){let t=new URL(e);if(t.username||t.password||t.protocol!=="https:")throw Error("Webhook endpoint must be credential-free HTTPS");return t.href}function ah(e){return Buffer.from(e).toString("base64url")}function Sk(e,t){if(!e.appId||!e.privateKey)throw Error("GitHub App credentials require appId and privateKey");let r=ah(JSON.stringify({alg:"RS256",typ:"JWT"})),o=Math.floor(t.getTime()/1000)-30,m=ah(JSON.stringify({iat:o,exp:o+540,iss:e.appId})),h=bk("RSA-SHA256");return h.update(`${r}.${m}`),h.end(),`${r}.${m}.${h.sign(e.privateKey).toString("base64url")}`}class ic{connection;credential;capabilities=ch;fetchFn;timeoutMs;nowFn;constructor(e,t,r={}){this.connection=e;this.credential=t;this.fetchFn=r.fetch??((o,m)=>globalThis.fetch(o,m)),this.timeoutMs=Math.max(100,r.timeoutMs??20000),this.nowFn=r.now??(()=>new Date)}async request(e,t={}){let r=new URL(`${this.apiRoot().replace(/\/$/,"")}/`),o=new URL(e.replace(/^\//,""),r);if(o.origin!==r.origin)throw Error("Provider pagination cannot leave the configured host");let m=new AbortController,h=setTimeout(()=>m.abort(),this.timeoutMs);try{let I=await this.fetchFn(o,{...t,redirect:"error",signal:m.signal,headers:{Accept:"application/json","User-Agent":"ts-cloud-source/1",...await this.authorization(),...t.headers}});if(!I.ok){let R=Number(I.headers.get("retry-after")??""),A=I.headers.get("x-request-id")??I.headers.get("x-github-request-id");throw new qt(`Source provider request failed (${I.status})${A?` [request ${A}]`:""}`,I.status,Number.isFinite(R)?R:void 0)}if(I.status===204)return{data:void 0,headers:I.headers};return{data:await I.json(),headers:I.headers}}catch(I){if(I instanceof qt)throw I;if(m.signal.aborted)throw new qt(`Source provider request exceeded ${this.timeoutMs}ms`);throw new qt(I instanceof Error?I.message.replace(/(?:token|password|secret)=[^\s&]+/gi,"$1=[REDACTED]"):"Source provider request failed")}finally{clearTimeout(h)}}async deleteWebhook(e,t){await this.request(this.webhookPath(e,t),{method:"DELETE"})}}class Ud extends ic{provider="github";installationToken;apiRoot(){return this.connection.host==="https://github.com"?"https://api.github.com":`${this.connection.host}/api/v3`}async authorization(){if(this.credential?.token)return{Authorization:`Bearer ${this.credential.token}`,"X-GitHub-Api-Version":"2022-11-28"};if(!this.credential?.installationId)return{};if(!this.installationToken||this.installationToken.expiresAt<this.nowFn().getTime()+60000){let e=Sk(this.credential,this.nowFn()),t=this.apiRoot().replace(/\/$/,""),r=new AbortController,o=setTimeout(()=>r.abort(),this.timeoutMs);try{let m=await this.fetchFn(`${t}/app/installations/${encodeURIComponent(this.credential.installationId)}/access_tokens`,{method:"POST",signal:r.signal,redirect:"error",headers:{Accept:"application/vnd.github+json",Authorization:`Bearer ${e}`,"X-GitHub-Api-Version":"2022-11-28","User-Agent":"ts-cloud-source/1"}});if(!m.ok)throw new qt(`GitHub App token refresh failed (${m.status})`,m.status);let h=await m.json();this.installationToken={value:h.token,expiresAt:new Date(h.expires_at).getTime()}}finally{clearTimeout(o)}}return{Authorization:`Bearer ${this.installationToken.value}`,"X-GitHub-Api-Version":"2022-11-28"}}async testConnection(){let e=this.credential?.installationId?"/installation/repositories?per_page=1":"/user",{data:t,headers:r}=await this.request(e);return{ok:!0,account:t.login??this.connection.owner,scopes:(r.get("x-oauth-scopes")??this.connection.grantedScopes.join(",")).split(",").map((o)=>o.trim()).filter(Boolean),message:"GitHub connection is healthy"}}async listRepositories(e={}){let t=rs(e.limit),r=ts(e.cursor),o=this.credential?.installationId?`/installation/repositories?per_page=${t}&page=${r}`:`/user/repos?per_page=${t}&page=${r}&sort=updated`,{data:m}=await this.request(o),h=Array.isArray(m)?m:m.repositories;return{repositories:(e.search?h.filter((R)=>R.full_name.toLowerCase().includes(e.search.toLowerCase())):h).map((R)=>({providerRepositoryId:String(R.id),fullName:R.full_name,cloneUrl:R.clone_url,defaultBranch:R.default_branch||"main",visibility:R.visibility??(R.private?"private":"public"),archived:!!R.archived,metadata:{}})),nextCursor:h.length===t?String(r+1):void 0}}async refs(e,t,r={}){let o=rs(r.limit),m=ts(r.cursor),{data:h}=await this.request(`/repos/${Mn(e)}/${t}?per_page=${o}&page=${m}`);return{refs:h.map((I)=>({name:I.name,commitSha:I.commit.sha,protected:I.protected})),nextCursor:h.length===o?String(m+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Mn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events,url:e.config.url??""}}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:JSON.stringify({name:"web",active:!0,events:t.events,config:{url:nc(t.url),content_type:"json",secret:t.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:JSON.stringify({active:!0,events:r.events,config:{url:nc(r.url),content_type:"json",secret:r.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){await this.request(`/repos/${Mn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}class Qd extends ic{provider="gitlab";apiRoot(){return`${this.connection.host}/api/v4`}async authorization(){return this.credential?.token?{"PRIVATE-TOKEN":this.credential.token}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username,scopes:this.connection.grantedScopes,message:"GitLab connection is healthy"}}async listRepositories(e={}){let t=rs(e.limit),r=ts(e.cursor),o=e.search?`&search=${encodeURIComponent(e.search)}`:"",{data:m,headers:h}=await this.request(`/projects?membership=true&simple=true&order_by=last_activity_at&per_page=${t}&page=${r}${o}`);return{repositories:m.map((I)=>({providerRepositoryId:String(I.id),fullName:I.path_with_namespace,cloneUrl:I.http_url_to_repo,defaultBranch:I.default_branch??"main",visibility:I.visibility??"unknown",archived:!!I.archived,metadata:{}})),nextCursor:h.get("x-next-page")||void 0}}async refs(e,t,r={}){let o=rs(r.limit),m=ts(r.cursor),{data:h,headers:I}=await this.request(`/projects/${encodeURIComponent(Mn(e))}/repository/${t}?per_page=${o}&page=${m}`);return{refs:h.map((R)=>({name:R.name,commitSha:R.commit.id,protected:R.protected})),nextCursor:I.get("x-next-page")||void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/projects/${encodeURIComponent(Mn(e))}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:!0,events:[...e.push_events?["push"]:[],...e.merge_requests_events?["pull_request"]:[]],url:e.url}}body(e){return JSON.stringify({url:nc(e.url),token:e.secret,enable_ssl_verification:!0,push_events:e.events.includes("push"),merge_requests_events:e.events.includes("pull_request")})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){let o=r.state==="failure"||r.state==="error"?"failed":r.state;await this.request(`/projects/${encodeURIComponent(Mn(e))}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:o,target_url:r.url,description:r.description.slice(0,255),name:r.context??"ts-cloud/preview"})})}}class Hd extends ic{provider="bitbucket";apiRoot(){return this.connection.host==="https://bitbucket.org"?"https://api.bitbucket.org/2.0":`${this.connection.host}/2.0`}async authorization(){return this.credential?.token?{Authorization:`Bearer ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username??e.display_name,scopes:this.connection.grantedScopes,message:"Bitbucket connection is healthy"}}async listRepositories(e={}){if(!this.connection.owner)throw Error("Bitbucket repository discovery requires an owner/workspace");let t=ts(e.cursor),r=rs(e.limit),o=e.search?`&q=name~%22${encodeURIComponent(e.search)}%22`:"",{data:m}=await this.request(`/repositories/${encodeURIComponent(this.connection.owner)}?pagelen=${r}&page=${t}${o}`);return{repositories:m.values.map((h)=>({providerRepositoryId:h.uuid,fullName:h.full_name,cloneUrl:h.links.clone.find((I)=>I.name==="https")?.href??h.links.clone[0]?.href??"",defaultBranch:h.mainbranch?.name??"main",visibility:h.is_private?"private":"public",archived:!1,metadata:{}})),nextCursor:m.next?String(t+1):void 0}}async refs(e,t,r={}){let o=ts(r.cursor),m=rs(r.limit),{data:h}=await this.request(`/repositories/${Mn(e)}/refs/${t}?pagelen=${m}&page=${o}`);return{refs:h.values.map((I)=>({name:I.name,commitSha:I.target.hash})),nextCursor:h.next?String(o+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repositories/${Mn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:e.uuid,active:e.active,events:e.events.map((t)=>t.replace("repo:push","push").replace("pullrequest:","pull_request:")),url:e.url}}body(e){return JSON.stringify({description:"ts-cloud deploy",url:nc(e.url),active:!0,events:e.events.map((t)=>t==="push"?"repo:push":t.replace("pull_request:","pullrequest:"))})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.values.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){let o=r.state==="success"?"SUCCESSFUL":r.state==="pending"?"INPROGRESS":"FAILED";await this.request(`/repositories/${Mn(e)}/commit/${encodeURIComponent(t)}/statuses/build/ts-cloud-preview`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:o,key:"ts-cloud-preview",name:r.context??"ts-cloud/preview",url:r.url,description:r.description.slice(0,255)})})}}class Gd extends ic{provider="gitea";capabilities={...ch,tokenRefresh:!1};apiRoot(){return`${this.connection.host}/api/v1`}async authorization(){return this.credential?.token?{Authorization:`token ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.login,scopes:this.connection.grantedScopes,message:"Gitea connection is healthy"}}async listRepositories(e={}){let t=ts(e.cursor),r=rs(e.limit),o=e.search?`/repos/search?q=${encodeURIComponent(e.search)}&limit=${r}&page=${t}`:`/user/repos?limit=${r}&page=${t}`,{data:m,headers:h}=await this.request(o),I=Array.isArray(m)?m:m.data;return{repositories:I.map((R)=>({providerRepositoryId:String(R.id),fullName:R.full_name,cloneUrl:R.clone_url,defaultBranch:R.default_branch??"main",visibility:R.private?"private":"public",archived:!!R.archived,metadata:{}})),nextCursor:h.get("x-hasmore")==="true"||I.length===r?String(t+1):void 0}}async refs(e,t,r={}){let o=ts(r.cursor),m=rs(r.limit),{data:h}=await this.request(`/repos/${Mn(e)}/${t}?limit=${m}&page=${o}`);return{refs:h.map((I)=>({name:I.name,commitSha:I.commit.id})),nextCursor:h.length===m?String(o+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Mn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events??[],url:e.config.url??""}}body(e){return JSON.stringify({type:"gitea",active:!0,events:e.events,config:{url:nc(e.url),content_type:"json",secret:e.secret,insecure_ssl:"0"}})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){await this.request(`/repos/${Mn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}function Ve(e,t,r={}){switch(e.provider){case"github":return new Ud(e,t,r);case"gitlab":return new Qd(e,t,r);case"bitbucket":return new Hd(e,t,r);case"gitea":return new Gd(e,t,r);default:throw Error(`${e.provider} uses bounded Git discovery instead of a hosted provider API`)}}import{createHmac as wk,timingSafeEqual as kk}from"node:crypto";function hn(e,t){if(e instanceof Headers)return e.get(t)??void 0;return Object.entries(e).find(([o])=>o.toLowerCase()===t.toLowerCase())?.[1]}function dh(e,t){let r=Buffer.from(e),o=Buffer.from(t);return r.length===o.length&&kk(r,o)}function Ik(e,t){return wk("sha256",e).update(t).digest("hex")}function Ek(e,t,r,o,m){if(e==="gitlab")return dh(hn(r,"x-gitlab-token")??"",t);let h=e==="github"?hn(r,"x-hub-signature-256"):e==="gitea"?hn(r,"x-gitea-signature"):hn(r,"x-hub-signature")??hn(r,"x-ts-cloud-signature");if(!h)return!1;if(e==="generic_https"||e==="generic_ssh"){let I=Number(hn(r,"x-ts-cloud-timestamp"));if(!Number.isFinite(I)||Math.abs(m.getTime()-I*1000)>300000)return!1}return dh(h.replace(/^sha256=/,""),Ik(t,o))}function Rk(e,t){return{github:["x-github-delivery"],gitlab:["x-gitlab-event-uuid","x-request-id"],bitbucket:["x-request-uuid"],gitea:["x-gitea-delivery"],generic_https:["x-ts-cloud-delivery"],generic_ssh:["x-ts-cloud-delivery"]}[e].map((o)=>hn(t,o)?.trim()).find(Boolean)}function ns(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");return/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t)?t:""}function fp(e){return[...new Set(e.flatMap((t)=>{if(!t||typeof t!=="object")return[];let r=t;return[...r.added??[],...r.modified??[],...r.removed??[]].map(String)}).filter((t)=>t&&!t.includes("\x00")).slice(0,500))]}function Jg(e,t,r){let o=e,m=t,h=r;if(o==="github"){let I=hn(m,"x-github-event"),R=ns(h.repository?.full_name);if(I==="push")return{event:"push",repository:R,ref:String(h.ref??""),branch:String(h.ref??"").replace(/^refs\/heads\//,""),tag:String(h.ref??"").startsWith("refs/tags/")?String(h.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(h.after??h.head_commit?.id??""),changedPaths:fp(h.commits??[]),deleted:h.deleted===!0||/^0{40,64}$/.test(String(h.after??""))};if(I==="pull_request")return{event:"pull_request",action:String(h.action??""),repository:R,branch:String(h.pull_request?.head?.ref??""),commitSha:String(h.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(h.number)||void 0,fork:ns(h.pull_request?.head?.repo?.full_name)!==R}}if(o==="gitlab"){let I=String(h.object_kind??"").toLowerCase(),R=ns(h.project?.path_with_namespace);if(I==="push"||I==="tag_push")return{event:"push",repository:R,ref:String(h.ref??""),branch:String(h.ref??"").replace(/^refs\/heads\//,""),tag:I==="tag_push"?String(h.ref??"").replace(/^refs\/tags\//,""):void 0,commitSha:String(h.checkout_sha??h.after??""),changedPaths:fp(h.commits??[]),deleted:/^0{40,64}$/.test(String(h.after??""))};if(I==="merge_request")return{event:"pull_request",action:String(h.object_attributes?.action??h.object_attributes?.state??""),repository:R,branch:String(h.object_attributes?.source_branch??""),commitSha:String(h.object_attributes?.last_commit?.id??""),changedPaths:[],pullRequestNumber:Number(h.object_attributes?.iid)||void 0,fork:h.object_attributes?.source_project_id!==h.object_attributes?.target_project_id}}if(o==="bitbucket"){let I=hn(m,"x-event-key")??"",R=ns(h.repository?.full_name);if(I==="repo:push"){let A=h.push?.changes?.[0]??{},E=A.new??A.old??{},x=A.new?.target??A.old?.target;return{event:"push",repository:R,ref:String(E.name??""),branch:E.type==="branch"?String(E.name):void 0,tag:E.type==="tag"?String(E.name):void 0,commitSha:String(x?.hash??""),changedPaths:[],deleted:A.closed===!0||A.new==null}}if(I.startsWith("pullrequest:"))return{event:"pull_request",action:I.replace("pullrequest:",""),repository:R,branch:String(h.pullrequest?.source?.branch?.name??""),commitSha:String(h.pullrequest?.source?.commit?.hash??""),changedPaths:[],pullRequestNumber:Number(h.pullrequest?.id)||void 0,fork:ns(h.pullrequest?.source?.repository?.full_name)!==R}}if(o==="gitea"){let I=hn(m,"x-gitea-event"),R=ns(h.repository?.full_name);if(I==="push")return{event:"push",repository:R,ref:String(h.ref??""),branch:String(h.ref??"").replace(/^refs\/heads\//,""),tag:String(h.ref??"").startsWith("refs/tags/")?String(h.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(h.after??""),changedPaths:fp(h.commits??[]),deleted:h.deleted===!0||/^0{40,64}$/.test(String(h.after??""))};if(I==="pull_request")return{event:"pull_request",action:String(h.action??""),repository:R,branch:String(h.pull_request?.head?.ref??""),commitSha:String(h.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(h.number)||void 0,fork:ns(h.pull_request?.head?.repo?.full_name)!==R}}if(o==="generic_https"||o==="generic_ssh"){if(h.event!=="push"&&h.event!=="pull_request")return;return{event:h.event,action:typeof h.action==="string"?h.action:void 0,repository:ns(h.repository),ref:typeof h.ref==="string"?h.ref:void 0,branch:typeof h.branch==="string"?h.branch:void 0,tag:typeof h.tag==="string"?h.tag:void 0,commitSha:String(h.commitSha??""),changedPaths:Array.isArray(h.changedPaths)?h.changedPaths.map(String).slice(0,500):[],pullRequestNumber:Number(h.pullRequestNumber)||void 0,fork:h.fork===!0,deleted:h.deleted===!0}}return}function ba(e,t){let r="^";for(let o=0;o<t.length;o++){let m=t[o];if(m==="*"&&t[o+1]==="*")r+=".*",o++;else if(m==="*")r+="[^/]*";else if(m==="?")r+="[^/]";else r+=m.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")}return new RegExp(`${r}$`).test(e)}function Ak(e,t){if(t.event==="pull_request")return e.pullRequestPreviews;if(!e.autoDeploy)return!1;if(t.tag)return!!e.tagRule&&ba(t.tag,e.tagRule);return ba(t.branch??"",e.branchRule??e.defaultBranch)}function Ck(e,t){if(!t.length)return!0;return t.filter((o)=>!e.excludePaths.some((m)=>ba(o,m))).some((o)=>!e.includePaths.length||e.includePaths.some((m)=>ba(o,m)))}function lh(e,t){return hn(t,e==="github"?"x-github-event":e==="gitlab"?"x-gitlab-event":e==="bitbucket"?"x-event-key":e==="gitea"?"x-gitea-event":"x-ts-cloud-event")??"unknown"}function Ts(){return{accepted:!1,duplicate:!1,status:"rejected",operations:[],message:"Webhook unavailable"}}async function qd(e){if(e.rawBody.byteLength>2097152)return Ts();let t=e.sources.getWebhookByEndpointToken(e.endpointToken);if(!t||t.status==="disabled")return Ts();let r=e.sources.getConnection(t.connectionId);if(!r||r.status==="disconnected"||r.status==="expired")return Ts();let o=Rk(r.provider,e.headers);if(!o||o.length>200)return Ts();if(!Ek(r.provider,e.sources.getWebhookSecret(t.id),e.headers,e.rawBody,e.now??new Date))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:o,event:lh(r.provider,e.headers),signatureStatus:hn(e.headers,"x-hub-signature-256")||hn(e.headers,"x-gitlab-token")||hn(e.headers,"x-hub-signature")||hn(e.headers,"x-gitea-signature")?"invalid":"missing",status:"rejected",error:"Webhook signature verification failed"}),Ts();let h;try{h=JSON.parse(new TextDecoder().decode(e.rawBody))}catch{return Ts()}let I=Jg(r.provider,e.headers,h);if(!I||!I.repository||!/^[a-f0-9]{7,64}$/i.test(I.commitSha))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:o,event:lh(r.provider,e.headers),signatureStatus:"verified",status:"rejected",error:"Unsupported or malformed source event"}),Ts();let R=e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:o,event:I.event,action:I.action,commitSha:I.commitSha,signatureStatus:"verified",status:"accepted",payloadSummary:{repository:I.repository,ref:I.ref??null,branch:I.branch??null,tag:I.tag??null,commitSha:I.commitSha,pullRequestNumber:I.pullRequestNumber??null,changedPathCount:I.changedPaths.length}});if(R.duplicate&&R.delivery.status!=="accepted")return{accepted:!0,duplicate:!0,status:"duplicate",operations:[],message:"Delivery already processed"};let A=new $e(e.controlPlane),E=e.sources.listBindings({connectionId:r.id,status:"active"}).filter((z)=>{if(z.repositoryFullName.toLowerCase()!==I.repository.toLowerCase()||!Ck(z,I.changedPaths))return!1;let H=z.resourceId?A.getDefinitionForResource(z.resourceId):void 0,K=I.event==="push"&&!!H?.branchRule&&!!I.branch&&ba(I.branch,H.branchRule);return Ak(z,I)||K});if(!E.length)return e.sources.updateDelivery(R.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:R.duplicate,status:"ignored",operations:[],message:"Verified event did not match an active deployment rule"};let x=new c(e.controlPlane),N=new Set(["closed","merged","declined"]),F=E.flatMap((z)=>{if(I.event==="push"&&z.resourceId&&I.branch){let K=A.getDefinitionForResource(z.resourceId);if(K?.branchRule&&ba(I.branch,K.branchRule)){let X=A.findForBranch(K.id,I.repository,I.branch);if(I.deleted){if(!K.cleanupOnClose||!X||X.status==="destroyed")return[];let fe=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${X.id}:branch-delete:${o}`,correlationId:`preview:${X.id}`,input:{previewId:X.id,reason:"branch_deleted",source:{repository:I.repository,commitSha:I.commitSha,branch:I.branch}},lockKey:`preview:${X.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(X.id,"queued",{operationId:fe.id}),[fe]}let oe=A.upsert({definitionId:K.id,sourceProvider:r.provider,repository:I.repository,branch:I.branch,commitSha:I.commitSha});if(!oe.changed)return[];let ye=oe.created?"preview.create":"preview.update",ne=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:ye,idempotencyKey:`preview:${oe.preview.id}:${I.commitSha}`,correlationId:`preview:${oe.preview.id}`,input:{previewId:oe.preview.id,source:{connectionId:r.id,bindingId:z.id,repository:I.repository,commitSha:I.commitSha,branch:I.branch,monorepoRoot:z.monorepoRoot,submodules:z.submodules,cloneDepth:z.cloneDepth??null}},lockKey:`preview:${oe.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(oe.preview.id,"queued",{operationId:ne.id}),[ne]}}if(I.event==="pull_request"&&z.resourceId&&I.pullRequestNumber){let K=A.getDefinitionForResource(z.resourceId);if(K){let X=N.has(String(I.action??"").toLowerCase()),oe=A.findForPullRequest(K.id,I.repository,I.pullRequestNumber);if(X){if(!K.cleanupOnClose||!oe||oe.status==="destroyed")return[];let ye=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${oe.id}:destroy:${o}`,correlationId:`preview:${oe.id}`,input:{previewId:oe.id,reason:"pull_request_closed",source:{repository:I.repository,commitSha:I.commitSha,branch:I.branch??null,pullRequestNumber:I.pullRequestNumber}},lockKey:`preview:${oe.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(oe.id,"queued",{operationId:ye.id}),[ye]}try{let ye=A.upsert({definitionId:K.id,sourceProvider:r.provider,repository:I.repository,branch:I.branch??`pr-${I.pullRequestNumber}`,pullRequestNumber:I.pullRequestNumber,fork:I.fork,commitSha:I.commitSha});if(!ye.changed)return[];let ne=ye.created?"preview.create":"preview.update",fe=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:ne,idempotencyKey:`preview:${ye.preview.id}:${I.commitSha}`,correlationId:`preview:${ye.preview.id}`,input:{previewId:ye.preview.id,source:{connectionId:r.id,bindingId:z.id,repository:I.repository,commitSha:I.commitSha,branch:I.branch??null,pullRequestNumber:I.pullRequestNumber,fork:!!I.fork,monorepoRoot:z.monorepoRoot,submodules:z.submodules,cloneDepth:z.cloneDepth??null},inheritedSecretNames:ye.inheritedSecrets},lockKey:`preview:${ye.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(ye.preview.id,"queued",{operationId:fe.id}),[fe]}catch(ye){return e.controlPlane.appendEvent({projectId:z.projectId,resourceId:z.resourceId,type:"preview.rejected",level:"warning",payload:{repository:I.repository,pullRequestNumber:I.pullRequestNumber,fork:!!I.fork,reason:ye instanceof Error?ye.message:String(ye)}}),[]}}}let H=I.event==="pull_request"?"deploy.preview":"deploy.source";return[x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:H,idempotencyKey:`source:${r.id}:${o}:${z.id}:${I.commitSha}`,correlationId:`source:${o}`,input:{source:{connectionId:r.id,bindingId:z.id,repository:I.repository,commitSha:I.commitSha,branch:I.branch??null,tag:I.tag??null,monorepoRoot:z.monorepoRoot,submodules:z.submodules,cloneDepth:z.cloneDepth??null},preview:I.event==="pull_request"?{number:I.pullRequestNumber??null,action:I.action??null}:null},lockKey:z.resourceId?`resource:${z.resourceId}`:`environment:${z.environmentId??z.projectId}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:I.event==="pull_request"?14:90}).operation]});if(!F.length)return e.sources.updateDelivery(R.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:R.duplicate,status:"ignored",operations:[],message:"Verified event required no preview lifecycle change"};return e.sources.updateDelivery(R.delivery.id,{status:"enqueued",operationId:F[0]?.id}),e.controlPlane.appendEvent({organizationId:r.organizationId,projectId:E[0]?.projectId,operationId:F[0]?.id,type:"source.webhook.enqueued",payload:{webhookId:t.id,deliveryId:R.delivery.id,repository:I.repository,commitSha:I.commitSha,operationIds:F.map((z)=>z.id)}}),{accepted:!0,duplicate:R.duplicate,status:"enqueued",operations:F,message:`${F.length} deployment operation${F.length===1?"":"s"} enqueued`}}function Vt(e,t){if(!t.endpointToken)throw Error("The webhook endpoint token is only available at creation time");let r=new URL(e);if(r.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(r.hostname))throw Error("Webhook base URL must use HTTPS");return new URL(`/api/source/webhooks/${encodeURIComponent(t.endpointToken)}`,r).href}import{chmodSync as uh,mkdtempSync as Pk,rmSync as _k,writeFileSync as ph}from"node:fs";import{tmpdir as Tk}from"node:os";import{join as Uc,resolve as xk}from"node:path";function gh(e,t){let r=e.trim();if(/\r|\n|\0/.test(r))throw Error("Git remote contains control characters");if(r.startsWith("https://")){let m=new URL(r);if(m.username||m.password||m.search||m.hash)throw Error("HTTPS Git remotes cannot contain credentials, queries, or fragments");return m.href}let o=r.startsWith("ssh://")?new URL(r).hostname:r.match(/^git@([A-Za-z0-9.-]+):/)?.[1];if(!o)throw Error("Git remote must use credential-free HTTPS or SSH");if(!t||t.host.toLowerCase()!==o.toLowerCase())throw Error("SSH Git remote requires a deploy key with a pinned key for the same host");return r}function Dk(e,t,r){let o=e.replaceAll(t,"[REMOTE]").slice(0,4000);for(let m of[r?.token,r?.privateKey])if(m)o=o.replaceAll(m,"[REDACTED]");return o}function Ok(e){let t={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_NOSYSTEM:"1",GIT_OPTIONAL_LOCKS:"0"},r;if(e.credential?.token){let o=e.credential.username??"oauth2";t.GIT_CONFIG_COUNT="1",t.GIT_CONFIG_KEY_0="http.extraHeader",t.GIT_CONFIG_VALUE_0=`Authorization: Basic ${Buffer.from(`${o}:${e.credential.token}`).toString("base64")}`}if(e.deployKey){r=Pk(Uc(Tk(),"ts-cloud-git-transport-"));let o=Uc(r,"key"),m=Uc(r,"known_hosts");ph(o,e.deployKey.privateKey,{mode:384}),ph(m,`${e.deployKey.host} ${e.deployKey.hostKey}
45
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?)`,[r,e.projectId,e.environmentId??null,e.resourceId??null,e.connectionId,e.repositoryId??null,lp(e.repositoryFullName),e.defaultBranch?.trim()||"main",e.branchRule?.trim()||null,e.tagRule?.trim()||null,nh(e.monorepoRoot??"."),ni(zc(e.includePaths)),ni(zc(e.excludePaths)),e.submodules?1:0,e.cloneDepth??null,e.deployKeyId??null,e.autoDeploy===!1?0:1,e.pullRequestPreviews===!1?0:1,e.actorId??null,o,o]),this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:e.projectId,actorId:e.actorId,type:"source.binding.created",payload:{bindingId:r,connectionId:e.connectionId,repository:e.repositoryFullName,branch:e.defaultBranch??"main"}}),this.getBinding(r)}getBinding(e){let t=this.controlPlane.database.query("SELECT * FROM source_bindings WHERE id = ?").get(e);return t?ih(t):void 0}listBindings(e={}){return this.controlPlane.database.query("SELECT * FROM source_bindings ORDER BY created_at DESC").all().map(ih).filter((r)=>(!e.connectionId||r.connectionId===e.connectionId)&&(!e.projectId||r.projectId===e.projectId)&&(!e.status||r.status===e.status))}updateBinding(e,t,r){let o=this.getBinding(e);if(!o||o.version!==t)throw Error(`Source binding ${e} changed since version ${t}`);let m=this.getConnection(o.connectionId);if((!m||["disconnected","expired"].includes(m.status))&&(r.status==="active"||r.autoDeploy===!0))throw Error("Rotate or reconnect the source credential before enabling this binding");if(r.deployKeyId&&this.getDeployKey(r.deployKeyId)?.connectionId!==o.connectionId)throw Error("Deploy key does not belong to this connection");let h=this.now();if(this.controlPlane.database.run("UPDATE source_bindings SET default_branch=?, branch_rule=?, tag_rule=?, monorepo_root=?, include_paths=?, exclude_paths=?, submodules=?, clone_depth=?, deploy_key_id=?, auto_deploy=?, pull_request_previews=?, status=?, disabled_reason=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.defaultBranch?.trim()||o.defaultBranch,r.branchRule===void 0?o.branchRule??null:r.branchRule.trim()||null,r.tagRule===void 0?o.tagRule??null:r.tagRule.trim()||null,r.monorepoRoot===void 0?o.monorepoRoot:nh(r.monorepoRoot),ni(r.includePaths===void 0?o.includePaths:zc(r.includePaths)),ni(r.excludePaths===void 0?o.excludePaths:zc(r.excludePaths)),r.submodules??o.submodules?1:0,r.cloneDepth===void 0?o.cloneDepth??null:r.cloneDepth,r.deployKeyId===void 0?o.deployKeyId??null:r.deployKeyId,r.autoDeploy??o.autoDeploy?1:0,r.pullRequestPreviews??o.pullRequestPreviews?1:0,r.status??o.status,r.disabledReason===void 0?o.disabledReason??null:r.disabledReason.slice(0,1000),h,e,t]).changes!==1)throw Error(`Source binding ${e} changed since version ${t}`);let R=this.getConnection(o.connectionId);return this.controlPlane.appendEvent({organizationId:R.organizationId,projectId:o.projectId,actorId:r.actorId,type:"source.binding.updated",payload:{bindingId:e,fromVersion:t,toVersion:t+1,status:r.status??o.status}}),this.getBinding(e)}createWebhook(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status))throw Error("Active source connection was not found");if(e.repositoryId&&this.getRepository(e.repositoryId)?.connectionId!==t.id)throw Error("Repository does not belong to this connection");let r=this.idFn(),o=this.now(),m=e.endpointToken??dp(24).toString("base64url"),h=e.secret??dp(32).toString("base64url"),I=[...new Set(e.events??["push","pull_request"])].filter((R)=>["push","pull_request"].includes(R));if(!I.length)throw Error("At least one supported webhook event is required");return this.run("INSERT INTO source_webhooks (id, connection_id, repository_id, repository_full_name, endpoint_token_hash, endpoint_token_ciphertext, secret_ciphertext, events, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?)",[r,e.connectionId,e.repositoryId??null,lp(e.repositoryFullName),Ps(m),this.encrypt(m),this.encrypt(h),ni(I),o,o]),this.controlPlane.appendEvent({organizationId:t.organizationId,type:"source.webhook.created",payload:{webhookId:r,connectionId:t.id,repository:e.repositoryFullName,events:I}}),{webhook:{...this.getWebhook(r),endpointToken:m},secret:h}}getWebhook(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE id = ?").get(e);return t?mp(t):void 0}getWebhookByEndpointToken(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE endpoint_token_hash = ?").get(Ps(e));return t?mp(t):void 0}getWebhookSecret(e){let t=this.controlPlane.database.query("SELECT secret_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t)throw Error("Source webhook was not found");return this.decrypt(String(t.secret_ciphertext))}getWebhookEndpointToken(e){let t=this.controlPlane.database.query("SELECT endpoint_token_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t?.endpoint_token_ciphertext)throw Error("Source webhook endpoint token is unavailable");return this.decrypt(String(t.endpoint_token_ciphertext))}listWebhooks(e){return this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE connection_id = ? ORDER BY repository_full_name").all(e).map(mp)}updateWebhookState(e,t){let r=this.getWebhook(e);if(!r)throw Error("Source webhook was not found");let o=this.now();this.run("UPDATE source_webhooks SET provider_webhook_id=COALESCE(?, provider_webhook_id), status=?, health_message=?, last_reconciled_at=COALESCE(?, last_reconciled_at), updated_at=? WHERE id=?",[t.providerWebhookId??null,t.status,t.healthMessage?.slice(0,1000)??null,t.reconciled?o:null,o,e]);let m=this.getConnection(r.connectionId);if(m)this.controlPlane.appendEvent({organizationId:m.organizationId,type:"source.webhook.updated",payload:{webhookId:e,connectionId:m.id,repository:r.repositoryFullName,status:t.status,reconciled:t.reconciled??!1,providerWebhookId:t.providerWebhookId??r.providerWebhookId??null}});return this.getWebhook(e)}getDeliveryByProviderId(e,t){let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE connection_id = ? AND provider_delivery_id = ?").get(e,t);return r?gp(r):void 0}recordDelivery(e){let t=this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId);if(t)return{delivery:t,duplicate:!0};let r=this.idFn(),o=this.now();return this.controlPlane.database.transaction(()=>{this.run("INSERT INTO source_webhook_deliveries (id, connection_id, webhook_id, provider_delivery_id, event, action, commit_sha, signature_status, status, payload_summary, operation_id, error, received_at, processed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.connectionId,e.webhookId,e.providerDeliveryId,e.event.slice(0,100),e.action?.slice(0,100)??null,e.commitSha?.slice(0,128)??null,e.signatureStatus,e.status,ni(e.payloadSummary??{}),e.operationId??null,e.error?.slice(0,2000)??null,o,["enqueued","ignored","rejected","failed"].includes(e.status)?o:null]),this.run("UPDATE source_webhooks SET last_delivery_at=?, updated_at=? WHERE id=?",[o,o,e.webhookId])})(),{delivery:this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId),duplicate:!1}}updateDelivery(e,t){this.run("UPDATE source_webhook_deliveries SET status=?, operation_id=?, error=?, processed_at=? WHERE id=?",[t.status,t.operationId??null,t.error?.slice(0,2000)??null,this.now(),e]);let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE id = ?").get(e);if(!r)throw Error("Source webhook delivery was not found");return gp(r)}listDeliveries(e,t=100){return this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE webhook_id = ? ORDER BY received_at DESC LIMIT ?").all(e,Math.min(500,Math.max(1,t))).map(gp)}disconnectConnection(e,t){let r=this.getConnection(e);if(!r)throw Error("Source connection was not found");let o=this.listBindings({connectionId:e,status:"active"}),m=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_connections SET status='disconnected', credential_ciphertext=NULL, health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[m,e]),this.run("UPDATE source_bindings SET status='disabled', auto_deploy=0, disabled_reason='Source connection was disconnected', version=version+1, updated_at=? WHERE connection_id=? AND status='active'",[m,e]),this.run("UPDATE source_webhooks SET status='disabled', health_message='Source connection was disconnected', updated_at=? WHERE connection_id=?",[m,e])})(),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"source.connection.disconnected",level:"warning",payload:{connectionId:e,affectedBindingIds:o.map((h)=>h.id),affectedRepositories:o.map((h)=>h.repositoryFullName)}}),{connection:this.getConnection(e),affectedBindings:o}}}import{createSign as bk}from"node:crypto";class qt extends Error{status;retryAfterSeconds;constructor(e,t,r){super(e);this.status=t;this.retryAfterSeconds=r;this.name="SourceProviderError"}}var ch={repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0};function ts(e){let t=Number(e??"1");return Number.isInteger(t)&&t>0?t:1}function rs(e){return Math.max(1,Math.min(100,e??50))}function Mn(e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t))throw Error("Repository must use owner/name format");return t}function nc(e){let t=new URL(e);if(t.username||t.password||t.protocol!=="https:")throw Error("Webhook endpoint must be credential-free HTTPS");return t.href}function ah(e){return Buffer.from(e).toString("base64url")}function Sk(e,t){if(!e.appId||!e.privateKey)throw Error("GitHub App credentials require appId and privateKey");let r=ah(JSON.stringify({alg:"RS256",typ:"JWT"})),o=Math.floor(t.getTime()/1000)-30,m=ah(JSON.stringify({iat:o,exp:o+540,iss:e.appId})),h=bk("RSA-SHA256");return h.update(`${r}.${m}`),h.end(),`${r}.${m}.${h.sign(e.privateKey).toString("base64url")}`}class ic{connection;credential;capabilities=ch;fetchFn;timeoutMs;nowFn;constructor(e,t,r={}){this.connection=e;this.credential=t;this.fetchFn=r.fetch??((o,m)=>globalThis.fetch(o,m)),this.timeoutMs=Math.max(100,r.timeoutMs??20000),this.nowFn=r.now??(()=>new Date)}async request(e,t={}){let r=new URL(`${this.apiRoot().replace(/\/$/,"")}/`),o=new URL(e.replace(/^\//,""),r);if(o.origin!==r.origin)throw Error("Provider pagination cannot leave the configured host");let m=new AbortController,h=setTimeout(()=>m.abort(),this.timeoutMs);try{let I=await this.fetchFn(o,{...t,redirect:"error",signal:m.signal,headers:{Accept:"application/json","User-Agent":"ts-cloud-source/1",...await this.authorization(),...t.headers}});if(!I.ok){let R=Number(I.headers.get("retry-after")??""),A=I.headers.get("x-request-id")??I.headers.get("x-github-request-id");throw new qt(`Source provider request failed (${I.status})${A?` [request ${A}]`:""}`,I.status,Number.isFinite(R)?R:void 0)}if(I.status===204)return{data:void 0,headers:I.headers};return{data:await I.json(),headers:I.headers}}catch(I){if(I instanceof qt)throw I;if(m.signal.aborted)throw new qt(`Source provider request exceeded ${this.timeoutMs}ms`);throw new qt(I instanceof Error?I.message.replace(/(?:token|password|secret)=[^\s&]+/gi,"$1=[REDACTED]"):"Source provider request failed")}finally{clearTimeout(h)}}async deleteWebhook(e,t){await this.request(this.webhookPath(e,t),{method:"DELETE"})}}class Ud extends ic{provider="github";installationToken;apiRoot(){return this.connection.host==="https://github.com"?"https://api.github.com":`${this.connection.host}/api/v3`}async authorization(){if(this.credential?.token)return{Authorization:`Bearer ${this.credential.token}`,"X-GitHub-Api-Version":"2022-11-28"};if(!this.credential?.installationId)return{};if(!this.installationToken||this.installationToken.expiresAt<this.nowFn().getTime()+60000){let e=Sk(this.credential,this.nowFn()),t=this.apiRoot().replace(/\/$/,""),r=new AbortController,o=setTimeout(()=>r.abort(),this.timeoutMs);try{let m=await this.fetchFn(`${t}/app/installations/${encodeURIComponent(this.credential.installationId)}/access_tokens`,{method:"POST",signal:r.signal,redirect:"error",headers:{Accept:"application/vnd.github+json",Authorization:`Bearer ${e}`,"X-GitHub-Api-Version":"2022-11-28","User-Agent":"ts-cloud-source/1"}});if(!m.ok)throw new qt(`GitHub App token refresh failed (${m.status})`,m.status);let h=await m.json();this.installationToken={value:h.token,expiresAt:new Date(h.expires_at).getTime()}}finally{clearTimeout(o)}}return{Authorization:`Bearer ${this.installationToken.value}`,"X-GitHub-Api-Version":"2022-11-28"}}async testConnection(){let e=this.credential?.installationId?"/installation/repositories?per_page=1":"/user",{data:t,headers:r}=await this.request(e);return{ok:!0,account:t.login??this.connection.owner,scopes:(r.get("x-oauth-scopes")??this.connection.grantedScopes.join(",")).split(",").map((o)=>o.trim()).filter(Boolean),message:"GitHub connection is healthy"}}async listRepositories(e={}){let t=rs(e.limit),r=ts(e.cursor),o=this.credential?.installationId?`/installation/repositories?per_page=${t}&page=${r}`:`/user/repos?per_page=${t}&page=${r}&sort=updated`,{data:m}=await this.request(o),h=Array.isArray(m)?m:m.repositories;return{repositories:(e.search?h.filter((R)=>R.full_name.toLowerCase().includes(e.search.toLowerCase())):h).map((R)=>({providerRepositoryId:String(R.id),fullName:R.full_name,cloneUrl:R.clone_url,defaultBranch:R.default_branch||"main",visibility:R.visibility??(R.private?"private":"public"),archived:!!R.archived,metadata:{}})),nextCursor:h.length===t?String(r+1):void 0}}async refs(e,t,r={}){let o=rs(r.limit),m=ts(r.cursor),{data:h}=await this.request(`/repos/${Mn(e)}/${t}?per_page=${o}&page=${m}`);return{refs:h.map((I)=>({name:I.name,commitSha:I.commit.sha,protected:I.protected})),nextCursor:h.length===o?String(m+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Mn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events,url:e.config.url??""}}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:JSON.stringify({name:"web",active:!0,events:t.events,config:{url:nc(t.url),content_type:"json",secret:t.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:JSON.stringify({active:!0,events:r.events,config:{url:nc(r.url),content_type:"json",secret:r.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){await this.request(`/repos/${Mn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}class Qd extends ic{provider="gitlab";apiRoot(){return`${this.connection.host}/api/v4`}async authorization(){return this.credential?.token?{"PRIVATE-TOKEN":this.credential.token}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username,scopes:this.connection.grantedScopes,message:"GitLab connection is healthy"}}async listRepositories(e={}){let t=rs(e.limit),r=ts(e.cursor),o=e.search?`&search=${encodeURIComponent(e.search)}`:"",{data:m,headers:h}=await this.request(`/projects?membership=true&simple=true&order_by=last_activity_at&per_page=${t}&page=${r}${o}`);return{repositories:m.map((I)=>({providerRepositoryId:String(I.id),fullName:I.path_with_namespace,cloneUrl:I.http_url_to_repo,defaultBranch:I.default_branch??"main",visibility:I.visibility??"unknown",archived:!!I.archived,metadata:{}})),nextCursor:h.get("x-next-page")||void 0}}async refs(e,t,r={}){let o=rs(r.limit),m=ts(r.cursor),{data:h,headers:I}=await this.request(`/projects/${encodeURIComponent(Mn(e))}/repository/${t}?per_page=${o}&page=${m}`);return{refs:h.map((R)=>({name:R.name,commitSha:R.commit.id,protected:R.protected})),nextCursor:I.get("x-next-page")||void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/projects/${encodeURIComponent(Mn(e))}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:!0,events:[...e.push_events?["push"]:[],...e.merge_requests_events?["pull_request"]:[]],url:e.url}}body(e){return JSON.stringify({url:nc(e.url),token:e.secret,enable_ssl_verification:!0,push_events:e.events.includes("push"),merge_requests_events:e.events.includes("pull_request")})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){let o=r.state==="failure"||r.state==="error"?"failed":r.state;await this.request(`/projects/${encodeURIComponent(Mn(e))}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:o,target_url:r.url,description:r.description.slice(0,255),name:r.context??"ts-cloud/preview"})})}}class Hd extends ic{provider="bitbucket";apiRoot(){return this.connection.host==="https://bitbucket.org"?"https://api.bitbucket.org/2.0":`${this.connection.host}/2.0`}async authorization(){return this.credential?.token?{Authorization:`Bearer ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username??e.display_name,scopes:this.connection.grantedScopes,message:"Bitbucket connection is healthy"}}async listRepositories(e={}){if(!this.connection.owner)throw Error("Bitbucket repository discovery requires an owner/workspace");let t=ts(e.cursor),r=rs(e.limit),o=e.search?`&q=name~%22${encodeURIComponent(e.search)}%22`:"",{data:m}=await this.request(`/repositories/${encodeURIComponent(this.connection.owner)}?pagelen=${r}&page=${t}${o}`);return{repositories:m.values.map((h)=>({providerRepositoryId:h.uuid,fullName:h.full_name,cloneUrl:h.links.clone.find((I)=>I.name==="https")?.href??h.links.clone[0]?.href??"",defaultBranch:h.mainbranch?.name??"main",visibility:h.is_private?"private":"public",archived:!1,metadata:{}})),nextCursor:m.next?String(t+1):void 0}}async refs(e,t,r={}){let o=ts(r.cursor),m=rs(r.limit),{data:h}=await this.request(`/repositories/${Mn(e)}/refs/${t}?pagelen=${m}&page=${o}`);return{refs:h.values.map((I)=>({name:I.name,commitSha:I.target.hash})),nextCursor:h.next?String(o+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repositories/${Mn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:e.uuid,active:e.active,events:e.events.map((t)=>t.replace("repo:push","push").replace("pullrequest:","pull_request:")),url:e.url}}body(e){return JSON.stringify({description:"ts-cloud deploy",url:nc(e.url),active:!0,events:e.events.map((t)=>t==="push"?"repo:push":t.replace("pull_request:","pullrequest:"))})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.values.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){let o=r.state==="success"?"SUCCESSFUL":r.state==="pending"?"INPROGRESS":"FAILED";await this.request(`/repositories/${Mn(e)}/commit/${encodeURIComponent(t)}/statuses/build/ts-cloud-preview`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:o,key:"ts-cloud-preview",name:r.context??"ts-cloud/preview",url:r.url,description:r.description.slice(0,255)})})}}class Gd extends ic{provider="gitea";capabilities={...ch,tokenRefresh:!1};apiRoot(){return`${this.connection.host}/api/v1`}async authorization(){return this.credential?.token?{Authorization:`token ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.login,scopes:this.connection.grantedScopes,message:"Gitea connection is healthy"}}async listRepositories(e={}){let t=ts(e.cursor),r=rs(e.limit),o=e.search?`/repos/search?q=${encodeURIComponent(e.search)}&limit=${r}&page=${t}`:`/user/repos?limit=${r}&page=${t}`,{data:m,headers:h}=await this.request(o),I=Array.isArray(m)?m:m.data;return{repositories:I.map((R)=>({providerRepositoryId:String(R.id),fullName:R.full_name,cloneUrl:R.clone_url,defaultBranch:R.default_branch??"main",visibility:R.private?"private":"public",archived:!!R.archived,metadata:{}})),nextCursor:h.get("x-hasmore")==="true"||I.length===r?String(t+1):void 0}}async refs(e,t,r={}){let o=ts(r.cursor),m=rs(r.limit),{data:h}=await this.request(`/repos/${Mn(e)}/${t}?limit=${m}&page=${o}`);return{refs:h.map((I)=>({name:I.name,commitSha:I.commit.id})),nextCursor:h.length===m?String(o+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Mn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events??[],url:e.config.url??""}}body(e){return JSON.stringify({type:"gitea",active:!0,events:e.events,config:{url:nc(e.url),content_type:"json",secret:e.secret,insecure_ssl:"0"}})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:o}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(o)}async setCommitStatus(e,t,r){await this.request(`/repos/${Mn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}function je(e,t,r={}){switch(e.provider){case"github":return new Ud(e,t,r);case"gitlab":return new Qd(e,t,r);case"bitbucket":return new Hd(e,t,r);case"gitea":return new Gd(e,t,r);default:throw Error(`${e.provider} uses bounded Git discovery instead of a hosted provider API`)}}import{createHmac as wk,timingSafeEqual as kk}from"node:crypto";function hn(e,t){if(e instanceof Headers)return e.get(t)??void 0;return Object.entries(e).find(([o])=>o.toLowerCase()===t.toLowerCase())?.[1]}function dh(e,t){let r=Buffer.from(e),o=Buffer.from(t);return r.length===o.length&&kk(r,o)}function Ik(e,t){return wk("sha256",e).update(t).digest("hex")}function Ek(e,t,r,o,m){if(e==="gitlab")return dh(hn(r,"x-gitlab-token")??"",t);let h=e==="github"?hn(r,"x-hub-signature-256"):e==="gitea"?hn(r,"x-gitea-signature"):hn(r,"x-hub-signature")??hn(r,"x-ts-cloud-signature");if(!h)return!1;if(e==="generic_https"||e==="generic_ssh"){let I=Number(hn(r,"x-ts-cloud-timestamp"));if(!Number.isFinite(I)||Math.abs(m.getTime()-I*1000)>300000)return!1}return dh(h.replace(/^sha256=/,""),Ik(t,o))}function Rk(e,t){return{github:["x-github-delivery"],gitlab:["x-gitlab-event-uuid","x-request-id"],bitbucket:["x-request-uuid"],gitea:["x-gitea-delivery"],generic_https:["x-ts-cloud-delivery"],generic_ssh:["x-ts-cloud-delivery"]}[e].map((o)=>hn(t,o)?.trim()).find(Boolean)}function ns(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");return/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t)?t:""}function fp(e){return[...new Set(e.flatMap((t)=>{if(!t||typeof t!=="object")return[];let r=t;return[...r.added??[],...r.modified??[],...r.removed??[]].map(String)}).filter((t)=>t&&!t.includes("\x00")).slice(0,500))]}function Jg(e,t,r){let o=e,m=t,h=r;if(o==="github"){let I=hn(m,"x-github-event"),R=ns(h.repository?.full_name);if(I==="push")return{event:"push",repository:R,ref:String(h.ref??""),branch:String(h.ref??"").replace(/^refs\/heads\//,""),tag:String(h.ref??"").startsWith("refs/tags/")?String(h.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(h.after??h.head_commit?.id??""),changedPaths:fp(h.commits??[]),deleted:h.deleted===!0||/^0{40,64}$/.test(String(h.after??""))};if(I==="pull_request")return{event:"pull_request",action:String(h.action??""),repository:R,branch:String(h.pull_request?.head?.ref??""),commitSha:String(h.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(h.number)||void 0,fork:ns(h.pull_request?.head?.repo?.full_name)!==R}}if(o==="gitlab"){let I=String(h.object_kind??"").toLowerCase(),R=ns(h.project?.path_with_namespace);if(I==="push"||I==="tag_push")return{event:"push",repository:R,ref:String(h.ref??""),branch:String(h.ref??"").replace(/^refs\/heads\//,""),tag:I==="tag_push"?String(h.ref??"").replace(/^refs\/tags\//,""):void 0,commitSha:String(h.checkout_sha??h.after??""),changedPaths:fp(h.commits??[]),deleted:/^0{40,64}$/.test(String(h.after??""))};if(I==="merge_request")return{event:"pull_request",action:String(h.object_attributes?.action??h.object_attributes?.state??""),repository:R,branch:String(h.object_attributes?.source_branch??""),commitSha:String(h.object_attributes?.last_commit?.id??""),changedPaths:[],pullRequestNumber:Number(h.object_attributes?.iid)||void 0,fork:h.object_attributes?.source_project_id!==h.object_attributes?.target_project_id}}if(o==="bitbucket"){let I=hn(m,"x-event-key")??"",R=ns(h.repository?.full_name);if(I==="repo:push"){let A=h.push?.changes?.[0]??{},E=A.new??A.old??{},x=A.new?.target??A.old?.target;return{event:"push",repository:R,ref:String(E.name??""),branch:E.type==="branch"?String(E.name):void 0,tag:E.type==="tag"?String(E.name):void 0,commitSha:String(x?.hash??""),changedPaths:[],deleted:A.closed===!0||A.new==null}}if(I.startsWith("pullrequest:"))return{event:"pull_request",action:I.replace("pullrequest:",""),repository:R,branch:String(h.pullrequest?.source?.branch?.name??""),commitSha:String(h.pullrequest?.source?.commit?.hash??""),changedPaths:[],pullRequestNumber:Number(h.pullrequest?.id)||void 0,fork:ns(h.pullrequest?.source?.repository?.full_name)!==R}}if(o==="gitea"){let I=hn(m,"x-gitea-event"),R=ns(h.repository?.full_name);if(I==="push")return{event:"push",repository:R,ref:String(h.ref??""),branch:String(h.ref??"").replace(/^refs\/heads\//,""),tag:String(h.ref??"").startsWith("refs/tags/")?String(h.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(h.after??""),changedPaths:fp(h.commits??[]),deleted:h.deleted===!0||/^0{40,64}$/.test(String(h.after??""))};if(I==="pull_request")return{event:"pull_request",action:String(h.action??""),repository:R,branch:String(h.pull_request?.head?.ref??""),commitSha:String(h.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(h.number)||void 0,fork:ns(h.pull_request?.head?.repo?.full_name)!==R}}if(o==="generic_https"||o==="generic_ssh"){if(h.event!=="push"&&h.event!=="pull_request")return;return{event:h.event,action:typeof h.action==="string"?h.action:void 0,repository:ns(h.repository),ref:typeof h.ref==="string"?h.ref:void 0,branch:typeof h.branch==="string"?h.branch:void 0,tag:typeof h.tag==="string"?h.tag:void 0,commitSha:String(h.commitSha??""),changedPaths:Array.isArray(h.changedPaths)?h.changedPaths.map(String).slice(0,500):[],pullRequestNumber:Number(h.pullRequestNumber)||void 0,fork:h.fork===!0,deleted:h.deleted===!0}}return}function ba(e,t){let r="^";for(let o=0;o<t.length;o++){let m=t[o];if(m==="*"&&t[o+1]==="*")r+=".*",o++;else if(m==="*")r+="[^/]*";else if(m==="?")r+="[^/]";else r+=m.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")}return new RegExp(`${r}$`).test(e)}function Ak(e,t){if(t.event==="pull_request")return e.pullRequestPreviews;if(!e.autoDeploy)return!1;if(t.tag)return!!e.tagRule&&ba(t.tag,e.tagRule);return ba(t.branch??"",e.branchRule??e.defaultBranch)}function Ck(e,t){if(!t.length)return!0;return t.filter((o)=>!e.excludePaths.some((m)=>ba(o,m))).some((o)=>!e.includePaths.length||e.includePaths.some((m)=>ba(o,m)))}function lh(e,t){return hn(t,e==="github"?"x-github-event":e==="gitlab"?"x-gitlab-event":e==="bitbucket"?"x-event-key":e==="gitea"?"x-gitea-event":"x-ts-cloud-event")??"unknown"}function Ts(){return{accepted:!1,duplicate:!1,status:"rejected",operations:[],message:"Webhook unavailable"}}async function qd(e){if(e.rawBody.byteLength>2097152)return Ts();let t=e.sources.getWebhookByEndpointToken(e.endpointToken);if(!t||t.status==="disabled")return Ts();let r=e.sources.getConnection(t.connectionId);if(!r||r.status==="disconnected"||r.status==="expired")return Ts();let o=Rk(r.provider,e.headers);if(!o||o.length>200)return Ts();if(!Ek(r.provider,e.sources.getWebhookSecret(t.id),e.headers,e.rawBody,e.now??new Date))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:o,event:lh(r.provider,e.headers),signatureStatus:hn(e.headers,"x-hub-signature-256")||hn(e.headers,"x-gitlab-token")||hn(e.headers,"x-hub-signature")||hn(e.headers,"x-gitea-signature")?"invalid":"missing",status:"rejected",error:"Webhook signature verification failed"}),Ts();let h;try{h=JSON.parse(new TextDecoder().decode(e.rawBody))}catch{return Ts()}let I=Jg(r.provider,e.headers,h);if(!I||!I.repository||!/^[a-f0-9]{7,64}$/i.test(I.commitSha))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:o,event:lh(r.provider,e.headers),signatureStatus:"verified",status:"rejected",error:"Unsupported or malformed source event"}),Ts();let R=e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:o,event:I.event,action:I.action,commitSha:I.commitSha,signatureStatus:"verified",status:"accepted",payloadSummary:{repository:I.repository,ref:I.ref??null,branch:I.branch??null,tag:I.tag??null,commitSha:I.commitSha,pullRequestNumber:I.pullRequestNumber??null,changedPathCount:I.changedPaths.length}});if(R.duplicate&&R.delivery.status!=="accepted")return{accepted:!0,duplicate:!0,status:"duplicate",operations:[],message:"Delivery already processed"};let A=new Me(e.controlPlane),E=e.sources.listBindings({connectionId:r.id,status:"active"}).filter((z)=>{if(z.repositoryFullName.toLowerCase()!==I.repository.toLowerCase()||!Ck(z,I.changedPaths))return!1;let H=z.resourceId?A.getDefinitionForResource(z.resourceId):void 0,K=I.event==="push"&&!!H?.branchRule&&!!I.branch&&ba(I.branch,H.branchRule);return Ak(z,I)||K});if(!E.length)return e.sources.updateDelivery(R.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:R.duplicate,status:"ignored",operations:[],message:"Verified event did not match an active deployment rule"};let x=new c(e.controlPlane),N=new Set(["closed","merged","declined"]),F=E.flatMap((z)=>{if(I.event==="push"&&z.resourceId&&I.branch){let K=A.getDefinitionForResource(z.resourceId);if(K?.branchRule&&ba(I.branch,K.branchRule)){let X=A.findForBranch(K.id,I.repository,I.branch);if(I.deleted){if(!K.cleanupOnClose||!X||X.status==="destroyed")return[];let fe=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${X.id}:branch-delete:${o}`,correlationId:`preview:${X.id}`,input:{previewId:X.id,reason:"branch_deleted",source:{repository:I.repository,commitSha:I.commitSha,branch:I.branch}},lockKey:`preview:${X.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(X.id,"queued",{operationId:fe.id}),[fe]}let oe=A.upsert({definitionId:K.id,sourceProvider:r.provider,repository:I.repository,branch:I.branch,commitSha:I.commitSha});if(!oe.changed)return[];let ye=oe.created?"preview.create":"preview.update",ne=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:ye,idempotencyKey:`preview:${oe.preview.id}:${I.commitSha}`,correlationId:`preview:${oe.preview.id}`,input:{previewId:oe.preview.id,source:{connectionId:r.id,bindingId:z.id,repository:I.repository,commitSha:I.commitSha,branch:I.branch,monorepoRoot:z.monorepoRoot,submodules:z.submodules,cloneDepth:z.cloneDepth??null}},lockKey:`preview:${oe.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(oe.preview.id,"queued",{operationId:ne.id}),[ne]}}if(I.event==="pull_request"&&z.resourceId&&I.pullRequestNumber){let K=A.getDefinitionForResource(z.resourceId);if(K){let X=N.has(String(I.action??"").toLowerCase()),oe=A.findForPullRequest(K.id,I.repository,I.pullRequestNumber);if(X){if(!K.cleanupOnClose||!oe||oe.status==="destroyed")return[];let ye=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${oe.id}:destroy:${o}`,correlationId:`preview:${oe.id}`,input:{previewId:oe.id,reason:"pull_request_closed",source:{repository:I.repository,commitSha:I.commitSha,branch:I.branch??null,pullRequestNumber:I.pullRequestNumber}},lockKey:`preview:${oe.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(oe.id,"queued",{operationId:ye.id}),[ye]}try{let ye=A.upsert({definitionId:K.id,sourceProvider:r.provider,repository:I.repository,branch:I.branch??`pr-${I.pullRequestNumber}`,pullRequestNumber:I.pullRequestNumber,fork:I.fork,commitSha:I.commitSha});if(!ye.changed)return[];let ne=ye.created?"preview.create":"preview.update",fe=x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:ne,idempotencyKey:`preview:${ye.preview.id}:${I.commitSha}`,correlationId:`preview:${ye.preview.id}`,input:{previewId:ye.preview.id,source:{connectionId:r.id,bindingId:z.id,repository:I.repository,commitSha:I.commitSha,branch:I.branch??null,pullRequestNumber:I.pullRequestNumber,fork:!!I.fork,monorepoRoot:z.monorepoRoot,submodules:z.submodules,cloneDepth:z.cloneDepth??null},inheritedSecretNames:ye.inheritedSecrets},lockKey:`preview:${ye.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return A.transition(ye.preview.id,"queued",{operationId:fe.id}),[fe]}catch(ye){return e.controlPlane.appendEvent({projectId:z.projectId,resourceId:z.resourceId,type:"preview.rejected",level:"warning",payload:{repository:I.repository,pullRequestNumber:I.pullRequestNumber,fork:!!I.fork,reason:ye instanceof Error?ye.message:String(ye)}}),[]}}}let H=I.event==="pull_request"?"deploy.preview":"deploy.source";return[x.enqueue({projectId:z.projectId,environmentId:z.environmentId,resourceId:z.resourceId,kind:H,idempotencyKey:`source:${r.id}:${o}:${z.id}:${I.commitSha}`,correlationId:`source:${o}`,input:{source:{connectionId:r.id,bindingId:z.id,repository:I.repository,commitSha:I.commitSha,branch:I.branch??null,tag:I.tag??null,monorepoRoot:z.monorepoRoot,submodules:z.submodules,cloneDepth:z.cloneDepth??null},preview:I.event==="pull_request"?{number:I.pullRequestNumber??null,action:I.action??null}:null},lockKey:z.resourceId?`resource:${z.resourceId}`:`environment:${z.environmentId??z.projectId}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:I.event==="pull_request"?14:90}).operation]});if(!F.length)return e.sources.updateDelivery(R.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:R.duplicate,status:"ignored",operations:[],message:"Verified event required no preview lifecycle change"};return e.sources.updateDelivery(R.delivery.id,{status:"enqueued",operationId:F[0]?.id}),e.controlPlane.appendEvent({organizationId:r.organizationId,projectId:E[0]?.projectId,operationId:F[0]?.id,type:"source.webhook.enqueued",payload:{webhookId:t.id,deliveryId:R.delivery.id,repository:I.repository,commitSha:I.commitSha,operationIds:F.map((z)=>z.id)}}),{accepted:!0,duplicate:R.duplicate,status:"enqueued",operations:F,message:`${F.length} deployment operation${F.length===1?"":"s"} enqueued`}}function Vt(e,t){if(!t.endpointToken)throw Error("The webhook endpoint token is only available at creation time");let r=new URL(e);if(r.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(r.hostname))throw Error("Webhook base URL must use HTTPS");return new URL(`/api/source/webhooks/${encodeURIComponent(t.endpointToken)}`,r).href}import{chmodSync as uh,mkdtempSync as Pk,rmSync as _k,writeFileSync as ph}from"node:fs";import{tmpdir as Tk}from"node:os";import{join as Uc,resolve as xk}from"node:path";function gh(e,t){let r=e.trim();if(/\r|\n|\0/.test(r))throw Error("Git remote contains control characters");if(r.startsWith("https://")){let m=new URL(r);if(m.username||m.password||m.search||m.hash)throw Error("HTTPS Git remotes cannot contain credentials, queries, or fragments");return m.href}let o=r.startsWith("ssh://")?new URL(r).hostname:r.match(/^git@([A-Za-z0-9.-]+):/)?.[1];if(!o)throw Error("Git remote must use credential-free HTTPS or SSH");if(!t||t.host.toLowerCase()!==o.toLowerCase())throw Error("SSH Git remote requires a deploy key with a pinned key for the same host");return r}function Dk(e,t,r){let o=e.replaceAll(t,"[REMOTE]").slice(0,4000);for(let m of[r?.token,r?.privateKey])if(m)o=o.replaceAll(m,"[REDACTED]");return o}function Ok(e){let t={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_NOSYSTEM:"1",GIT_OPTIONAL_LOCKS:"0"},r;if(e.credential?.token){let o=e.credential.username??"oauth2";t.GIT_CONFIG_COUNT="1",t.GIT_CONFIG_KEY_0="http.extraHeader",t.GIT_CONFIG_VALUE_0=`Authorization: Basic ${Buffer.from(`${o}:${e.credential.token}`).toString("base64")}`}if(e.deployKey){r=Pk(Uc(Tk(),"ts-cloud-git-transport-"));let o=Uc(r,"key"),m=Uc(r,"known_hosts");ph(o,e.deployKey.privateKey,{mode:384}),ph(m,`${e.deployKey.host} ${e.deployKey.hostKey}
46
46
  `,{mode:384}),uh(o,384),uh(m,384),t.GIT_SSH_COMMAND=`ssh -i ${o} -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=${m} -o GlobalKnownHostsFile=/dev/null -o BatchMode=yes`}return{env:t,cleanup:()=>{if(r)_k(r,{recursive:!0,force:!0})}}}async function xs(e,t,r){let o=Ok(r),m=Bun.spawn([r.executable??"git",...e],{stdout:"pipe",stderr:"pipe",env:o.env}),h=Math.max(100,r.timeoutMs??120000),I,R=new Promise((A,E)=>{I=setTimeout(()=>{m.kill(),E(Error(`Git operation exceeded ${h}ms`))},h)});try{let A=Promise.all([m.exited,new Response(m.stdout).text(),new Response(m.stderr).text()]),[E,x,N]=await Promise.race([A,R]);if(E!==0)throw Error(Dk(N||`Git exited with ${E}`,t,r.credential));return x}finally{if(I)clearTimeout(I);o.cleanup()}}function mh(e,t){let r=new Map;for(let o of e.split(`
47
- `)){let m=o.trim().match(/^([a-f0-9]{40,64})\s+(.+)$/i);if(!m||!m[2].startsWith(t)||m[2].endsWith("^{}"))continue;let h=m[2].slice(t.length);r.set(h,{name:h,commitSha:m[1]})}return[...r.values()].sort((o,m)=>o.name.localeCompare(m.name))}async function yo(e,t={}){let r=gh(e,t.deployKey),o=await xs(["ls-remote","--heads","--tags","--",r],r,t);return{branches:mh(o,"refs/heads/"),tags:mh(o,"refs/tags/")}}async function Io(e,t={}){let r=gh(e.remote,t.deployKey),o=xk(e.destination),m=e.ref?.trim()||e.binding.defaultBranch;if(!/^[A-Za-z0-9._/-]{1,255}$/.test(m)||m.startsWith("-")||m.includes(".."))throw Error("Git ref contains unsupported characters");let h=["clone","--no-tags","--single-branch","--branch",m],I=[...new Set(e.sparsePaths??[])];if(I.some((A)=>!A||A.startsWith("/")||A.split("/").includes("..")||/[\0\r\n]/.test(A)))throw Error("Sparse checkout paths must stay inside the repository");if(I.length)h.push("--filter=blob:none","--no-checkout");if(e.binding.cloneDepth)h.push("--depth",String(e.binding.cloneDepth));if(e.binding.submodules)h.push("--recurse-submodules","--shallow-submodules");if(h.push("--",r,o),await xs(h,r,t),I.length)await xs(["-C",o,"sparse-checkout","set","--cone","--",...I],r,t),await xs(["-C",o,"checkout","--force"],r,t);if(e.commitSha){if(!/^[a-f0-9]{40,64}$/i.test(e.commitSha))throw Error("Expected source commit must be an immutable 40-64 character SHA");await xs(["-C",o,"fetch","--no-tags","--depth","1","origin",e.commitSha],r,t),await xs(["-C",o,"checkout","--detach","--force",e.commitSha],r,t)}let R=(await xs(["-C",o,"rev-parse","HEAD"],r,t)).trim();if(!/^[a-f0-9]{40,64}$/i.test(R))throw Error("Git clone did not produce a valid commit SHA");if(e.commitSha&&R.toLowerCase()!==e.commitSha.toLowerCase())throw Error(`Git checkout resolved ${R} instead of the requested immutable commit`);return{directory:e.binding.monorepoRoot==="."?o:Uc(o,e.binding.monorepoRoot),commitSha:R}}function oc(e){return["github","gitlab","bitbucket","gitea"].includes(e)}async function So(e,t,r){let o=e.getConnection(t);if(!o||["disconnected","expired"].includes(o.status))throw Error("Active source connection was not found");try{if(oc(o.provider)){let I=await Ve(o,e.getCredential(o.id)).testConnection();return e.updateHealth(o.id,{status:I.ok?"healthy":"degraded",message:I.message,tested:!0,grantedScopes:I.scopes})}let m=r?e.getRepository(r):e.listRepositories(o.id,void 0,1)[0];if(!m)return e.updateHealth(o.id,{status:"degraded",message:"Add a repository URL before testing this generic connection.",tested:!0});let h=o.provider==="generic_ssh"?e.listBindings({connectionId:o.id}).map((I)=>I.deployKeyId).filter(Boolean).map((I)=>e.getDeployKey(I)).find(Boolean):void 0;return await yo(m.cloneUrl,{credential:e.getCredential(o.id),deployKey:h?{...h,privateKey:e.getDeployPrivateKey(h.id)}:void 0}),e.updateHealth(o.id,{status:"healthy",message:"Git repository access is healthy.",tested:!0})}catch(m){return e.updateHealth(o.id,{status:"degraded",message:m instanceof Error?m.message:"Connection test failed",tested:!0})}}async function Ti(e,t,r={}){let o=e.getConnection(t);if(!o||!oc(o.provider)||["disconnected","expired"].includes(o.status))throw Error("A hosted active source connection is required for repository discovery");let m=Ve(o,e.getCredential(o.id)),h=[],I;for(let R=0;R<Math.min(20,Math.max(1,r.maxPages??10));R++){let A=await m.listRepositories({cursor:I,search:r.search,limit:100});for(let E of A.repositories)h.push(e.upsertRepository({connectionId:o.id,...E}));if(I=A.nextCursor,!I)break}return e.updateHealth(o.id,{status:"healthy",message:`${h.length} repositories synchronized.`,synced:!0}),h}async function wi(e,t){let r=e.getConnection(t.connectionId);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active source connection was not found");if(oc(r.provider)){let R=Ve(r,e.getCredential(r.id));return t.type==="tags"?R.listTags(t.repository,t):R.listBranches(t.repository,t)}let o=t.repositoryId?e.getRepository(t.repositoryId):e.listRepositories(r.id).find((R)=>R.fullName===t.repository);if(!o||o.connectionId!==r.id)throw Error("Generic repository metadata was not found");let m=t.deployKeyId?e.getDeployKey(t.deployKeyId):void 0;if(m&&m.connectionId!==r.id)throw Error("Deploy key does not belong to this connection");let h=await yo(o.cloneUrl,{credential:e.getCredential(r.id),deployKey:m?{...m,privateKey:e.getDeployPrivateKey(m.id)}:void 0});return{refs:(t.type==="tags"?h.tags:h.branches).slice(0,Math.min(500,t.limit??100))}}async function Mr(e,t,r){let o=e.getWebhook(t),m=o?e.getConnection(o.connectionId):void 0;if(!o||!m||["disconnected","expired"].includes(m.status))throw Error("Active source webhook was not found");let h=Vt(r,{...o,endpointToken:e.getWebhookEndpointToken(o.id)});if(!oc(m.provider))return e.updateWebhookState(o.id,{status:"healthy",healthMessage:"Manual webhook endpoint is ready.",reconciled:!0});try{let I=Ve(m,e.getCredential(m.id)),R=e.getWebhookSecret(o.id),A=o.providerWebhookId?await I.updateWebhook(o.repositoryFullName,o.providerWebhookId,{url:h,secret:R,events:o.events}):await I.createWebhook(o.repositoryFullName,{url:h,secret:R,events:o.events});return e.updateWebhookState(o.id,{providerWebhookId:A.providerWebhookId,status:A.active?"healthy":"degraded",healthMessage:A.active?"Provider webhook is synchronized.":"Provider webhook exists but is inactive.",reconciled:!0})}catch(I){return e.updateWebhookState(o.id,{status:"degraded",healthMessage:I instanceof Error?I.message:"Webhook reconciliation failed",reconciled:!0})}}async function Vd(e,t){let r=e.getWebhook(t),o=r?e.getConnection(r.connectionId):void 0;if(!r||!o)throw Error("Source webhook was not found");if(oc(o.provider)&&r.providerWebhookId&&!["disconnected","expired"].includes(o.status))await Ve(o,e.getCredential(o.id)).deleteWebhook(r.repositoryFullName,r.providerWebhookId);return e.updateWebhookState(r.id,{status:"disabled",healthMessage:"Webhook disabled."})}var Ri="1.6.0";function Co(){let e={type:"object",required:["error"],properties:{error:{type:"object",required:["code","message","requestId"],properties:{code:{type:"string"},message:{type:"string"},requestId:{type:"string",format:"uuid"},details:{}}}}},t=(o)=>({type:"object",required:["data","page","requestId"],properties:{data:{type:"array",items:o},page:{type:"object",required:["hasMore"],properties:{nextCursor:{type:"string"},hasMore:{type:"boolean"}}},requestId:{type:"string",format:"uuid"}}}),r=(o)=>({"200":{description:"A stable cursor page.",content:{"application/json":{schema:t(o)}}},default:{$ref:"#/components/responses/Error"}});return{openapi:"3.1.0",info:{title:"ts-cloud API",version:Ri,description:"Additive changes are released within v1. Breaking request or response changes require a new URL version."},servers:[{url:"/"}],security:[{bearerAuth:[]}],paths:{...Us(),"/api/v1/projects":{get:{operationId:"listProjects",summary:"List accessible projects",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Project"})}},"/api/v1/projects/{projectId}/environments":{get:{operationId:"listEnvironments",summary:"List accessible project environments",parameters:[{$ref:"#/components/parameters/ProjectId"},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Environment"})}},"/api/v1/services":{get:{operationId:"listServices",summary:"List accessible services",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{name:"environmentId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Service"})}},"/api/v1/source/connections":{get:{operationId:"listSourceConnections",summary:"List safe Git connection metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceConnection"})},post:{operationId:"createSourceConnection",summary:"Create an encrypted Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["provider","name","host"],properties:{provider:{type:"string",enum:["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"]},name:{type:"string"},host:{type:"string",format:"uri"},token:{type:"string",writeOnly:!0},repositoryFullName:{type:"string"},repositoryUrl:{type:"string"}}}}}},responses:{"201":{description:"Encrypted connection created."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectSourceConnection",summary:"Preview or safely disconnect a Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["id"],properties:{id:{type:"string"},preview:{type:"boolean"}}}}}},responses:{"200":{description:"Impact preview or disconnected connection."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/repositories":{get:{operationId:"listSourceRepositories",summary:"List or synchronize granted repositories",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"sync",in:"query",schema:{type:"boolean"}},{name:"search",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceRepository"})}},"/api/v1/source/refs":{get:{operationId:"listSourceRefs",summary:"List repository branches or tags",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"repository",in:"query",required:!0,schema:{type:"string"}},{name:"repositoryId",in:"query",schema:{type:"string"}},{name:"type",in:"query",schema:{type:"string",enum:["branches","tags"]}}],responses:{"200":{description:"Provider reference page."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/bindings":{post:{operationId:"createSourceBinding",summary:"Bind a repository to an application",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/SourceBindingRequest"}}}},responses:{"201":{description:"Source binding created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/webhooks":{post:{operationId:"createSourceWebhook",summary:"Create and optionally reconcile a signed webhook",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["connectionId","repositoryFullName","baseUrl"],properties:{connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},baseUrl:{type:"string",format:"uri"},events:{type:"array",items:{type:"string",enum:["push","pull_request"]}},reconcile:{type:"boolean"}}}}}},responses:{"201":{description:"Webhook endpoint created; endpoint is revealed once."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-detections":{post:{operationId:"detectApplication",summary:"Detect bounded application build candidates",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["files"],properties:{files:{type:"array",maxItems:1e4,items:{$ref:"#/components/schemas/DetectionFile"}}}}}}},responses:{"200":{description:"Ranked detection candidates with evidence."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-plans":{post:{operationId:"planApplication",summary:"Validate and normalize an application manifest",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["draft"],properties:{draft:{$ref:"#/components/schemas/ApplicationInput"},suppliedSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}}}}}},responses:{"200":{description:"Validated plan, config patch, capabilities, costs, and missing secret names."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-drafts":{get:{operationId:"listApplicationDrafts",summary:"List resumable secret-free drafts",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/ApplicationDraft"})},post:{operationId:"createApplicationDraft",summary:"Create a resumable application draft",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/ApplicationDraftCreateRequest"}}}},responses:{"201":{description:"Draft created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateApplicationDraft",summary:"Optimistically update a draft",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/ApplicationDraftCreateRequest"},{type:"object",required:["id","version","step"],properties:{id:{type:"string"},version:{type:"integer",minimum:1}}}]}}}},responses:{"200":{description:"Updated draft."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/applications":{post:{operationId:"createApplication",summary:"Confirm and queue an application plan",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["draftId","version","confirmEnvironment"],properties:{draftId:{type:"string"},version:{type:"integer",minimum:1},confirmEnvironment:{type:"string",description:"Exact target environment slug."}}}}}},responses:{"202":{description:"Application operation queued; identical requests replay safely."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-artifacts":{post:{operationId:"uploadApplicationArtifact",summary:"Inspect and store a bounded ZIP or TAR source artifact",parameters:[{name:"X-Project-Id",in:"header",required:!0,schema:{type:"string"}},{name:"X-Artifact-Filename",in:"header",required:!0,schema:{type:"string"}}],requestBody:{required:!0,content:{"application/octet-stream":{schema:{type:"string",format:"binary",maxLength:104857600}}}},responses:{"201":{description:"Deduplicated artifact metadata; archive contents are never executed."},"413":{$ref:"#/components/responses/Error"},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/registry-connections":{get:{operationId:"listRegistryConnections",summary:"List safe private-registry metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/RegistryConnection"})},post:{operationId:"createRegistryConnection",summary:"Create an encrypted private-registry connection",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/RegistryConnectionRequest"}}}},responses:{"201":{description:"Encrypted registry connection created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateRegistryConnection",summary:"Test access or rotate write-only credentials",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/RegistryConnectionRequest"},{type:"object",required:["id","action"],properties:{id:{type:"string"},action:{type:"string",enum:["test","rotate"]},image:{type:"string"}}}]}}}},responses:{"200":{description:"Safe connection health metadata."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectRegistryConnection",summary:"Disconnect and erase registry credentials",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["id"],properties:{id:{type:"string"}}}}}},responses:{"200":{description:"Credentials erased and connection disconnected."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue":{get:{operationId:"listQueue",summary:"List authorized durable operations and blocking metadata",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"state",in:"query",schema:{type:"string",enum:["queued","running","succeeded","failed","cancelled","timed_out"]}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/QueueOperation"})}},"/api/v1/preview-definitions":{get:{operationId:"listPreviewDefinitions",summary:"List preview policies",responses:r({type:"object"})},post:{operationId:"createPreviewDefinition",summary:"Configure bounded preview policy",responses:{"200":{description:"Preview definition created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews":{get:{operationId:"listPreviews",summary:"List authorized persistent previews",responses:r({type:"object"})},post:{operationId:"createPreview",summary:"Create or update one immutable preview identity",responses:{"200":{description:"Preview deployment queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/destroy":{post:{operationId:"destroyPreview",summary:"Confirm tagged preview teardown",responses:{"200":{description:"Teardown queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/extend":{post:{operationId:"extendPreview",summary:"Extend preview TTL",responses:{"200":{description:"Expiry extended."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/rebuild":{post:{operationId:"rebuildPreview",summary:"Rebuild the exact recorded commit",responses:{"200":{description:"Rebuild queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/cleanup":{post:{operationId:"cleanupPreviews",summary:"Dry-run or queue TTL/keep-count teardown",responses:{"200":{description:"Cleanup plan or operations."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-templates":{get:{operationId:"listComposeTemplates",summary:"List pinned verified application templates",responses:r({type:"object"})}},"/api/v1/compose-applications":{get:{operationId:"listComposeApplications",summary:"List authorized multi-service applications",responses:r({type:"object"})},post:{operationId:"createComposeApplication",summary:"Import Compose or materialize a template",responses:{"200":{description:"Editable normalized application."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/preview":{post:{operationId:"previewComposeApplication",summary:"Parse and diagnose Compose without mutation",responses:{"200":{description:"Normalized preview and actionable diagnostics."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/services":{get:{operationId:"listComposeServices",summary:"Inspect per-service desired and observed state",responses:{"200":{description:"Service topology and status."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/{action}":{post:{operationId:"operateComposeApplication",summary:"Deploy, redeploy, start, stop, scale, or delete through the durable queue",responses:{"200":{description:"Scoped operation queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/release-artifacts":{post:{operationId:"createReleaseArtifact",summary:"Register a verified content-addressed artifact",responses:{"200":{description:"Artifact identity registered."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases":{get:{operationId:"listReleases",summary:"List unified authorized release history",responses:r({type:"object"})},post:{operationId:"createRelease",summary:"Create an immutable release from an existing artifact",responses:{"200":{description:"Release record created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/capabilities":{get:{operationId:"getReleaseCapabilities",summary:"Explain supported strategies, capacity, cost, and rollback",responses:{"200":{description:"Provider-aware strategy capabilities."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}":{get:{operationId:"getRelease",summary:"Inspect provenance, approvals, health, and transitions",responses:{"200":{description:"Release detail."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}/{action}":{post:{operationId:"operateRelease",summary:"Promote, approve, activate, roll back, report health, or pin",responses:{"200":{description:"Release lifecycle updated."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/settings":{get:{operationId:"getQueueSettings",summary:"Get effective concurrency limits",responses:{"200":{description:"Queue concurrency settings."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateQueueSettings",summary:"Confirm and audit production concurrency changes",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm","concurrency"],properties:{confirm:{const:"update queue limits"},concurrency:{$ref:"#/components/schemas/QueueConcurrency"}}}}}},responses:{"200":{description:"Updated effective limits."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/history":{delete:{operationId:"clearQueueHistory",summary:"Clear terminal jobs whose retention has elapsed",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm"],properties:{confirm:{const:"clear completed"},before:{type:"string",format:"date-time"},projectId:{type:"string"}}}}}},responses:{"200":{description:"Eligible history cleared with an audit event."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs":{get:{operationId:"listOperationLogs",summary:"Resume ordered sanitized operation logs from a cursor",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:{"200":{description:"Ordered log chunks and next cursor."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs/stream":{get:{operationId:"streamOperationLogs",summary:"Stream authorized operation logs with Last-Event-ID resume",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"Last-Event-ID",in:"header",schema:{type:"integer",minimum:0}}],responses:{"200":{description:"Server-sent log and completion events.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/cancel":{post:{operationId:"cancelOperation",summary:"Cancel queued work or request cooperative running cancellation",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{content:{"application/json":{schema:{type:"object"}}}},responses:{"200":{description:"Cancellation state recorded."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/retry":{post:{operationId:"retryOperation",summary:"Retry an allow-listed failure class within the attempt limit",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["errorClass"],properties:{errorClass:{type:"string"},delayMs:{type:"integer",minimum:0}}}}}},responses:{"200":{description:"Retry queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/deployments":{post:{operationId:"createDeployment",summary:"Queue a deployment",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/DeploymentRequest"}}}},responses:{"202":{description:"Queued operation.",content:{"application/json":{schema:{$ref:"#/components/schemas/OperationResponse"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations":{get:{operationId:"listOperations",summary:"List scoped operations",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Operation"})}},"/api/v1/events":{get:{operationId:"listEvents",summary:"List scoped audit events",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:r({$ref:"#/components/schemas/Event"})}},"/api/v1/events/stream":{get:{operationId:"streamEvents",summary:"Stream scoped audit events",responses:{"200":{description:"Authenticated server-sent event stream.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/openapi.json":{get:{operationId:"getOpenApi",summary:"Get the OpenAPI contract",security:[],responses:{"200":{description:"OpenAPI 3.1 contract."}}}}},components:{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer",bearerFormat:"tsc_v1"}},parameters:{Limit:{name:"limit",in:"query",schema:{type:"integer",minimum:1,maximum:100,default:50}},Cursor:{name:"cursor",in:"query",schema:{type:"string"}},ProjectId:{name:"projectId",in:"path",required:!0,schema:{type:"string"}},OperationId:{name:"operationId",in:"path",required:!0,schema:{type:"string"}}},responses:{Error:{description:"Stable error envelope.",content:{"application/json":{schema:e}}}},schemas:{Project:{type:"object",required:["id","slug","name"],properties:{id:{type:"string"},slug:{type:"string"},name:{type:"string"},description:{type:"string"}}},Environment:{type:"object",required:["id","projectId","slug","name","kind"],properties:{id:{type:"string"},projectId:{type:"string"},slug:{type:"string"},name:{type:"string"},kind:{type:"string"},region:{type:"string"}}},Service:{type:"object",required:["id","projectId","kind","slug","name"],properties:{id:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},kind:{type:"string"},slug:{type:"string"},name:{type:"string"},metadata:{type:"object",additionalProperties:!0}}},SourceConnection:{type:"object",required:["id","provider","name","host","status","credentialConfigured"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},status:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},grantedScopes:{type:"array",items:{type:"string"}}}},SourceRepository:{type:"object",required:["id","connectionId","fullName","cloneUrl","defaultBranch"],properties:{id:{type:"string"},connectionId:{type:"string"},fullName:{type:"string"},cloneUrl:{type:"string"},defaultBranch:{type:"string"},visibility:{type:"string"},archived:{type:"boolean"}}},SourceBindingRequest:{type:"object",additionalProperties:!1,required:["projectId","connectionId","repositoryFullName"],properties:{projectId:{type:"string"},environmentId:{type:"string"},resourceId:{type:"string"},connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},defaultBranch:{type:"string"},branchRule:{type:"string"},tagRule:{type:"string"},monorepoRoot:{type:"string"},includePaths:{type:"array",items:{type:"string"}},excludePaths:{type:"array",items:{type:"string"}},submodules:{type:"boolean"},cloneDepth:{type:"integer",minimum:1},deployKeyId:{type:"string"},autoDeploy:{type:"boolean"},pullRequestPreviews:{type:"boolean"}}},DetectionFile:{type:"object",additionalProperties:!1,required:["path"],properties:{path:{type:"string"},size:{type:"integer",minimum:0},content:{type:"string",maxLength:262144}}},ApplicationInput:{type:"object",additionalProperties:!1,required:["schemaVersion","name","slug","projectId","environmentId","source","build","runtime"],properties:{schemaVersion:{const:1},name:{type:"string"},slug:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},source:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["git","local","artifact","image"]}},additionalProperties:!0},build:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["dockerfile","buildpack","static","server","serverless","prebuilt_image"]},secretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}},additionalProperties:!0},runtime:{type:"object",required:["architecture","target"],properties:{architecture:{type:"string",enum:["x86_64","arm64"]},target:{type:"string",enum:["server","serverless","container"]},port:{type:"integer",minimum:1,maximum:65535},healthCheck:{type:"object",additionalProperties:!0}},additionalProperties:!0},environment:{type:"object",additionalProperties:{oneOf:[{type:"string"},{type:"object",additionalProperties:!1,required:["secretRef"],properties:{secretRef:{type:"string"}}}]}},requiredSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}},domain:{type:"object",properties:{hostname:{type:"string"},path:{type:"string"},tls:{type:"boolean"}}}}},ApplicationDraftCreateRequest:{type:"object",additionalProperties:!1,required:["projectId","draft"],properties:{projectId:{type:"string"},name:{type:"string"},draft:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string",enum:["source","build","runtime","environment","domain","review"]},suppliedSecretNames:{type:"array",uniqueItems:!0,description:"Names only; values must use the secrets boundary.",items:{type:"string"}}}},ApplicationDraft:{type:"object",required:["id","projectId","input","step","status","version"],properties:{id:{type:"string"},projectId:{type:"string"},input:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string"},suppliedSecretNames:{type:"array",items:{type:"string"}},status:{type:"string",enum:["draft","ready","applied"]},version:{type:"integer"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"}}},RegistryConnectionRequest:{type:"object",properties:{provider:{type:"string",enum:["docker_hub","ghcr","ecr","gcr","generic"]},name:{type:"string"},host:{type:"string"},username:{type:"string",writeOnly:!0},password:{type:"string",writeOnly:!0},token:{type:"string",writeOnly:!0},credentialExpiresAt:{type:"string",format:"date-time"},expiresAt:{type:"string",format:"date-time"}}},RegistryConnection:{type:"object",required:["id","provider","name","host","credentialConfigured","status","version"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},credentialExpiresAt:{type:"string",format:"date-time"},status:{type:"string",enum:["pending","healthy","degraded","expired","disconnected"]},healthMessage:{type:"string"},lastTestedAt:{type:"string",format:"date-time"},version:{type:"integer"}}},QueueConcurrency:{type:"object",additionalProperties:!1,properties:{project:{type:"integer",minimum:1,maximum:100},environment:{type:"integer",minimum:1,maximum:100},provider:{type:"integer",minimum:1,maximum:100},builds:{type:"integer",minimum:1,maximum:100}}},QueueOperation:{allOf:[{$ref:"#/components/schemas/Operation"},{type:"object",required:["queue"],properties:{queue:{type:"object",required:["maxAttempts","availableAt","timeoutSeconds","retryClasses","resumePolicy","cancellationMode","retentionUntil"],properties:{lockKey:{type:"string"},providerKey:{type:"string"},buildSlot:{type:"boolean"},maxAttempts:{type:"integer"},availableAt:{type:"string",format:"date-time"},timeoutSeconds:{type:"integer"},heartbeatAt:{type:"string",format:"date-time"},currentStep:{type:"string"},blockedReason:{type:"string"},retryClasses:{type:"array",items:{type:"string"}},resumePolicy:{type:"string",enum:["fail","requeue"]},cancellationMode:{type:"string",enum:["cooperative","provider_non_cancellable"]},retentionUntil:{type:"string",format:"date-time"}}},approximatePosition:{type:"object",properties:{ahead:{type:"integer"},precision:{const:"bounded"}}}}}]},DeploymentRequest:{type:"object",additionalProperties:!1,required:["projectId","environmentId"],properties:{projectId:{type:"string"},environmentId:{type:"string"},serviceId:{type:"string"},action:{type:"string",enum:["deploy","rollback"],default:"deploy"},revision:{type:"string"}}},Operation:{type:"object",required:["id","state","kind","correlationId","createdAt"],properties:{id:{type:"string"},state:{type:"string"},kind:{type:"string"},correlationId:{type:"string"},createdAt:{type:"string",format:"date-time"}}},OperationResponse:{type:"object",required:["operation","idempotentReplay","requestId"],properties:{operation:{$ref:"#/components/schemas/Operation"},idempotentReplay:{type:"boolean"},requestId:{type:"string",format:"uuid"}}},Event:{type:"object",required:["id","sequence","type","level","correlationId","createdAt"],properties:{id:{type:"string"},sequence:{type:"integer"},type:{type:"string"},level:{type:"string"},correlationId:{type:"string"},payload:{},createdAt:{type:"string",format:"date-time"}}}}}}}function Nk(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}function jk(e){if(!e)return;try{let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return t&&typeof t==="object"&&!Array.isArray(t)?t:void 0}catch{return}}function yn(e,t,r,o=["createdAt","id"]){let m=Math.min(100,Math.max(1,Number(t.searchParams.get("limit"))||50)),h=jk(t.searchParams.get("cursor"));if(t.searchParams.has("cursor")&&!h)throw new i("invalid_cursor","The pagination cursor is invalid.",400);let I=0;if(h){let x=e.findIndex((N)=>o.every((F)=>N[F]===h[F]));if(x<0)throw new i("invalid_cursor","The pagination cursor is no longer available.",400);I=x+1}let R=e.slice(I,I+m),A=I+m<e.length,E=R.at(-1);return{data:R,page:{hasMore:A,nextCursor:A&&E?Nk(Object.fromEntries(o.map((x)=>[x,E[x]]))):void 0},requestId:r}}function bo(e){let t=new di(e.controlPlane,e.identities),r=new c(e.controlPlane),o=new Ir(e.controlPlane),m=new Cr(e.controlPlane),h=new lt(e.controlPlane),I=e.spend?.store??new ei(e.controlPlane,{now:e.now}),R={store:I,service:e.spend?.service??new Lt(I)},A=new Map,E=e.now??(()=>new Date),x=e.rateLimit??120,N=(z,H,K,X={})=>new Response(JSON.stringify(z),{status:H,headers:{"content-type":"application/json; charset=utf-8","cache-control":"no-store","x-request-id":K,"x-api-version":Ri,...X}}),F=(z,H,K,X,oe,ye)=>N({error:{code:z,message:H,requestId:X,details:oe}},K,X,ye);return async(z,H)=>{let K=new URL(z.url);if(!K.pathname.startsWith("/api/v1"))return;let X=crypto.randomUUID();if(K.pathname==="/api/v1/openapi.json"&&z.method==="GET")return N(Co(),200,X,{"cache-control":"public, max-age=300"});let oe=z.headers.get("authorization")??"",ye=oe.startsWith("Bearer ")?oe.slice(7).trim():"",ne=ye?e.identities.verifyToken(ye,H):void 0;if(!ne)return F("unauthorized","A valid bearer token is required.",401,X,void 0,{"www-authenticate":'Bearer realm="ts-cloud", error="invalid_token"'});let fe=A.get(ne.token.id),Ce=E().getTime(),_e=!fe||Ce-fe.start>=60000?{start:Ce,count:0}:fe;_e.count+=1,A.set(ne.token.id,_e);let he=Math.max(0,x-_e.count),Ue={"x-ratelimit-limit":String(x),"x-ratelimit-remaining":String(he),"x-ratelimit-reset":String(Math.ceil((_e.start+60000)/1000))};if(_e.count>x)return F("rate_limited","API rate limit exceeded.",429,X,void 0,{...Ue,"retry-after":String(Math.max(1,Math.ceil((_e.start+60000-Ce)/1000)))});try{let me,We=async()=>{let Y=await z.text();if(Y.length>1048576)throw new i("payload_too_large","Request body exceeds 1 MB.",413);try{return JSON.parse(Y)}catch{throw new i("invalid_json","Request body must be valid JSON.",400)}},nt=/^\/api\/v1\/projects\/([^/]+)\/environments$/.exec(K.pathname),wt=/^\/api\/v1\/operations\/([^/]+)\/logs(?:\/(stream))?$/.exec(K.pathname),cr=/^\/api\/v1\/operations\/([^/]+)\/(cancel|retry)$/.exec(K.pathname),st=/^\/api\/v1\/previews\/([^/]+)\/(destroy|extend|rebuild)$/.exec(K.pathname),Ft=/^\/api\/v1\/compose-applications\/([^/]+)\/(deploy|redeploy|start|stop|scale|delete)$/.exec(K.pathname),dr=/^\/api\/v1\/compose-applications\/([^/]+)\/services$/.exec(K.pathname),vt=/^\/api\/v1\/releases\/([^/]+)\/(promote|approve|activate|rollback|health|pin)$/.exec(K.pathname);if(z.method==="GET"&&K.pathname==="/api/v1/projects")me=yn(t.listProjects(ne),K,X);else if(z.method==="GET"&&nt)me=yn(t.listEnvironments(ne,decodeURIComponent(nt[1])),K,X);else if(z.method==="GET"&&K.pathname==="/api/v1/services"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);me=yn(t.listServices(ne,Y,K.searchParams.get("environmentId")??void 0),K,X)}else if(z.method==="GET"&&K.pathname==="/api/v1/operations")me=yn(t.listOperations(ne,K.searchParams.get("projectId")??void 0),K,X);else if(z.method==="GET"&&K.pathname==="/api/v1/previews"){let Y=K.searchParams.get("projectId")??void 0,be=o.previews.listInstances({projectId:Y}).filter((Ee)=>{try{return t.authorize(ne,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee}));me=yn(be,K,X)}else if(z.method==="GET"&&K.pathname==="/api/v1/compose-templates")me=yn(yr().map((Y)=>({...Y})),K,X,["id","version"]);else if(z.method==="GET"&&K.pathname==="/api/v1/releases/capabilities"){let Y=String(K.searchParams.get("kind")??"");me={capabilities:$r({kind:Y,hasHealthGate:K.searchParams.get("health")==="true",replicas:Number(K.searchParams.get("replicas"))||1}),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/releases"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);t.authorize(ne,"project:read",{type:"project",id:Y});let be=h.releases.list({projectId:Y,environmentId:K.searchParams.get("environmentId")??void 0,resourceId:K.searchParams.get("resourceId")??void 0}).filter((Ee)=>{try{return t.authorize(ne,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,artifact:h.releases.getArtifact(Ee.artifactId),transitions:h.releases.transitions(Ee.id),approvals:h.releases.approvals(Ee.id)}));me=yn(be,K,X)}else if(z.method==="POST"&&K.pathname==="/api/v1/release-artifacts"){let Y=await We();t.authorize(ne,"applications:manage",{type:"organization"}),me={artifact:h.releases.registerArtifact({organizationId:ne.serviceAccount.organizationId,digest:String(Y.digest??""),kind:String(Y.kind??""),uri:String(Y.uri??""),size:Number(Y.size),mediaType:typeof Y.mediaType==="string"?Y.mediaType:void 0,provenance:Y.provenance,attestation:Y.attestation}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/releases"){let Y=await We(),be=String(Y.resourceId??"");t.authorize(ne,"applications:manage",{type:"resource",id:be}),me={release:h.releases.create({organizationId:ne.serviceAccount.organizationId,projectId:String(Y.projectId??""),environmentId:String(Y.environmentId??""),resourceId:be,artifactId:String(Y.artifactId??""),kind:String(Y.kind??""),sourceSha:typeof Y.sourceSha==="string"?Y.sourceSha:void 0,config:Y.config??{},manifest:Y.manifest??{},provenance:Y.provenance,strategy:String(Y.strategy??"atomic"),healthGate:Y.healthGate,hooks:Y.hooks,drainSeconds:Number(Y.drainSeconds)||void 0,graceSeconds:Number(Y.graceSeconds)||void 0,automaticRollback:Y.automaticRollback!==!1,actorId:ne.actor.id,trigger:typeof Y.trigger==="string"?Y.trigger:"api",approvalRequired:Y.approvalRequired===!0,replicas:Number(Y.replicas)||void 0}),requestId:X}}else if(z.method==="GET"&&/^\/api\/v1\/releases\/[^/]+$/.test(K.pathname)){let Y=decodeURIComponent(K.pathname.split("/").at(-1)),be=h.releases.get(Y);if(!be)throw new i("not_found","Release was not found.",404);t.authorize(ne,"deployments:read",{type:"resource",id:be.resourceId}),me={release:be,artifact:h.releases.getArtifact(be.artifactId),transitions:h.releases.transitions(Y),approvals:h.releases.approvals(Y),requestId:X}}else if(z.method==="POST"&&vt){let Y=h.releases.get(decodeURIComponent(vt[1]));if(!Y)throw new i("not_found","Release was not found.",404);let be=await We(),Ee=vt[2];if(Ee==="promote"){let Be=String(be.targetResourceId??"");t.authorize(ne,"deployments:create",{type:"resource",id:Be}),me={release:h.releases.promote(Y.id,{targetEnvironmentId:String(be.targetEnvironmentId??""),targetResourceId:Be,config:be.config??{},strategy:be.strategy,healthGate:be.healthGate,actorId:ne.actor.id,approvalRequired:be.approvalRequired===!0}),requestId:X}}else if(Ee==="approve")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={release:h.releases.approve(Y.id,{actorId:ne.actor.id,decision:be.decision==="rejected"?"rejected":"approved",comment:typeof be.comment==="string"?be.comment:void 0}),requestId:X};else if(Ee==="activate")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(h.enqueueActivation(Y,{actorId:ne.actor.id})),requestId:X};else if(Ee==="rollback")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(h.enqueueRollback(Y,{actorId:ne.actor.id,targetReleaseId:typeof be.targetReleaseId==="string"?be.targetReleaseId:void 0})),requestId:X};else if(Ee==="health"){t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId});let Be=h.completeHealthGate(Y.id,{healthy:be.healthy===!0,operationId:typeof be.operationId==="string"?be.operationId:void 0,health:be.health,message:typeof be.message==="string"?be.message:void 0});me={release:Be.release,rollbackOperation:Be.rollbackOperation?t.operation(Be.rollbackOperation):void 0,requestId:X}}else t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={release:h.releases.pin(Y.id,be.pinned!==!1,typeof be.reason==="string"?be.reason:void 0),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/compose-applications"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);t.authorize(ne,"project:read",{type:"project",id:Y});let be=m.applications.list({projectId:Y,environmentId:K.searchParams.get("environmentId")??void 0}).filter((Ee)=>{try{return t.authorize(ne,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,services:m.applications.services(Ee.id)}));me=yn(be,K,X)}else if(z.method==="POST"&&K.pathname==="/api/v1/compose-applications/preview"){let Y=await We(),be=String(Y.projectId??"");t.authorize(ne,"project:read",{type:"project",id:be}),me={result:m.applications.preview(String(Y.source??""),{name:String(Y.name??""),slug:typeof Y.slug==="string"?Y.slug:void 0,projectId:be,environmentId:String(Y.environmentId??"")}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/compose-applications"){let Y=await We(),be=String(Y.projectId??"");t.authorize(ne,"applications:manage",{type:"environment",id:String(Y.environmentId??"")});let Ee={name:String(Y.name??""),slug:typeof Y.slug==="string"?Y.slug:void 0,projectId:be,environmentId:String(Y.environmentId??""),createdByActorId:ne.actor.id},Be=typeof Y.templateId==="string"?m.applications.fromTemplate(Y.templateId,Y.inputs&&typeof Y.inputs==="object"&&!Array.isArray(Y.inputs)?Y.inputs:{},{...Ee,version:typeof Y.templateVersion==="string"?Y.templateVersion:void 0}):m.applications.import(String(Y.source??""),Ee);me={application:Be.application,diagnostics:Be.parsed.diagnostics,requestId:X}}else if(z.method==="GET"&&dr){let Y=m.applications.get(decodeURIComponent(dr[1]));if(!Y)throw new i("not_found","Compose application was not found.",404);t.authorize(ne,"deployments:read",{type:"resource",id:Y.resourceId}),me={application:Y,services:m.applications.services(Y.id),requestId:X}}else if(z.method==="POST"&&Ft){let Y=m.applications.get(decodeURIComponent(Ft[1]));if(!Y)throw new i("not_found","Compose application was not found.",404);let be=Ft[2],Ee=await We();t.authorize(ne,be==="delete"||be==="stop"?"deployments:cancel":"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(m.enqueue(Y,be,{actorId:ne.actor.id,service:typeof Ee.service==="string"?Ee.service:void 0,replicas:Number.isFinite(Number(Ee.replicas))?Number(Ee.replicas):void 0,removeVolumes:Ee.removeVolumes===!0,confirmation:typeof Ee.confirm==="string"?Ee.confirm:void 0})),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/preview-definitions"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);t.authorize(ne,"project:read",{type:"project",id:Y}),me=yn(o.previews.listDefinitions(Y).map((be)=>({...be})),K,X)}else if(z.method==="POST"&&K.pathname==="/api/v1/preview-definitions"){let Y=await We();t.authorize(ne,"config:write",{type:"resource",id:String(Y.resourceId??"")}),me={definition:o.previews.createDefinition({...Y,projectId:String(Y.projectId??""),resourceId:String(Y.resourceId??""),baseEnvironmentId:String(Y.baseEnvironmentId??""),domainPattern:String(Y.domainPattern??""),createdByActorId:ne.actor.id}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/previews"){let Y=await We(),be=o.previews.getDefinition(String(Y.definitionId??""));if(!be)throw new i("not_found","Preview definition was not found.",404);t.authorize(ne,"deployments:create",{type:"resource",id:be.resourceId});let Ee=o.previews.upsert({definitionId:be.id,sourceProvider:"api",repository:typeof Y.repository==="string"?Y.repository:"api",branch:String(Y.branch??""),pullRequestNumber:Number(Y.pullRequestNumber)||void 0,fork:Y.fork===!0,commitSha:String(Y.commitSha??""),createdByActorId:ne.actor.id});me={preview:Ee.preview,operation:t.operation(o.enqueueDeploy(Ee.preview,{created:Ee.created,actorId:ne.actor.id})),requestId:X}}else if(z.method==="POST"&&st){let Y=o.previews.getInstance(decodeURIComponent(st[1]));if(!Y)throw new i("not_found","Preview was not found.",404);let be=await We(),Ee=st[2];if(Ee==="destroy"){if(t.authorize(ne,"deployments:cancel",{type:"resource",id:Y.resourceId}),be.confirm!==Y.name)throw new i("confirmation_required",`Type ${Y.name} to confirm preview teardown.`,409);me={operation:t.operation(o.enqueueDestroy(Y,"api",ne.actor.id)),requestId:X}}else if(Ee==="extend")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={preview:o.previews.extend(Y.id,Number(be.hours)),requestId:X};else t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(o.enqueueDeploy(Y,{actorId:ne.actor.id,reason:"manual_rebuild"})),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/previews/cleanup"){t.authorize(ne,"automation:manage",{type:"organization"});let Y=await We();if(!Y.dryRun&&Y.confirm!=="cleanup previews")throw new i("confirmation_required","Type cleanup previews to confirm preview cleanup.",409);me={...o.cleanup({dryRun:Y.dryRun===!0,maxAgeHours:Number(Y.maxAgeHours)||void 0,keepCount:Number(Y.keepCount)||void 0,actorId:ne.actor.id}),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/queue"){let Y=K.searchParams.get("projectId")??void 0,be=K.searchParams.get("state"),Ee=r.list({projectId:Y,state:["queued","running","succeeded","failed","cancelled","timed_out"].includes(be)?be:void 0,limit:500}).filter((Be)=>{let It=Be.operation.resourceId?{type:"resource",id:Be.operation.resourceId}:Be.operation.environmentId?{type:"environment",id:Be.operation.environmentId}:Be.operation.projectId?{type:"project",id:Be.operation.projectId}:{type:"organization"};try{return t.authorize(ne,"deployments:read",It),!0}catch{return!1}}).map((Be)=>({...t.operation(Be.operation),queue:Be.job,approximatePosition:Be.approximatePosition}));me=yn(Ee,K,X)}else if(z.method==="GET"&&K.pathname==="/api/v1/queue/settings")t.authorize(ne,"deployments:read",ne.token.scope),me={concurrency:r.limits,requestId:X};else if(z.method==="PATCH"&&K.pathname==="/api/v1/queue/settings"){t.authorize(ne,"automation:manage",{type:"organization"});let Y=await We();if(Y.confirm!=="update queue limits")throw new i("confirmation_required","Type update queue limits to confirm production concurrency changes.",409);me={concurrency:r.configureConcurrency(Y.concurrency??{},{organizationId:ne.serviceAccount.organizationId,actorId:ne.actor.id}),requestId:X}}else if(z.method==="DELETE"&&K.pathname==="/api/v1/queue/history"){t.authorize(ne,"automation:manage",{type:"organization"});let Y=await We();if(Y.confirm!=="clear completed")throw new i("confirmation_required","Type clear completed to confirm queue retention cleanup.",409);me={deleted:r.clearCompleted({before:typeof Y.before==="string"?Y.before:void 0,actorId:ne.actor.id,projectId:typeof Y.projectId==="string"?Y.projectId:void 0}),requestId:X}}else if(z.method==="GET"&&wt){let Y=e.controlPlane.getOperation(decodeURIComponent(wt[1]));if(!Y)throw new i("not_found","Operation was not found.",404);let be=Y.resourceId?{type:"resource",id:Y.resourceId}:Y.environmentId?{type:"environment",id:Y.environmentId}:Y.projectId?{type:"project",id:Y.projectId}:{type:"organization"};t.authorize(ne,"deployments:read",be);let Ee=z.headers.get("last-event-id")?.trim(),Be=Number(Ee||K.searchParams.get("after")||0);if(wt[2]==="stream"){let Ut=new TextEncoder,Fe=Be,Ct,bt=!1,rt=new ReadableStream({start(ln){let Qs=()=>{if(bt)return;if(!e.identities.verifyToken(ye,H)){if(bt=!0,Ct)clearInterval(Ct);ln.close();return}let Zn=r.logs(Y.id,{after:Fe,limit:500});for(let lr of Zn)Fe=lr.sequence,ln.enqueue(Ut.encode(`id: ${lr.sequence}
47
+ `)){let m=o.trim().match(/^([a-f0-9]{40,64})\s+(.+)$/i);if(!m||!m[2].startsWith(t)||m[2].endsWith("^{}"))continue;let h=m[2].slice(t.length);r.set(h,{name:h,commitSha:m[1]})}return[...r.values()].sort((o,m)=>o.name.localeCompare(m.name))}async function yo(e,t={}){let r=gh(e,t.deployKey),o=await xs(["ls-remote","--heads","--tags","--",r],r,t);return{branches:mh(o,"refs/heads/"),tags:mh(o,"refs/tags/")}}async function Io(e,t={}){let r=gh(e.remote,t.deployKey),o=xk(e.destination),m=e.ref?.trim()||e.binding.defaultBranch;if(!/^[A-Za-z0-9._/-]{1,255}$/.test(m)||m.startsWith("-")||m.includes(".."))throw Error("Git ref contains unsupported characters");let h=["clone","--no-tags","--single-branch","--branch",m],I=[...new Set(e.sparsePaths??[])];if(I.some((A)=>!A||A.startsWith("/")||A.split("/").includes("..")||/[\0\r\n]/.test(A)))throw Error("Sparse checkout paths must stay inside the repository");if(I.length)h.push("--filter=blob:none","--no-checkout");if(e.binding.cloneDepth)h.push("--depth",String(e.binding.cloneDepth));if(e.binding.submodules)h.push("--recurse-submodules","--shallow-submodules");if(h.push("--",r,o),await xs(h,r,t),I.length)await xs(["-C",o,"sparse-checkout","set","--cone","--",...I],r,t),await xs(["-C",o,"checkout","--force"],r,t);if(e.commitSha){if(!/^[a-f0-9]{40,64}$/i.test(e.commitSha))throw Error("Expected source commit must be an immutable 40-64 character SHA");await xs(["-C",o,"fetch","--no-tags","--depth","1","origin",e.commitSha],r,t),await xs(["-C",o,"checkout","--detach","--force",e.commitSha],r,t)}let R=(await xs(["-C",o,"rev-parse","HEAD"],r,t)).trim();if(!/^[a-f0-9]{40,64}$/i.test(R))throw Error("Git clone did not produce a valid commit SHA");if(e.commitSha&&R.toLowerCase()!==e.commitSha.toLowerCase())throw Error(`Git checkout resolved ${R} instead of the requested immutable commit`);return{directory:e.binding.monorepoRoot==="."?o:Uc(o,e.binding.monorepoRoot),commitSha:R}}function oc(e){return["github","gitlab","bitbucket","gitea"].includes(e)}async function So(e,t,r){let o=e.getConnection(t);if(!o||["disconnected","expired"].includes(o.status))throw Error("Active source connection was not found");try{if(oc(o.provider)){let I=await je(o,e.getCredential(o.id)).testConnection();return e.updateHealth(o.id,{status:I.ok?"healthy":"degraded",message:I.message,tested:!0,grantedScopes:I.scopes})}let m=r?e.getRepository(r):e.listRepositories(o.id,void 0,1)[0];if(!m)return e.updateHealth(o.id,{status:"degraded",message:"Add a repository URL before testing this generic connection.",tested:!0});let h=o.provider==="generic_ssh"?e.listBindings({connectionId:o.id}).map((I)=>I.deployKeyId).filter(Boolean).map((I)=>e.getDeployKey(I)).find(Boolean):void 0;return await yo(m.cloneUrl,{credential:e.getCredential(o.id),deployKey:h?{...h,privateKey:e.getDeployPrivateKey(h.id)}:void 0}),e.updateHealth(o.id,{status:"healthy",message:"Git repository access is healthy.",tested:!0})}catch(m){return e.updateHealth(o.id,{status:"degraded",message:m instanceof Error?m.message:"Connection test failed",tested:!0})}}async function Ti(e,t,r={}){let o=e.getConnection(t);if(!o||!oc(o.provider)||["disconnected","expired"].includes(o.status))throw Error("A hosted active source connection is required for repository discovery");let m=je(o,e.getCredential(o.id)),h=[],I;for(let R=0;R<Math.min(20,Math.max(1,r.maxPages??10));R++){let A=await m.listRepositories({cursor:I,search:r.search,limit:100});for(let E of A.repositories)h.push(e.upsertRepository({connectionId:o.id,...E}));if(I=A.nextCursor,!I)break}return e.updateHealth(o.id,{status:"healthy",message:`${h.length} repositories synchronized.`,synced:!0}),h}async function wi(e,t){let r=e.getConnection(t.connectionId);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active source connection was not found");if(oc(r.provider)){let R=je(r,e.getCredential(r.id));return t.type==="tags"?R.listTags(t.repository,t):R.listBranches(t.repository,t)}let o=t.repositoryId?e.getRepository(t.repositoryId):e.listRepositories(r.id).find((R)=>R.fullName===t.repository);if(!o||o.connectionId!==r.id)throw Error("Generic repository metadata was not found");let m=t.deployKeyId?e.getDeployKey(t.deployKeyId):void 0;if(m&&m.connectionId!==r.id)throw Error("Deploy key does not belong to this connection");let h=await yo(o.cloneUrl,{credential:e.getCredential(r.id),deployKey:m?{...m,privateKey:e.getDeployPrivateKey(m.id)}:void 0});return{refs:(t.type==="tags"?h.tags:h.branches).slice(0,Math.min(500,t.limit??100))}}async function Mr(e,t,r){let o=e.getWebhook(t),m=o?e.getConnection(o.connectionId):void 0;if(!o||!m||["disconnected","expired"].includes(m.status))throw Error("Active source webhook was not found");let h=Vt(r,{...o,endpointToken:e.getWebhookEndpointToken(o.id)});if(!oc(m.provider))return e.updateWebhookState(o.id,{status:"healthy",healthMessage:"Manual webhook endpoint is ready.",reconciled:!0});try{let I=je(m,e.getCredential(m.id)),R=e.getWebhookSecret(o.id),A=o.providerWebhookId?await I.updateWebhook(o.repositoryFullName,o.providerWebhookId,{url:h,secret:R,events:o.events}):await I.createWebhook(o.repositoryFullName,{url:h,secret:R,events:o.events});return e.updateWebhookState(o.id,{providerWebhookId:A.providerWebhookId,status:A.active?"healthy":"degraded",healthMessage:A.active?"Provider webhook is synchronized.":"Provider webhook exists but is inactive.",reconciled:!0})}catch(I){return e.updateWebhookState(o.id,{status:"degraded",healthMessage:I instanceof Error?I.message:"Webhook reconciliation failed",reconciled:!0})}}async function Vd(e,t){let r=e.getWebhook(t),o=r?e.getConnection(r.connectionId):void 0;if(!r||!o)throw Error("Source webhook was not found");if(oc(o.provider)&&r.providerWebhookId&&!["disconnected","expired"].includes(o.status))await je(o,e.getCredential(o.id)).deleteWebhook(r.repositoryFullName,r.providerWebhookId);return e.updateWebhookState(r.id,{status:"disabled",healthMessage:"Webhook disabled."})}var Ri="1.6.0";function Co(){let e={type:"object",required:["error"],properties:{error:{type:"object",required:["code","message","requestId"],properties:{code:{type:"string"},message:{type:"string"},requestId:{type:"string",format:"uuid"},details:{}}}}},t=(o)=>({type:"object",required:["data","page","requestId"],properties:{data:{type:"array",items:o},page:{type:"object",required:["hasMore"],properties:{nextCursor:{type:"string"},hasMore:{type:"boolean"}}},requestId:{type:"string",format:"uuid"}}}),r=(o)=>({"200":{description:"A stable cursor page.",content:{"application/json":{schema:t(o)}}},default:{$ref:"#/components/responses/Error"}});return{openapi:"3.1.0",info:{title:"ts-cloud API",version:Ri,description:"Additive changes are released within v1. Breaking request or response changes require a new URL version."},servers:[{url:"/"}],security:[{bearerAuth:[]}],paths:{...Us(),"/api/v1/projects":{get:{operationId:"listProjects",summary:"List accessible projects",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Project"})}},"/api/v1/projects/{projectId}/environments":{get:{operationId:"listEnvironments",summary:"List accessible project environments",parameters:[{$ref:"#/components/parameters/ProjectId"},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Environment"})}},"/api/v1/services":{get:{operationId:"listServices",summary:"List accessible services",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{name:"environmentId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Service"})}},"/api/v1/source/connections":{get:{operationId:"listSourceConnections",summary:"List safe Git connection metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceConnection"})},post:{operationId:"createSourceConnection",summary:"Create an encrypted Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["provider","name","host"],properties:{provider:{type:"string",enum:["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"]},name:{type:"string"},host:{type:"string",format:"uri"},token:{type:"string",writeOnly:!0},repositoryFullName:{type:"string"},repositoryUrl:{type:"string"}}}}}},responses:{"201":{description:"Encrypted connection created."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectSourceConnection",summary:"Preview or safely disconnect a Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["id"],properties:{id:{type:"string"},preview:{type:"boolean"}}}}}},responses:{"200":{description:"Impact preview or disconnected connection."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/repositories":{get:{operationId:"listSourceRepositories",summary:"List or synchronize granted repositories",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"sync",in:"query",schema:{type:"boolean"}},{name:"search",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceRepository"})}},"/api/v1/source/refs":{get:{operationId:"listSourceRefs",summary:"List repository branches or tags",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"repository",in:"query",required:!0,schema:{type:"string"}},{name:"repositoryId",in:"query",schema:{type:"string"}},{name:"type",in:"query",schema:{type:"string",enum:["branches","tags"]}}],responses:{"200":{description:"Provider reference page."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/bindings":{post:{operationId:"createSourceBinding",summary:"Bind a repository to an application",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/SourceBindingRequest"}}}},responses:{"201":{description:"Source binding created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/webhooks":{post:{operationId:"createSourceWebhook",summary:"Create and optionally reconcile a signed webhook",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["connectionId","repositoryFullName","baseUrl"],properties:{connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},baseUrl:{type:"string",format:"uri"},events:{type:"array",items:{type:"string",enum:["push","pull_request"]}},reconcile:{type:"boolean"}}}}}},responses:{"201":{description:"Webhook endpoint created; endpoint is revealed once."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-detections":{post:{operationId:"detectApplication",summary:"Detect bounded application build candidates",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["files"],properties:{files:{type:"array",maxItems:1e4,items:{$ref:"#/components/schemas/DetectionFile"}}}}}}},responses:{"200":{description:"Ranked detection candidates with evidence."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-plans":{post:{operationId:"planApplication",summary:"Validate and normalize an application manifest",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["draft"],properties:{draft:{$ref:"#/components/schemas/ApplicationInput"},suppliedSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}}}}}},responses:{"200":{description:"Validated plan, config patch, capabilities, costs, and missing secret names."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-drafts":{get:{operationId:"listApplicationDrafts",summary:"List resumable secret-free drafts",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/ApplicationDraft"})},post:{operationId:"createApplicationDraft",summary:"Create a resumable application draft",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/ApplicationDraftCreateRequest"}}}},responses:{"201":{description:"Draft created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateApplicationDraft",summary:"Optimistically update a draft",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/ApplicationDraftCreateRequest"},{type:"object",required:["id","version","step"],properties:{id:{type:"string"},version:{type:"integer",minimum:1}}}]}}}},responses:{"200":{description:"Updated draft."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/applications":{post:{operationId:"createApplication",summary:"Confirm and queue an application plan",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["draftId","version","confirmEnvironment"],properties:{draftId:{type:"string"},version:{type:"integer",minimum:1},confirmEnvironment:{type:"string",description:"Exact target environment slug."}}}}}},responses:{"202":{description:"Application operation queued; identical requests replay safely."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-artifacts":{post:{operationId:"uploadApplicationArtifact",summary:"Inspect and store a bounded ZIP or TAR source artifact",parameters:[{name:"X-Project-Id",in:"header",required:!0,schema:{type:"string"}},{name:"X-Artifact-Filename",in:"header",required:!0,schema:{type:"string"}}],requestBody:{required:!0,content:{"application/octet-stream":{schema:{type:"string",format:"binary",maxLength:104857600}}}},responses:{"201":{description:"Deduplicated artifact metadata; archive contents are never executed."},"413":{$ref:"#/components/responses/Error"},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/registry-connections":{get:{operationId:"listRegistryConnections",summary:"List safe private-registry metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/RegistryConnection"})},post:{operationId:"createRegistryConnection",summary:"Create an encrypted private-registry connection",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/RegistryConnectionRequest"}}}},responses:{"201":{description:"Encrypted registry connection created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateRegistryConnection",summary:"Test access or rotate write-only credentials",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/RegistryConnectionRequest"},{type:"object",required:["id","action"],properties:{id:{type:"string"},action:{type:"string",enum:["test","rotate"]},image:{type:"string"}}}]}}}},responses:{"200":{description:"Safe connection health metadata."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectRegistryConnection",summary:"Disconnect and erase registry credentials",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["id"],properties:{id:{type:"string"}}}}}},responses:{"200":{description:"Credentials erased and connection disconnected."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue":{get:{operationId:"listQueue",summary:"List authorized durable operations and blocking metadata",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"state",in:"query",schema:{type:"string",enum:["queued","running","succeeded","failed","cancelled","timed_out"]}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/QueueOperation"})}},"/api/v1/preview-definitions":{get:{operationId:"listPreviewDefinitions",summary:"List preview policies",responses:r({type:"object"})},post:{operationId:"createPreviewDefinition",summary:"Configure bounded preview policy",responses:{"200":{description:"Preview definition created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews":{get:{operationId:"listPreviews",summary:"List authorized persistent previews",responses:r({type:"object"})},post:{operationId:"createPreview",summary:"Create or update one immutable preview identity",responses:{"200":{description:"Preview deployment queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/destroy":{post:{operationId:"destroyPreview",summary:"Confirm tagged preview teardown",responses:{"200":{description:"Teardown queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/extend":{post:{operationId:"extendPreview",summary:"Extend preview TTL",responses:{"200":{description:"Expiry extended."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/rebuild":{post:{operationId:"rebuildPreview",summary:"Rebuild the exact recorded commit",responses:{"200":{description:"Rebuild queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/cleanup":{post:{operationId:"cleanupPreviews",summary:"Dry-run or queue TTL/keep-count teardown",responses:{"200":{description:"Cleanup plan or operations."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-templates":{get:{operationId:"listComposeTemplates",summary:"List pinned verified application templates",responses:r({type:"object"})}},"/api/v1/compose-applications":{get:{operationId:"listComposeApplications",summary:"List authorized multi-service applications",responses:r({type:"object"})},post:{operationId:"createComposeApplication",summary:"Import Compose or materialize a template",responses:{"200":{description:"Editable normalized application."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/preview":{post:{operationId:"previewComposeApplication",summary:"Parse and diagnose Compose without mutation",responses:{"200":{description:"Normalized preview and actionable diagnostics."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/services":{get:{operationId:"listComposeServices",summary:"Inspect per-service desired and observed state",responses:{"200":{description:"Service topology and status."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/{action}":{post:{operationId:"operateComposeApplication",summary:"Deploy, redeploy, start, stop, scale, or delete through the durable queue",responses:{"200":{description:"Scoped operation queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/release-artifacts":{post:{operationId:"createReleaseArtifact",summary:"Register a verified content-addressed artifact",responses:{"200":{description:"Artifact identity registered."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases":{get:{operationId:"listReleases",summary:"List unified authorized release history",responses:r({type:"object"})},post:{operationId:"createRelease",summary:"Create an immutable release from an existing artifact",responses:{"200":{description:"Release record created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/capabilities":{get:{operationId:"getReleaseCapabilities",summary:"Explain supported strategies, capacity, cost, and rollback",responses:{"200":{description:"Provider-aware strategy capabilities."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}":{get:{operationId:"getRelease",summary:"Inspect provenance, approvals, health, and transitions",responses:{"200":{description:"Release detail."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}/{action}":{post:{operationId:"operateRelease",summary:"Promote, approve, activate, roll back, report health, or pin",responses:{"200":{description:"Release lifecycle updated."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/settings":{get:{operationId:"getQueueSettings",summary:"Get effective concurrency limits",responses:{"200":{description:"Queue concurrency settings."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateQueueSettings",summary:"Confirm and audit production concurrency changes",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm","concurrency"],properties:{confirm:{const:"update queue limits"},concurrency:{$ref:"#/components/schemas/QueueConcurrency"}}}}}},responses:{"200":{description:"Updated effective limits."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/history":{delete:{operationId:"clearQueueHistory",summary:"Clear terminal jobs whose retention has elapsed",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm"],properties:{confirm:{const:"clear completed"},before:{type:"string",format:"date-time"},projectId:{type:"string"}}}}}},responses:{"200":{description:"Eligible history cleared with an audit event."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs":{get:{operationId:"listOperationLogs",summary:"Resume ordered sanitized operation logs from a cursor",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:{"200":{description:"Ordered log chunks and next cursor."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs/stream":{get:{operationId:"streamOperationLogs",summary:"Stream authorized operation logs with Last-Event-ID resume",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"Last-Event-ID",in:"header",schema:{type:"integer",minimum:0}}],responses:{"200":{description:"Server-sent log and completion events.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/cancel":{post:{operationId:"cancelOperation",summary:"Cancel queued work or request cooperative running cancellation",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{content:{"application/json":{schema:{type:"object"}}}},responses:{"200":{description:"Cancellation state recorded."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/retry":{post:{operationId:"retryOperation",summary:"Retry an allow-listed failure class within the attempt limit",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["errorClass"],properties:{errorClass:{type:"string"},delayMs:{type:"integer",minimum:0}}}}}},responses:{"200":{description:"Retry queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/deployments":{post:{operationId:"createDeployment",summary:"Queue a deployment",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/DeploymentRequest"}}}},responses:{"202":{description:"Queued operation.",content:{"application/json":{schema:{$ref:"#/components/schemas/OperationResponse"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations":{get:{operationId:"listOperations",summary:"List scoped operations",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Operation"})}},"/api/v1/events":{get:{operationId:"listEvents",summary:"List scoped audit events",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:r({$ref:"#/components/schemas/Event"})}},"/api/v1/events/stream":{get:{operationId:"streamEvents",summary:"Stream scoped audit events",responses:{"200":{description:"Authenticated server-sent event stream.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/openapi.json":{get:{operationId:"getOpenApi",summary:"Get the OpenAPI contract",security:[],responses:{"200":{description:"OpenAPI 3.1 contract."}}}}},components:{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer",bearerFormat:"tsc_v1"}},parameters:{Limit:{name:"limit",in:"query",schema:{type:"integer",minimum:1,maximum:100,default:50}},Cursor:{name:"cursor",in:"query",schema:{type:"string"}},ProjectId:{name:"projectId",in:"path",required:!0,schema:{type:"string"}},OperationId:{name:"operationId",in:"path",required:!0,schema:{type:"string"}}},responses:{Error:{description:"Stable error envelope.",content:{"application/json":{schema:e}}}},schemas:{Project:{type:"object",required:["id","slug","name"],properties:{id:{type:"string"},slug:{type:"string"},name:{type:"string"},description:{type:"string"}}},Environment:{type:"object",required:["id","projectId","slug","name","kind"],properties:{id:{type:"string"},projectId:{type:"string"},slug:{type:"string"},name:{type:"string"},kind:{type:"string"},region:{type:"string"}}},Service:{type:"object",required:["id","projectId","kind","slug","name"],properties:{id:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},kind:{type:"string"},slug:{type:"string"},name:{type:"string"},metadata:{type:"object",additionalProperties:!0}}},SourceConnection:{type:"object",required:["id","provider","name","host","status","credentialConfigured"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},status:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},grantedScopes:{type:"array",items:{type:"string"}}}},SourceRepository:{type:"object",required:["id","connectionId","fullName","cloneUrl","defaultBranch"],properties:{id:{type:"string"},connectionId:{type:"string"},fullName:{type:"string"},cloneUrl:{type:"string"},defaultBranch:{type:"string"},visibility:{type:"string"},archived:{type:"boolean"}}},SourceBindingRequest:{type:"object",additionalProperties:!1,required:["projectId","connectionId","repositoryFullName"],properties:{projectId:{type:"string"},environmentId:{type:"string"},resourceId:{type:"string"},connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},defaultBranch:{type:"string"},branchRule:{type:"string"},tagRule:{type:"string"},monorepoRoot:{type:"string"},includePaths:{type:"array",items:{type:"string"}},excludePaths:{type:"array",items:{type:"string"}},submodules:{type:"boolean"},cloneDepth:{type:"integer",minimum:1},deployKeyId:{type:"string"},autoDeploy:{type:"boolean"},pullRequestPreviews:{type:"boolean"}}},DetectionFile:{type:"object",additionalProperties:!1,required:["path"],properties:{path:{type:"string"},size:{type:"integer",minimum:0},content:{type:"string",maxLength:262144}}},ApplicationInput:{type:"object",additionalProperties:!1,required:["schemaVersion","name","slug","projectId","environmentId","source","build","runtime"],properties:{schemaVersion:{const:1},name:{type:"string"},slug:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},source:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["git","local","artifact","image"]}},additionalProperties:!0},build:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["dockerfile","buildpack","static","server","serverless","prebuilt_image"]},secretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}},additionalProperties:!0},runtime:{type:"object",required:["architecture","target"],properties:{architecture:{type:"string",enum:["x86_64","arm64"]},target:{type:"string",enum:["server","serverless","container"]},port:{type:"integer",minimum:1,maximum:65535},healthCheck:{type:"object",additionalProperties:!0}},additionalProperties:!0},environment:{type:"object",additionalProperties:{oneOf:[{type:"string"},{type:"object",additionalProperties:!1,required:["secretRef"],properties:{secretRef:{type:"string"}}}]}},requiredSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}},domain:{type:"object",properties:{hostname:{type:"string"},path:{type:"string"},tls:{type:"boolean"}}}}},ApplicationDraftCreateRequest:{type:"object",additionalProperties:!1,required:["projectId","draft"],properties:{projectId:{type:"string"},name:{type:"string"},draft:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string",enum:["source","build","runtime","environment","domain","review"]},suppliedSecretNames:{type:"array",uniqueItems:!0,description:"Names only; values must use the secrets boundary.",items:{type:"string"}}}},ApplicationDraft:{type:"object",required:["id","projectId","input","step","status","version"],properties:{id:{type:"string"},projectId:{type:"string"},input:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string"},suppliedSecretNames:{type:"array",items:{type:"string"}},status:{type:"string",enum:["draft","ready","applied"]},version:{type:"integer"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"}}},RegistryConnectionRequest:{type:"object",properties:{provider:{type:"string",enum:["docker_hub","ghcr","ecr","gcr","generic"]},name:{type:"string"},host:{type:"string"},username:{type:"string",writeOnly:!0},password:{type:"string",writeOnly:!0},token:{type:"string",writeOnly:!0},credentialExpiresAt:{type:"string",format:"date-time"},expiresAt:{type:"string",format:"date-time"}}},RegistryConnection:{type:"object",required:["id","provider","name","host","credentialConfigured","status","version"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},credentialExpiresAt:{type:"string",format:"date-time"},status:{type:"string",enum:["pending","healthy","degraded","expired","disconnected"]},healthMessage:{type:"string"},lastTestedAt:{type:"string",format:"date-time"},version:{type:"integer"}}},QueueConcurrency:{type:"object",additionalProperties:!1,properties:{project:{type:"integer",minimum:1,maximum:100},environment:{type:"integer",minimum:1,maximum:100},provider:{type:"integer",minimum:1,maximum:100},builds:{type:"integer",minimum:1,maximum:100}}},QueueOperation:{allOf:[{$ref:"#/components/schemas/Operation"},{type:"object",required:["queue"],properties:{queue:{type:"object",required:["maxAttempts","availableAt","timeoutSeconds","retryClasses","resumePolicy","cancellationMode","retentionUntil"],properties:{lockKey:{type:"string"},providerKey:{type:"string"},buildSlot:{type:"boolean"},maxAttempts:{type:"integer"},availableAt:{type:"string",format:"date-time"},timeoutSeconds:{type:"integer"},heartbeatAt:{type:"string",format:"date-time"},currentStep:{type:"string"},blockedReason:{type:"string"},retryClasses:{type:"array",items:{type:"string"}},resumePolicy:{type:"string",enum:["fail","requeue"]},cancellationMode:{type:"string",enum:["cooperative","provider_non_cancellable"]},retentionUntil:{type:"string",format:"date-time"}}},approximatePosition:{type:"object",properties:{ahead:{type:"integer"},precision:{const:"bounded"}}}}}]},DeploymentRequest:{type:"object",additionalProperties:!1,required:["projectId","environmentId"],properties:{projectId:{type:"string"},environmentId:{type:"string"},serviceId:{type:"string"},action:{type:"string",enum:["deploy","rollback"],default:"deploy"},revision:{type:"string"}}},Operation:{type:"object",required:["id","state","kind","correlationId","createdAt"],properties:{id:{type:"string"},state:{type:"string"},kind:{type:"string"},correlationId:{type:"string"},createdAt:{type:"string",format:"date-time"}}},OperationResponse:{type:"object",required:["operation","idempotentReplay","requestId"],properties:{operation:{$ref:"#/components/schemas/Operation"},idempotentReplay:{type:"boolean"},requestId:{type:"string",format:"uuid"}}},Event:{type:"object",required:["id","sequence","type","level","correlationId","createdAt"],properties:{id:{type:"string"},sequence:{type:"integer"},type:{type:"string"},level:{type:"string"},correlationId:{type:"string"},payload:{},createdAt:{type:"string",format:"date-time"}}}}}}}function Nk(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}function jk(e){if(!e)return;try{let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return t&&typeof t==="object"&&!Array.isArray(t)?t:void 0}catch{return}}function yn(e,t,r,o=["createdAt","id"]){let m=Math.min(100,Math.max(1,Number(t.searchParams.get("limit"))||50)),h=jk(t.searchParams.get("cursor"));if(t.searchParams.has("cursor")&&!h)throw new i("invalid_cursor","The pagination cursor is invalid.",400);let I=0;if(h){let x=e.findIndex((N)=>o.every((F)=>N[F]===h[F]));if(x<0)throw new i("invalid_cursor","The pagination cursor is no longer available.",400);I=x+1}let R=e.slice(I,I+m),A=I+m<e.length,E=R.at(-1);return{data:R,page:{hasMore:A,nextCursor:A&&E?Nk(Object.fromEntries(o.map((x)=>[x,E[x]]))):void 0},requestId:r}}function bo(e){let t=new di(e.controlPlane,e.identities),r=new c(e.controlPlane),o=new Ir(e.controlPlane),m=new Cr(e.controlPlane),h=new lt(e.controlPlane),I=e.spend?.store??new ei(e.controlPlane,{now:e.now}),R={store:I,service:e.spend?.service??new Lt(I)},A=new Map,E=e.now??(()=>new Date),x=e.rateLimit??120,N=(z,H,K,X={})=>new Response(JSON.stringify(z),{status:H,headers:{"content-type":"application/json; charset=utf-8","cache-control":"no-store","x-request-id":K,"x-api-version":Ri,...X}}),F=(z,H,K,X,oe,ye)=>N({error:{code:z,message:H,requestId:X,details:oe}},K,X,ye);return async(z,H)=>{let K=new URL(z.url);if(!K.pathname.startsWith("/api/v1"))return;let X=crypto.randomUUID();if(K.pathname==="/api/v1/openapi.json"&&z.method==="GET")return N(Co(),200,X,{"cache-control":"public, max-age=300"});let oe=z.headers.get("authorization")??"",ye=oe.startsWith("Bearer ")?oe.slice(7).trim():"",ne=ye?e.identities.verifyToken(ye,H):void 0;if(!ne)return F("unauthorized","A valid bearer token is required.",401,X,void 0,{"www-authenticate":'Bearer realm="ts-cloud", error="invalid_token"'});let fe=A.get(ne.token.id),Ce=E().getTime(),xe=!fe||Ce-fe.start>=60000?{start:Ce,count:0}:fe;xe.count+=1,A.set(ne.token.id,xe);let he=Math.max(0,x-xe.count),Ue={"x-ratelimit-limit":String(x),"x-ratelimit-remaining":String(he),"x-ratelimit-reset":String(Math.ceil((xe.start+60000)/1000))};if(xe.count>x)return F("rate_limited","API rate limit exceeded.",429,X,void 0,{...Ue,"retry-after":String(Math.max(1,Math.ceil((xe.start+60000-Ce)/1000)))});try{let me,He=async()=>{let Y=await z.text();if(Y.length>1048576)throw new i("payload_too_large","Request body exceeds 1 MB.",413);try{return JSON.parse(Y)}catch{throw new i("invalid_json","Request body must be valid JSON.",400)}},nt=/^\/api\/v1\/projects\/([^/]+)\/environments$/.exec(K.pathname),wt=/^\/api\/v1\/operations\/([^/]+)\/logs(?:\/(stream))?$/.exec(K.pathname),cr=/^\/api\/v1\/operations\/([^/]+)\/(cancel|retry)$/.exec(K.pathname),st=/^\/api\/v1\/previews\/([^/]+)\/(destroy|extend|rebuild)$/.exec(K.pathname),Ft=/^\/api\/v1\/compose-applications\/([^/]+)\/(deploy|redeploy|start|stop|scale|delete)$/.exec(K.pathname),dr=/^\/api\/v1\/compose-applications\/([^/]+)\/services$/.exec(K.pathname),vt=/^\/api\/v1\/releases\/([^/]+)\/(promote|approve|activate|rollback|health|pin)$/.exec(K.pathname);if(z.method==="GET"&&K.pathname==="/api/v1/projects")me=yn(t.listProjects(ne),K,X);else if(z.method==="GET"&&nt)me=yn(t.listEnvironments(ne,decodeURIComponent(nt[1])),K,X);else if(z.method==="GET"&&K.pathname==="/api/v1/services"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);me=yn(t.listServices(ne,Y,K.searchParams.get("environmentId")??void 0),K,X)}else if(z.method==="GET"&&K.pathname==="/api/v1/operations")me=yn(t.listOperations(ne,K.searchParams.get("projectId")??void 0),K,X);else if(z.method==="GET"&&K.pathname==="/api/v1/previews"){let Y=K.searchParams.get("projectId")??void 0,be=o.previews.listInstances({projectId:Y}).filter((Ee)=>{try{return t.authorize(ne,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee}));me=yn(be,K,X)}else if(z.method==="GET"&&K.pathname==="/api/v1/compose-templates")me=yn(yr().map((Y)=>({...Y})),K,X,["id","version"]);else if(z.method==="GET"&&K.pathname==="/api/v1/releases/capabilities"){let Y=String(K.searchParams.get("kind")??"");me={capabilities:$r({kind:Y,hasHealthGate:K.searchParams.get("health")==="true",replicas:Number(K.searchParams.get("replicas"))||1}),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/releases"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);t.authorize(ne,"project:read",{type:"project",id:Y});let be=h.releases.list({projectId:Y,environmentId:K.searchParams.get("environmentId")??void 0,resourceId:K.searchParams.get("resourceId")??void 0}).filter((Ee)=>{try{return t.authorize(ne,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,artifact:h.releases.getArtifact(Ee.artifactId),transitions:h.releases.transitions(Ee.id),approvals:h.releases.approvals(Ee.id)}));me=yn(be,K,X)}else if(z.method==="POST"&&K.pathname==="/api/v1/release-artifacts"){let Y=await He();t.authorize(ne,"applications:manage",{type:"organization"}),me={artifact:h.releases.registerArtifact({organizationId:ne.serviceAccount.organizationId,digest:String(Y.digest??""),kind:String(Y.kind??""),uri:String(Y.uri??""),size:Number(Y.size),mediaType:typeof Y.mediaType==="string"?Y.mediaType:void 0,provenance:Y.provenance,attestation:Y.attestation}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/releases"){let Y=await He(),be=String(Y.resourceId??"");t.authorize(ne,"applications:manage",{type:"resource",id:be}),me={release:h.releases.create({organizationId:ne.serviceAccount.organizationId,projectId:String(Y.projectId??""),environmentId:String(Y.environmentId??""),resourceId:be,artifactId:String(Y.artifactId??""),kind:String(Y.kind??""),sourceSha:typeof Y.sourceSha==="string"?Y.sourceSha:void 0,config:Y.config??{},manifest:Y.manifest??{},provenance:Y.provenance,strategy:String(Y.strategy??"atomic"),healthGate:Y.healthGate,hooks:Y.hooks,drainSeconds:Number(Y.drainSeconds)||void 0,graceSeconds:Number(Y.graceSeconds)||void 0,automaticRollback:Y.automaticRollback!==!1,actorId:ne.actor.id,trigger:typeof Y.trigger==="string"?Y.trigger:"api",approvalRequired:Y.approvalRequired===!0,replicas:Number(Y.replicas)||void 0}),requestId:X}}else if(z.method==="GET"&&/^\/api\/v1\/releases\/[^/]+$/.test(K.pathname)){let Y=decodeURIComponent(K.pathname.split("/").at(-1)),be=h.releases.get(Y);if(!be)throw new i("not_found","Release was not found.",404);t.authorize(ne,"deployments:read",{type:"resource",id:be.resourceId}),me={release:be,artifact:h.releases.getArtifact(be.artifactId),transitions:h.releases.transitions(Y),approvals:h.releases.approvals(Y),requestId:X}}else if(z.method==="POST"&&vt){let Y=h.releases.get(decodeURIComponent(vt[1]));if(!Y)throw new i("not_found","Release was not found.",404);let be=await He(),Ee=vt[2];if(Ee==="promote"){let Ne=String(be.targetResourceId??"");t.authorize(ne,"deployments:create",{type:"resource",id:Ne}),me={release:h.releases.promote(Y.id,{targetEnvironmentId:String(be.targetEnvironmentId??""),targetResourceId:Ne,config:be.config??{},strategy:be.strategy,healthGate:be.healthGate,actorId:ne.actor.id,approvalRequired:be.approvalRequired===!0}),requestId:X}}else if(Ee==="approve")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={release:h.releases.approve(Y.id,{actorId:ne.actor.id,decision:be.decision==="rejected"?"rejected":"approved",comment:typeof be.comment==="string"?be.comment:void 0}),requestId:X};else if(Ee==="activate")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(h.enqueueActivation(Y,{actorId:ne.actor.id})),requestId:X};else if(Ee==="rollback")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(h.enqueueRollback(Y,{actorId:ne.actor.id,targetReleaseId:typeof be.targetReleaseId==="string"?be.targetReleaseId:void 0})),requestId:X};else if(Ee==="health"){t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId});let Ne=h.completeHealthGate(Y.id,{healthy:be.healthy===!0,operationId:typeof be.operationId==="string"?be.operationId:void 0,health:be.health,message:typeof be.message==="string"?be.message:void 0});me={release:Ne.release,rollbackOperation:Ne.rollbackOperation?t.operation(Ne.rollbackOperation):void 0,requestId:X}}else t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={release:h.releases.pin(Y.id,be.pinned!==!1,typeof be.reason==="string"?be.reason:void 0),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/compose-applications"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);t.authorize(ne,"project:read",{type:"project",id:Y});let be=m.applications.list({projectId:Y,environmentId:K.searchParams.get("environmentId")??void 0}).filter((Ee)=>{try{return t.authorize(ne,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,services:m.applications.services(Ee.id)}));me=yn(be,K,X)}else if(z.method==="POST"&&K.pathname==="/api/v1/compose-applications/preview"){let Y=await He(),be=String(Y.projectId??"");t.authorize(ne,"project:read",{type:"project",id:be}),me={result:m.applications.preview(String(Y.source??""),{name:String(Y.name??""),slug:typeof Y.slug==="string"?Y.slug:void 0,projectId:be,environmentId:String(Y.environmentId??"")}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/compose-applications"){let Y=await He(),be=String(Y.projectId??"");t.authorize(ne,"applications:manage",{type:"environment",id:String(Y.environmentId??"")});let Ee={name:String(Y.name??""),slug:typeof Y.slug==="string"?Y.slug:void 0,projectId:be,environmentId:String(Y.environmentId??""),createdByActorId:ne.actor.id},Ne=typeof Y.templateId==="string"?m.applications.fromTemplate(Y.templateId,Y.inputs&&typeof Y.inputs==="object"&&!Array.isArray(Y.inputs)?Y.inputs:{},{...Ee,version:typeof Y.templateVersion==="string"?Y.templateVersion:void 0}):m.applications.import(String(Y.source??""),Ee);me={application:Ne.application,diagnostics:Ne.parsed.diagnostics,requestId:X}}else if(z.method==="GET"&&dr){let Y=m.applications.get(decodeURIComponent(dr[1]));if(!Y)throw new i("not_found","Compose application was not found.",404);t.authorize(ne,"deployments:read",{type:"resource",id:Y.resourceId}),me={application:Y,services:m.applications.services(Y.id),requestId:X}}else if(z.method==="POST"&&Ft){let Y=m.applications.get(decodeURIComponent(Ft[1]));if(!Y)throw new i("not_found","Compose application was not found.",404);let be=Ft[2],Ee=await He();t.authorize(ne,be==="delete"||be==="stop"?"deployments:cancel":"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(m.enqueue(Y,be,{actorId:ne.actor.id,service:typeof Ee.service==="string"?Ee.service:void 0,replicas:Number.isFinite(Number(Ee.replicas))?Number(Ee.replicas):void 0,removeVolumes:Ee.removeVolumes===!0,confirmation:typeof Ee.confirm==="string"?Ee.confirm:void 0})),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/preview-definitions"){let Y=K.searchParams.get("projectId");if(!Y)throw new i("validation_error","projectId is required.",422);t.authorize(ne,"project:read",{type:"project",id:Y}),me=yn(o.previews.listDefinitions(Y).map((be)=>({...be})),K,X)}else if(z.method==="POST"&&K.pathname==="/api/v1/preview-definitions"){let Y=await He();t.authorize(ne,"config:write",{type:"resource",id:String(Y.resourceId??"")}),me={definition:o.previews.createDefinition({...Y,projectId:String(Y.projectId??""),resourceId:String(Y.resourceId??""),baseEnvironmentId:String(Y.baseEnvironmentId??""),domainPattern:String(Y.domainPattern??""),createdByActorId:ne.actor.id}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/previews"){let Y=await He(),be=o.previews.getDefinition(String(Y.definitionId??""));if(!be)throw new i("not_found","Preview definition was not found.",404);t.authorize(ne,"deployments:create",{type:"resource",id:be.resourceId});let Ee=o.previews.upsert({definitionId:be.id,sourceProvider:"api",repository:typeof Y.repository==="string"?Y.repository:"api",branch:String(Y.branch??""),pullRequestNumber:Number(Y.pullRequestNumber)||void 0,fork:Y.fork===!0,commitSha:String(Y.commitSha??""),createdByActorId:ne.actor.id});me={preview:Ee.preview,operation:t.operation(o.enqueueDeploy(Ee.preview,{created:Ee.created,actorId:ne.actor.id})),requestId:X}}else if(z.method==="POST"&&st){let Y=o.previews.getInstance(decodeURIComponent(st[1]));if(!Y)throw new i("not_found","Preview was not found.",404);let be=await He(),Ee=st[2];if(Ee==="destroy"){if(t.authorize(ne,"deployments:cancel",{type:"resource",id:Y.resourceId}),be.confirm!==Y.name)throw new i("confirmation_required",`Type ${Y.name} to confirm preview teardown.`,409);me={operation:t.operation(o.enqueueDestroy(Y,"api",ne.actor.id)),requestId:X}}else if(Ee==="extend")t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={preview:o.previews.extend(Y.id,Number(be.hours)),requestId:X};else t.authorize(ne,"deployments:create",{type:"resource",id:Y.resourceId}),me={operation:t.operation(o.enqueueDeploy(Y,{actorId:ne.actor.id,reason:"manual_rebuild"})),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/previews/cleanup"){t.authorize(ne,"automation:manage",{type:"organization"});let Y=await He();if(!Y.dryRun&&Y.confirm!=="cleanup previews")throw new i("confirmation_required","Type cleanup previews to confirm preview cleanup.",409);me={...o.cleanup({dryRun:Y.dryRun===!0,maxAgeHours:Number(Y.maxAgeHours)||void 0,keepCount:Number(Y.keepCount)||void 0,actorId:ne.actor.id}),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/queue"){let Y=K.searchParams.get("projectId")??void 0,be=K.searchParams.get("state"),Ee=r.list({projectId:Y,state:["queued","running","succeeded","failed","cancelled","timed_out"].includes(be)?be:void 0,limit:500}).filter((Ne)=>{let It=Ne.operation.resourceId?{type:"resource",id:Ne.operation.resourceId}:Ne.operation.environmentId?{type:"environment",id:Ne.operation.environmentId}:Ne.operation.projectId?{type:"project",id:Ne.operation.projectId}:{type:"organization"};try{return t.authorize(ne,"deployments:read",It),!0}catch{return!1}}).map((Ne)=>({...t.operation(Ne.operation),queue:Ne.job,approximatePosition:Ne.approximatePosition}));me=yn(Ee,K,X)}else if(z.method==="GET"&&K.pathname==="/api/v1/queue/settings")t.authorize(ne,"deployments:read",ne.token.scope),me={concurrency:r.limits,requestId:X};else if(z.method==="PATCH"&&K.pathname==="/api/v1/queue/settings"){t.authorize(ne,"automation:manage",{type:"organization"});let Y=await He();if(Y.confirm!=="update queue limits")throw new i("confirmation_required","Type update queue limits to confirm production concurrency changes.",409);me={concurrency:r.configureConcurrency(Y.concurrency??{},{organizationId:ne.serviceAccount.organizationId,actorId:ne.actor.id}),requestId:X}}else if(z.method==="DELETE"&&K.pathname==="/api/v1/queue/history"){t.authorize(ne,"automation:manage",{type:"organization"});let Y=await He();if(Y.confirm!=="clear completed")throw new i("confirmation_required","Type clear completed to confirm queue retention cleanup.",409);me={deleted:r.clearCompleted({before:typeof Y.before==="string"?Y.before:void 0,actorId:ne.actor.id,projectId:typeof Y.projectId==="string"?Y.projectId:void 0}),requestId:X}}else if(z.method==="GET"&&wt){let Y=e.controlPlane.getOperation(decodeURIComponent(wt[1]));if(!Y)throw new i("not_found","Operation was not found.",404);let be=Y.resourceId?{type:"resource",id:Y.resourceId}:Y.environmentId?{type:"environment",id:Y.environmentId}:Y.projectId?{type:"project",id:Y.projectId}:{type:"organization"};t.authorize(ne,"deployments:read",be);let Ee=z.headers.get("last-event-id")?.trim(),Ne=Number(Ee||K.searchParams.get("after")||0);if(wt[2]==="stream"){let Ut=new TextEncoder,Le=Ne,Ct,bt=!1,rt=new ReadableStream({start(ln){let Qs=()=>{if(bt)return;if(!e.identities.verifyToken(ye,H)){if(bt=!0,Ct)clearInterval(Ct);ln.close();return}let Zn=r.logs(Y.id,{after:Le,limit:500});for(let lr of Zn)Le=lr.sequence,ln.enqueue(Ut.encode(`id: ${lr.sequence}
48
48
  event: log
49
49
  data: ${JSON.stringify(lr)}
50
50
 
51
- `));let nr=e.controlPlane.getOperation(Y.id);if(nr&&["succeeded","failed","cancelled","timed_out"].includes(nr.state)&&!r.logs(Y.id,{after:Fe,limit:1}).length){if(bt=!0,Ct)clearInterval(Ct);ln.enqueue(Ut.encode(`event: complete
52
- data: ${JSON.stringify({state:nr.state,cursor:Fe})}
51
+ `));let nr=e.controlPlane.getOperation(Y.id);if(nr&&["succeeded","failed","cancelled","timed_out"].includes(nr.state)&&!r.logs(Y.id,{after:Le,limit:1}).length){if(bt=!0,Ct)clearInterval(Ct);ln.enqueue(Ut.encode(`event: complete
52
+ data: ${JSON.stringify({state:nr.state,cursor:Le})}
53
53
 
54
- `)),ln.close()}};if(Qs(),!bt)Ct=setInterval(Qs,500);z.signal.addEventListener("abort",()=>{if(bt=!0,Ct)clearInterval(Ct);try{ln.close()}catch{}},{once:!0})},cancel(){if(bt=!0,Ct)clearInterval(Ct)}});return new Response(rt,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no","x-request-id":X,...Ue}})}let It=r.logs(Y.id,{after:Be,limit:Number(K.searchParams.get("limit"))||void 0});me={data:It,cursor:It.at(-1)?.sequence??Be,hasMore:It.length>=Math.min(1000,Math.max(1,Number(K.searchParams.get("limit"))||200)),requestId:X}}else if(z.method==="POST"&&cr){let Y=e.controlPlane.getOperation(decodeURIComponent(cr[1]));if(!Y)throw new i("not_found","Operation was not found.",404);let be=Y.resourceId?{type:"resource",id:Y.resourceId}:Y.environmentId?{type:"environment",id:Y.environmentId}:Y.projectId?{type:"project",id:Y.projectId}:{type:"organization"},Ee=await We();if(cr[2]==="cancel")t.authorize(ne,"deployments:cancel",be),me={operation:t.operation(r.requestCancellation(Y.id,ne.actor.id)),requestId:X};else t.authorize(ne,"deployments:create",be),me={operation:t.operation(r.retry(Y.id,String(Ee.errorClass??"manual"),{delayMs:Number(Ee.delayMs)||0,actorId:ne.actor.id})),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/source/connections"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:read",ne.token.scope),me=yn(e.sources.listConnections(ne.serviceAccount.organizationId),K,X,["createdAt","id"])}else if(z.method==="GET"&&K.pathname==="/api/v1/source/repositories"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:read",ne.token.scope);let Y=e.sources.getConnection(K.searchParams.get("connectionId")??"");if(!Y||Y.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);if(K.searchParams.get("sync")==="true")t.authorize(ne,"sources:manage",{type:"organization"}),await Ti(e.sources,Y.id,{search:K.searchParams.get("search")??void 0});me=yn(e.sources.listRepositories(Y.id,K.searchParams.get("search")??void 0),K,X,["fullName","id"])}else if(z.method==="GET"&&K.pathname==="/api/v1/source/refs"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:read",ne.token.scope);let Y=K.searchParams.get("connectionId")??"",be=e.sources.getConnection(Y);if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);me=await wi(e.sources,{connectionId:Y,repository:K.searchParams.get("repository")??"",repositoryId:K.searchParams.get("repositoryId")??void 0,type:K.searchParams.get("type")==="tags"?"tags":"branches",cursor:K.searchParams.get("cursor")??void 0,deployKeyId:K.searchParams.get("deployKeyId")??void 0})}else if(z.method==="POST"&&K.pathname==="/api/v1/application-detections"){t.authorize(ne,"applications:manage",ne.token.scope);let Y=await We();if(!Array.isArray(Y.files)||Y.files.length>1e4)throw new i("validation_error","files must contain at most 10,000 entries.",422);me={candidates:va(Y.files.map((be)=>({path:String(be.path??""),size:Number(be.size??0),content:typeof be.content==="string"?be.content.slice(0,262144):void 0}))),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/application-plans"){t.authorize(ne,"applications:manage",ne.token.scope);let Y=await We();me={plan:Vn(Y.draft,Array.isArray(Y.suppliedSecretNames)?Y.suppliedSecretNames.map(String):[]),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=K.searchParams.get("projectId")??"";t.authorize(ne,"applications:read",{type:"project",id:Y}),me=yn(e.applications.drafts.list(Y),K,X,["updatedAt","id"])}else if(z.method==="POST"&&K.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=await We(),be=String(Y.projectId??Y.draft?.projectId??"");t.authorize(ne,"applications:manage",{type:"project",id:be});let Ee=e.controlPlane.getProject(be);if(!Ee||Ee.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Project was not found.",404);let Be=e.applications.drafts.create({organizationId:Ee.organizationId,projectId:be,name:String(Y.name??Y.draft?.name??"Application draft"),draft:{...Y.draft,projectId:be},step:Y.step,suppliedSecretNames:Array.isArray(Y.suppliedSecretNames)?Y.suppliedSecretNames.map(String):[],actorId:ne.actor.id});return N({draft:Be,requestId:X},201,X,Ue)}else if(z.method==="PATCH"&&K.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=await We(),be=e.applications.drafts.get(String(Y.id??""));if(!be)throw new i("not_found","Application draft was not found.",404);t.authorize(ne,"applications:manage",{type:"project",id:be.projectId}),me={draft:e.applications.drafts.update(be.id,Number(Y.version),{draft:{...Y.draft,projectId:be.projectId},step:Y.step,suppliedSecretNames:Array.isArray(Y.suppliedSecretNames)?Y.suppliedSecretNames.map(String):void 0,actorId:ne.actor.id}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/applications"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=z.headers.get("idempotency-key")??"";if(!Y)throw new i("idempotency_required","Idempotency-Key is required for application creation.",428);if(!/^[A-Za-z0-9._:-]{8,128}$/.test(Y))throw new i("validation_error","Idempotency-Key must contain 8-128 safe characters.",422);let be=await We(),Ee=e.applications.drafts.get(String(be.draftId??""));if(!Ee)throw new i("not_found","Application draft was not found.",404);t.authorize(ne,"applications:manage",{type:"project",id:Ee.projectId});let Be=$k("sha256").update(`POST
54
+ `)),ln.close()}};if(Qs(),!bt)Ct=setInterval(Qs,500);z.signal.addEventListener("abort",()=>{if(bt=!0,Ct)clearInterval(Ct);try{ln.close()}catch{}},{once:!0})},cancel(){if(bt=!0,Ct)clearInterval(Ct)}});return new Response(rt,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no","x-request-id":X,...Ue}})}let It=r.logs(Y.id,{after:Ne,limit:Number(K.searchParams.get("limit"))||void 0});me={data:It,cursor:It.at(-1)?.sequence??Ne,hasMore:It.length>=Math.min(1000,Math.max(1,Number(K.searchParams.get("limit"))||200)),requestId:X}}else if(z.method==="POST"&&cr){let Y=e.controlPlane.getOperation(decodeURIComponent(cr[1]));if(!Y)throw new i("not_found","Operation was not found.",404);let be=Y.resourceId?{type:"resource",id:Y.resourceId}:Y.environmentId?{type:"environment",id:Y.environmentId}:Y.projectId?{type:"project",id:Y.projectId}:{type:"organization"},Ee=await He();if(cr[2]==="cancel")t.authorize(ne,"deployments:cancel",be),me={operation:t.operation(r.requestCancellation(Y.id,ne.actor.id)),requestId:X};else t.authorize(ne,"deployments:create",be),me={operation:t.operation(r.retry(Y.id,String(Ee.errorClass??"manual"),{delayMs:Number(Ee.delayMs)||0,actorId:ne.actor.id})),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/source/connections"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:read",ne.token.scope),me=yn(e.sources.listConnections(ne.serviceAccount.organizationId),K,X,["createdAt","id"])}else if(z.method==="GET"&&K.pathname==="/api/v1/source/repositories"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:read",ne.token.scope);let Y=e.sources.getConnection(K.searchParams.get("connectionId")??"");if(!Y||Y.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);if(K.searchParams.get("sync")==="true")t.authorize(ne,"sources:manage",{type:"organization"}),await Ti(e.sources,Y.id,{search:K.searchParams.get("search")??void 0});me=yn(e.sources.listRepositories(Y.id,K.searchParams.get("search")??void 0),K,X,["fullName","id"])}else if(z.method==="GET"&&K.pathname==="/api/v1/source/refs"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:read",ne.token.scope);let Y=K.searchParams.get("connectionId")??"",be=e.sources.getConnection(Y);if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);me=await wi(e.sources,{connectionId:Y,repository:K.searchParams.get("repository")??"",repositoryId:K.searchParams.get("repositoryId")??void 0,type:K.searchParams.get("type")==="tags"?"tags":"branches",cursor:K.searchParams.get("cursor")??void 0,deployKeyId:K.searchParams.get("deployKeyId")??void 0})}else if(z.method==="POST"&&K.pathname==="/api/v1/application-detections"){t.authorize(ne,"applications:manage",ne.token.scope);let Y=await He();if(!Array.isArray(Y.files)||Y.files.length>1e4)throw new i("validation_error","files must contain at most 10,000 entries.",422);me={candidates:va(Y.files.map((be)=>({path:String(be.path??""),size:Number(be.size??0),content:typeof be.content==="string"?be.content.slice(0,262144):void 0}))),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/application-plans"){t.authorize(ne,"applications:manage",ne.token.scope);let Y=await He();me={plan:Vn(Y.draft,Array.isArray(Y.suppliedSecretNames)?Y.suppliedSecretNames.map(String):[]),requestId:X}}else if(z.method==="GET"&&K.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=K.searchParams.get("projectId")??"";t.authorize(ne,"applications:read",{type:"project",id:Y}),me=yn(e.applications.drafts.list(Y),K,X,["updatedAt","id"])}else if(z.method==="POST"&&K.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=await He(),be=String(Y.projectId??Y.draft?.projectId??"");t.authorize(ne,"applications:manage",{type:"project",id:be});let Ee=e.controlPlane.getProject(be);if(!Ee||Ee.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Project was not found.",404);let Ne=e.applications.drafts.create({organizationId:Ee.organizationId,projectId:be,name:String(Y.name??Y.draft?.name??"Application draft"),draft:{...Y.draft,projectId:be},step:Y.step,suppliedSecretNames:Array.isArray(Y.suppliedSecretNames)?Y.suppliedSecretNames.map(String):[],actorId:ne.actor.id});return N({draft:Ne,requestId:X},201,X,Ue)}else if(z.method==="PATCH"&&K.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=await He(),be=e.applications.drafts.get(String(Y.id??""));if(!be)throw new i("not_found","Application draft was not found.",404);t.authorize(ne,"applications:manage",{type:"project",id:be.projectId}),me={draft:e.applications.drafts.update(be.id,Number(Y.version),{draft:{...Y.draft,projectId:be.projectId},step:Y.step,suppliedSecretNames:Array.isArray(Y.suppliedSecretNames)?Y.suppliedSecretNames.map(String):void 0,actorId:ne.actor.id}),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/applications"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);let Y=z.headers.get("idempotency-key")??"";if(!Y)throw new i("idempotency_required","Idempotency-Key is required for application creation.",428);if(!/^[A-Za-z0-9._:-]{8,128}$/.test(Y))throw new i("validation_error","Idempotency-Key must contain 8-128 safe characters.",422);let be=await He(),Ee=e.applications.drafts.get(String(be.draftId??""));if(!Ee)throw new i("not_found","Application draft was not found.",404);t.authorize(ne,"applications:manage",{type:"project",id:Ee.projectId});let Ne=$k("sha256").update(`POST
55
55
  /api/v1/applications
56
- ${JSON.stringify(be)}`).digest("hex"),It=e.identities.getIdempotency(ne.token.id,Y);if(It){if(It.requestHash!==Be)throw new i("idempotency_conflict","Idempotency-Key was already used for another request.",409);let Fe=It.operationId?e.controlPlane.getOperation(It.operationId):void 0,Ct=Fe?.resourceId?e.controlPlane.getResource(Fe.resourceId):void 0;if(!Fe||!Ct)throw new i("idempotency_unavailable","The original application operation is no longer available.",409);return N({resource:Ct,operation:t.operation(Fe),plan:Vn(Ee.input,Ee.suppliedSecretNames),idempotentReplay:!0,requestId:X},202,X,{...Ue,"idempotent-replayed":"true"})}let Ut=Fc({controlPlane:e.controlPlane,drafts:e.applications.drafts,draftId:Ee.id,expectedVersion:Number(be.version),confirmEnvironment:String(be.confirmEnvironment??""),actorId:ne.actor.id});return e.identities.saveIdempotency({tokenId:ne.token.id,key:Y,requestHash:Be,operationId:Ut.operation.id,responseStatus:202,responseBody:{draftId:Ee.id}}),N({resource:Ut.resource,operation:t.operation(Ut.operation),plan:Ut.plan,idempotentReplay:!1,requestId:X},202,X,Ue)}else if(z.method==="GET"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:read",ne.token.scope),me=yn(e.applications.registries.list(ne.serviceAccount.organizationId),K,X,["createdAt","id"])}else if(z.method==="POST"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:manage",{type:"organization"});let Y=await We(),be=e.applications.registries.create({organizationId:ne.serviceAccount.organizationId,provider:Y.provider,name:String(Y.name??"Container registry"),host:String(Y.host??""),credential:Y.token||Y.password?{username:typeof Y.username==="string"?Y.username:void 0,password:typeof Y.password==="string"?Y.password:void 0,token:typeof Y.token==="string"?Y.token:void 0}:void 0,credentialExpiresAt:typeof Y.credentialExpiresAt==="string"?Y.credentialExpiresAt:void 0,actorId:ne.actor.id});return N({registry:be,requestId:X},201,X,Ue)}else if(z.method==="PATCH"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:manage",{type:"organization"});let Y=await We(),be=e.applications.registries.get(String(Y.id??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Registry connection was not found.",404);if(Y.action==="test")me={registry:await e.applications.registries.test(be.id,{image:typeof Y.image==="string"?Y.image:void 0}),requestId:X};else if(Y.action==="rotate")me={registry:e.applications.registries.rotate(be.id,{username:Y.username,password:Y.password,token:Y.token},{expiresAt:Y.expiresAt,actorId:ne.actor.id}),requestId:X};else throw new i("validation_error","action must be test or rotate.",422)}else if(z.method==="DELETE"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:manage",{type:"organization"});let Y=await We(),be=e.applications.registries.get(String(Y.id??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Registry connection was not found.",404);me={registry:e.applications.registries.disconnect(be.id,ne.actor.id),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/application-artifacts"){if(!e.applications?.artifacts)throw new i("not_found","Application artifact storage is unavailable.",404);let Y=z.headers.get("x-project-id")??"";t.authorize(ne,"applications:manage",{type:"project",id:Y});let be=e.controlPlane.getProject(Y);if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Project was not found.",404);if(Number(z.headers.get("content-length")??0)>104857600)throw new i("payload_too_large","Artifact exceeds 100 MB.",413);let Be=e.applications.artifacts.create({organizationId:be.organizationId,projectId:Y,filename:z.headers.get("x-artifact-filename")??"application.zip",bytes:new Uint8Array(await z.arrayBuffer()),actorId:ne.actor.id});return N({artifact:Be,requestId:X},201,X,Ue)}else if(z.method==="POST"&&K.pathname==="/api/v1/source/connections"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:manage",{type:"organization"});let Y=await We(),be=String(Y.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(be))throw new i("validation_error","A supported provider is required.",422);let Ee=be==="github"&&(Y.privateKey||Y.appId)?{appId:typeof Y.appId==="string"?Y.appId:void 0,installationId:typeof Y.installationId==="string"?Y.installationId:void 0,privateKey:typeof Y.privateKey==="string"?Y.privateKey:void 0}:be!=="generic_ssh"&&Y.token?{token:String(Y.token),username:typeof Y.username==="string"?Y.username:void 0}:void 0,Be,It,Ut;return e.controlPlane.database.transaction(()=>{if(Be=e.sources.createConnection({organizationId:ne.serviceAccount.organizationId,provider:be,name:String(Y.name??be),host:String(Y.host??""),owner:typeof Y.owner==="string"?Y.owner:void 0,authKind:Y.authKind,credential:Ee,createdByActorId:ne.actor.id}),typeof Y.repositoryUrl==="string"&&typeof Y.repositoryFullName==="string")It=e.sources.upsertRepository({connectionId:Be.id,providerRepositoryId:`manual:${Y.repositoryFullName}`,fullName:Y.repositoryFullName,cloneUrl:Y.repositoryUrl,defaultBranch:String(Y.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"api"}});if(be==="generic_ssh")Ut=e.sources.createDeployKey({connectionId:Be.id,name:String(Y.deployKeyName??"Repository deploy key"),publicKey:String(Y.publicKey??""),privateKey:String(Y.deployPrivateKey??""),host:String(Y.sshHost??""),hostKey:String(Y.hostKey??""),actorId:ne.actor.id})})(),N({connection:Be,repository:It,deployKey:Ut,requestId:X},201,X,Ue)}else if(z.method==="POST"&&K.pathname==="/api/v1/source/bindings"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);let Y=await We(),be=String(Y.projectId??"");t.authorize(ne,"sources:manage",{type:"project",id:be});let Ee=e.sources.getConnection(String(Y.connectionId??""));if(!Ee||Ee.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);let Be=e.sources.createBinding({projectId:be,environmentId:typeof Y.environmentId==="string"?Y.environmentId:void 0,resourceId:typeof Y.resourceId==="string"?Y.resourceId:void 0,connectionId:Ee.id,repositoryId:typeof Y.repositoryId==="string"?Y.repositoryId:void 0,repositoryFullName:String(Y.repositoryFullName??""),defaultBranch:String(Y.defaultBranch??"main"),branchRule:typeof Y.branchRule==="string"?Y.branchRule:void 0,tagRule:typeof Y.tagRule==="string"?Y.tagRule:void 0,monorepoRoot:String(Y.monorepoRoot??"."),includePaths:Array.isArray(Y.includePaths)?Y.includePaths.map(String):[],excludePaths:Array.isArray(Y.excludePaths)?Y.excludePaths.map(String):[],submodules:Y.submodules===!0,cloneDepth:typeof Y.cloneDepth==="number"?Y.cloneDepth:void 0,deployKeyId:typeof Y.deployKeyId==="string"&&Y.deployKeyId?Y.deployKeyId:void 0,autoDeploy:Y.autoDeploy!==!1,pullRequestPreviews:Y.pullRequestPreviews!==!1,actorId:ne.actor.id});return N({binding:Be,requestId:X},201,X,Ue)}else if(z.method==="POST"&&K.pathname==="/api/v1/source/webhooks"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:manage",{type:"organization"});let Y=await We(),be=e.sources.getConnection(String(Y.connectionId??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);let Ee=typeof Y.baseUrl==="string"?Y.baseUrl:void 0;if(!Ee)throw new i("validation_error","baseUrl is required.",422);let Be=e.sources.createWebhook({connectionId:be.id,repositoryId:typeof Y.repositoryId==="string"?Y.repositoryId:void 0,repositoryFullName:String(Y.repositoryFullName??""),events:Array.isArray(Y.events)?Y.events.map(String):void 0}),It=Vt(Ee,Be.webhook),Ut=Y.reconcile===!1?Be.webhook:await Mr(e.sources,Be.webhook.id,Ee);return N({webhook:Ut,endpoint:It,endpointRevealOnce:!0,requestId:X},201,X,Ue)}else if(z.method==="DELETE"&&K.pathname==="/api/v1/source/connections"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:manage",{type:"organization"});let Y=await We(),be=e.sources.getConnection(String(Y.id??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);let Ee=e.sources.listBindings({connectionId:be.id,status:"active"});if(Y.preview===!0)return N({preview:!0,affectedBindings:Ee,requestId:X},200,X,Ue);return N({...e.sources.disconnectConnection(be.id,ne.actor.id),requestId:X},200,X,Ue)}else if(z.method==="GET"&&(K.pathname==="/api/v1/events"||K.pathname==="/api/v1/events/stream")){let Y=t.listEvents(ne,K.searchParams.get("projectId")??void 0,Number(K.searchParams.get("after"))||void 0);if(K.pathname.endsWith("/stream")){let be=new TextEncoder,Ee=Y.reduce((Fe,Ct)=>Math.max(Fe,Number(Ct.sequence)),Number(K.searchParams.get("after"))||0),Be,It=!1,Ut=new ReadableStream({start(Fe){let Ct=(bt)=>Fe.enqueue(be.encode(`id: ${bt.sequence}
56
+ ${JSON.stringify(be)}`).digest("hex"),It=e.identities.getIdempotency(ne.token.id,Y);if(It){if(It.requestHash!==Ne)throw new i("idempotency_conflict","Idempotency-Key was already used for another request.",409);let Le=It.operationId?e.controlPlane.getOperation(It.operationId):void 0,Ct=Le?.resourceId?e.controlPlane.getResource(Le.resourceId):void 0;if(!Le||!Ct)throw new i("idempotency_unavailable","The original application operation is no longer available.",409);return N({resource:Ct,operation:t.operation(Le),plan:Vn(Ee.input,Ee.suppliedSecretNames),idempotentReplay:!0,requestId:X},202,X,{...Ue,"idempotent-replayed":"true"})}let Ut=Fc({controlPlane:e.controlPlane,drafts:e.applications.drafts,draftId:Ee.id,expectedVersion:Number(be.version),confirmEnvironment:String(be.confirmEnvironment??""),actorId:ne.actor.id});return e.identities.saveIdempotency({tokenId:ne.token.id,key:Y,requestHash:Ne,operationId:Ut.operation.id,responseStatus:202,responseBody:{draftId:Ee.id}}),N({resource:Ut.resource,operation:t.operation(Ut.operation),plan:Ut.plan,idempotentReplay:!1,requestId:X},202,X,Ue)}else if(z.method==="GET"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:read",ne.token.scope),me=yn(e.applications.registries.list(ne.serviceAccount.organizationId),K,X,["createdAt","id"])}else if(z.method==="POST"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:manage",{type:"organization"});let Y=await He(),be=e.applications.registries.create({organizationId:ne.serviceAccount.organizationId,provider:Y.provider,name:String(Y.name??"Container registry"),host:String(Y.host??""),credential:Y.token||Y.password?{username:typeof Y.username==="string"?Y.username:void 0,password:typeof Y.password==="string"?Y.password:void 0,token:typeof Y.token==="string"?Y.token:void 0}:void 0,credentialExpiresAt:typeof Y.credentialExpiresAt==="string"?Y.credentialExpiresAt:void 0,actorId:ne.actor.id});return N({registry:be,requestId:X},201,X,Ue)}else if(z.method==="PATCH"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:manage",{type:"organization"});let Y=await He(),be=e.applications.registries.get(String(Y.id??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Registry connection was not found.",404);if(Y.action==="test")me={registry:await e.applications.registries.test(be.id,{image:typeof Y.image==="string"?Y.image:void 0}),requestId:X};else if(Y.action==="rotate")me={registry:e.applications.registries.rotate(be.id,{username:Y.username,password:Y.password,token:Y.token},{expiresAt:Y.expiresAt,actorId:ne.actor.id}),requestId:X};else throw new i("validation_error","action must be test or rotate.",422)}else if(z.method==="DELETE"&&K.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new i("not_found","Application onboarding is unavailable.",404);t.authorize(ne,"applications:manage",{type:"organization"});let Y=await He(),be=e.applications.registries.get(String(Y.id??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Registry connection was not found.",404);me={registry:e.applications.registries.disconnect(be.id,ne.actor.id),requestId:X}}else if(z.method==="POST"&&K.pathname==="/api/v1/application-artifacts"){if(!e.applications?.artifacts)throw new i("not_found","Application artifact storage is unavailable.",404);let Y=z.headers.get("x-project-id")??"";t.authorize(ne,"applications:manage",{type:"project",id:Y});let be=e.controlPlane.getProject(Y);if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Project was not found.",404);if(Number(z.headers.get("content-length")??0)>104857600)throw new i("payload_too_large","Artifact exceeds 100 MB.",413);let Ne=e.applications.artifacts.create({organizationId:be.organizationId,projectId:Y,filename:z.headers.get("x-artifact-filename")??"application.zip",bytes:new Uint8Array(await z.arrayBuffer()),actorId:ne.actor.id});return N({artifact:Ne,requestId:X},201,X,Ue)}else if(z.method==="POST"&&K.pathname==="/api/v1/source/connections"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:manage",{type:"organization"});let Y=await He(),be=String(Y.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(be))throw new i("validation_error","A supported provider is required.",422);let Ee=be==="github"&&(Y.privateKey||Y.appId)?{appId:typeof Y.appId==="string"?Y.appId:void 0,installationId:typeof Y.installationId==="string"?Y.installationId:void 0,privateKey:typeof Y.privateKey==="string"?Y.privateKey:void 0}:be!=="generic_ssh"&&Y.token?{token:String(Y.token),username:typeof Y.username==="string"?Y.username:void 0}:void 0,Ne,It,Ut;return e.controlPlane.database.transaction(()=>{if(Ne=e.sources.createConnection({organizationId:ne.serviceAccount.organizationId,provider:be,name:String(Y.name??be),host:String(Y.host??""),owner:typeof Y.owner==="string"?Y.owner:void 0,authKind:Y.authKind,credential:Ee,createdByActorId:ne.actor.id}),typeof Y.repositoryUrl==="string"&&typeof Y.repositoryFullName==="string")It=e.sources.upsertRepository({connectionId:Ne.id,providerRepositoryId:`manual:${Y.repositoryFullName}`,fullName:Y.repositoryFullName,cloneUrl:Y.repositoryUrl,defaultBranch:String(Y.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"api"}});if(be==="generic_ssh")Ut=e.sources.createDeployKey({connectionId:Ne.id,name:String(Y.deployKeyName??"Repository deploy key"),publicKey:String(Y.publicKey??""),privateKey:String(Y.deployPrivateKey??""),host:String(Y.sshHost??""),hostKey:String(Y.hostKey??""),actorId:ne.actor.id})})(),N({connection:Ne,repository:It,deployKey:Ut,requestId:X},201,X,Ue)}else if(z.method==="POST"&&K.pathname==="/api/v1/source/bindings"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);let Y=await He(),be=String(Y.projectId??"");t.authorize(ne,"sources:manage",{type:"project",id:be});let Ee=e.sources.getConnection(String(Y.connectionId??""));if(!Ee||Ee.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);let Ne=e.sources.createBinding({projectId:be,environmentId:typeof Y.environmentId==="string"?Y.environmentId:void 0,resourceId:typeof Y.resourceId==="string"?Y.resourceId:void 0,connectionId:Ee.id,repositoryId:typeof Y.repositoryId==="string"?Y.repositoryId:void 0,repositoryFullName:String(Y.repositoryFullName??""),defaultBranch:String(Y.defaultBranch??"main"),branchRule:typeof Y.branchRule==="string"?Y.branchRule:void 0,tagRule:typeof Y.tagRule==="string"?Y.tagRule:void 0,monorepoRoot:String(Y.monorepoRoot??"."),includePaths:Array.isArray(Y.includePaths)?Y.includePaths.map(String):[],excludePaths:Array.isArray(Y.excludePaths)?Y.excludePaths.map(String):[],submodules:Y.submodules===!0,cloneDepth:typeof Y.cloneDepth==="number"?Y.cloneDepth:void 0,deployKeyId:typeof Y.deployKeyId==="string"&&Y.deployKeyId?Y.deployKeyId:void 0,autoDeploy:Y.autoDeploy!==!1,pullRequestPreviews:Y.pullRequestPreviews!==!1,actorId:ne.actor.id});return N({binding:Ne,requestId:X},201,X,Ue)}else if(z.method==="POST"&&K.pathname==="/api/v1/source/webhooks"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:manage",{type:"organization"});let Y=await He(),be=e.sources.getConnection(String(Y.connectionId??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);let Ee=typeof Y.baseUrl==="string"?Y.baseUrl:void 0;if(!Ee)throw new i("validation_error","baseUrl is required.",422);let Ne=e.sources.createWebhook({connectionId:be.id,repositoryId:typeof Y.repositoryId==="string"?Y.repositoryId:void 0,repositoryFullName:String(Y.repositoryFullName??""),events:Array.isArray(Y.events)?Y.events.map(String):void 0}),It=Vt(Ee,Ne.webhook),Ut=Y.reconcile===!1?Ne.webhook:await Mr(e.sources,Ne.webhook.id,Ee);return N({webhook:Ut,endpoint:It,endpointRevealOnce:!0,requestId:X},201,X,Ue)}else if(z.method==="DELETE"&&K.pathname==="/api/v1/source/connections"){if(!e.sources)throw new i("not_found","Source integrations are unavailable.",404);t.authorize(ne,"sources:manage",{type:"organization"});let Y=await He(),be=e.sources.getConnection(String(Y.id??""));if(!be||be.organizationId!==ne.serviceAccount.organizationId)throw new i("not_found","Source connection was not found.",404);let Ee=e.sources.listBindings({connectionId:be.id,status:"active"});if(Y.preview===!0)return N({preview:!0,affectedBindings:Ee,requestId:X},200,X,Ue);return N({...e.sources.disconnectConnection(be.id,ne.actor.id),requestId:X},200,X,Ue)}else if(z.method==="GET"&&(K.pathname==="/api/v1/events"||K.pathname==="/api/v1/events/stream")){let Y=t.listEvents(ne,K.searchParams.get("projectId")??void 0,Number(K.searchParams.get("after"))||void 0);if(K.pathname.endsWith("/stream")){let be=new TextEncoder,Ee=Y.reduce((Le,Ct)=>Math.max(Le,Number(Ct.sequence)),Number(K.searchParams.get("after"))||0),Ne,It=!1,Ut=new ReadableStream({start(Le){let Ct=(bt)=>Le.enqueue(be.encode(`id: ${bt.sequence}
57
57
  event: ${bt.type}
58
58
  data: ${JSON.stringify(bt)}
59
59
 
60
- `));if(Y.length)Y.forEach(Ct);else Fe.enqueue(be.encode(`: connected
60
+ `));if(Y.length)Y.forEach(Ct);else Le.enqueue(be.encode(`: connected
61
61
 
62
- `));Be=setInterval(()=>{if(It)return;let bt=e.identities.verifyToken(ye,H);if(!bt){if(It=!0,Be)clearInterval(Be);Fe.close();return}try{let rt=t.listEvents(bt,K.searchParams.get("projectId")??void 0,Ee);for(let ln of rt)Ct(ln),Ee=Math.max(Ee,Number(ln.sequence));if(!rt.length)Fe.enqueue(be.encode(`: heartbeat ${Date.now()}
62
+ `));Ne=setInterval(()=>{if(It)return;let bt=e.identities.verifyToken(ye,H);if(!bt){if(It=!0,Ne)clearInterval(Ne);Le.close();return}try{let rt=t.listEvents(bt,K.searchParams.get("projectId")??void 0,Ee);for(let ln of rt)Ct(ln),Ee=Math.max(Ee,Number(ln.sequence));if(!rt.length)Le.enqueue(be.encode(`: heartbeat ${Date.now()}
63
63
 
64
- `))}catch{if(It=!0,Be)clearInterval(Be);Fe.close()}},1000),z.signal.addEventListener("abort",()=>{if(It=!0,Be)clearInterval(Be);try{Fe.close()}catch{}},{once:!0})},cancel(){if(It=!0,Be)clearInterval(Be)}});return new Response(Ut,{status:200,headers:{"content-type":"text/event-stream","cache-control":"no-store",connection:"keep-alive","x-accel-buffering":"no","x-request-id":X,...Ue}})}me=yn(Y,K,X,["sequence","id"])}else if(z.method==="POST"&&K.pathname==="/api/v1/deployments"){let Y=z.headers.get("idempotency-key")??"";if(!Y)throw new i("idempotency_required","Idempotency-Key is required for deployment requests.",428);let be=await z.text();if(be.length>1048576)throw new i("payload_too_large","Request body exceeds 1 MB.",413);let Ee;try{Ee=JSON.parse(be)}catch{throw new i("invalid_json","Request body must be valid JSON.",400)}if(!Ee||typeof Ee.projectId!=="string"||typeof Ee.environmentId!=="string"||Ee.action!==void 0&&!["deploy","rollback"].includes(Ee.action))throw new i("validation_error","projectId, environmentId, and a valid action are required.",422);let Be=t.createDeployment(ne,Ee,Y);return N({operation:Be.operation,idempotentReplay:Be.replay,requestId:X},202,X,{...Ue,...Be.replay?{"idempotent-replayed":"true"}:{}})}else{let Y=await Fs({...R,authorization:t,now:E},ne,{method:z.method,url:K,body:We});if(Y===void 0)throw new i("not_found","API resource was not found.",404);me=Y}return N(me,200,X,Ue)}catch(me){if(me instanceof i)return F(me.code,me.message,me.status,X,me.details,Ue);if(K.pathname.startsWith("/api/v1/source/")||K.pathname.startsWith("/api/v1/application")||K.pathname.startsWith("/api/v1/compose-")||K.pathname==="/api/v1/registry-connections")return F("validation_error",me instanceof Error?me.message:"Integration request could not be completed.",422,X,void 0,Ue);return F("internal_error","The API request could not be completed.",500,X,void 0,Ue)}}}import{createCipheriv as Lk,createDecipheriv as Fk,createHash as bh,randomBytes as yi}from"node:crypto";import{createHmac as Mk,timingSafeEqual as Bk}from"node:crypto";var hp="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function Ci(e){let t=0,r=0,o="";for(let m of e){r=r<<8|m,t+=8;while(t>=5)o+=hp[r>>>t-5&31],t-=5}if(t>0)o+=hp[r<<5-t&31];return o}function Rd(e){let t=e.toUpperCase().replace(/[^A-Z2-7]/g,""),r=0,o=0,m=[];for(let h of t){let I=hp.indexOf(h);if(I<0)throw Error("Invalid base32 secret");if(o=o<<5|I,r+=5,r>=8)m.push(o>>>r-8&255),r-=8}return Buffer.from(m)}function lo(e,t,r=6){let o=Buffer.alloc(8);o.writeBigUInt64BE(BigInt(t));let m=Mk("sha1",Rd(e)).update(o).digest(),h=m[m.length-1]&15,I=(m[h]&127)<<24|(m[h+1]&255)<<16|(m[h+2]&255)<<8|m[h+3]&255;return String(I%10**r).padStart(r,"0")}function Vg(e,t=Date.now(),r=30){return lo(e,Math.floor(t/1000/r))}function jg(e,t,r=Date.now(),o=1){return Or(e,t,r,o)!==void 0}function Or(e,t,r=Date.now(),o=1){let m=t.replace(/[\s-]/g,"");if(!/^\d{6}$/.test(m))return;let h=Buffer.from(m),I=Math.floor(r/1000/30);for(let R=-o;R<=o;R++){if(I+R<0)continue;let A=Buffer.from(lo(e,I+R));if(h.length===A.length&&Bk(h,A))return I+R}return}function uo(e){let t=e.issuer?.trim()||"ts-cloud",r=`${t}:${e.account}`;return`otpauth://totp/${encodeURIComponent(r)}?secret=${encodeURIComponent(e.secret)}&issuer=${encodeURIComponent(t)}&algorithm=SHA1&digits=6&period=30`}var Dd=1800000,Ge=43200000,Pd=3600000,Nd=300000,kd=600000;function xn(e){return typeof e==="string"?e:void 0}function Sh(e){if(typeof e!=="string")return{};try{return JSON.parse(e)}catch{return{}}}function zk(e){let t=e.trim();if(!/^[a-z0-9][a-z0-9._-]{1,31}$/i.test(t))throw Error("Username must be 2-32 characters: letters, numbers, dot, dash or underscore");return t}function yp(e){if(e===void 0||!e.trim())return;let t=e.trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)||t.length>254)throw Error("A valid email address is required");return t}function Uk(e){let t=e.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(t))throw Error("OIDC provider slug must be 2-48 lowercase letters, numbers or dashes");return t}function qk(e){let t=new URL(e.trim());if(t.search||t.hash||t.username||t.password)throw Error("OIDC issuer cannot contain credentials, a query, or a fragment");if(t.protocol!=="https:"&&!(t.protocol==="http:"&&["127.0.0.1","::1","localhost"].includes(t.hostname)))throw Error("OIDC issuer must use HTTPS");return t.href.replace(/\/$/,"")}function Vk(e){let t=[...new Set(e.map((r)=>r.trim().toLowerCase()).filter(Boolean))];if(t.length===0)throw Error("At least one explicit OIDC email domain is required");if(t.some((r)=>!/^[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?$/.test(r)||!r.includes(".")||r.includes("..")))throw Error("OIDC email domains must be explicit DNS names without wildcards");return t}function Wk(e){let t=[...new Set(["openid",...e??["email","profile"]].map((r)=>r.trim()).filter(Boolean))];if(t.some((r)=>!/^[\x21\x23-\x5B\x5D-\x7E]+$/.test(r)))throw Error("OIDC scopes contain unsupported characters");return t}function Wn(e){return bh("sha256").update(e).digest("hex")}function sc(e){return{id:String(e.id),actorId:String(e.actor_id),username:String(e.username),email:xn(e.email),emailVerifiedAt:xn(e.email_verified_at),passwordHash:String(e.password_hash),credentialVersion:Number(e.credential_version),requiresPasswordUpgrade:Number(e.requires_password_upgrade)===1,disabledAt:xn(e.disabled_at),lastLoginAt:xn(e.last_login_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function fh(e,t){let r=xn(e.consumed_at),o=String(e.expires_at);return{id:String(e.id),identityId:String(e.identity_id),type:String(e.type),metadata:Sh(e.metadata),expiresAt:o,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":o<=t?"expired":"pending"}}function vp(e,t){let r=xn(e.revoked_at),o=String(e.idle_expires_at),m=String(e.absolute_expires_at);return{id:String(e.id),identityId:String(e.identity_id),credentialVersion:Number(e.credential_version),authMethod:String(e.auth_method),userAgent:xn(e.user_agent),networkHint:xn(e.network_hint),createdAt:String(e.created_at),lastUsedAt:String(e.last_used_at),idleExpiresAt:o,absoluteExpiresAt:m,recentAuthAt:String(e.recent_auth_at),mfaAt:xn(e.mfa_at),revokedAt:r,state:r?"revoked":o<=t||m<=t?"expired":"active"}}function hh(e){let t=xn(e.verified_at),r=xn(e.disabled_at);return{id:String(e.id),identityId:String(e.identity_id),type:"totp",label:String(e.label),createdAt:String(e.created_at),verifiedAt:t,disabledAt:r,state:r?"disabled":t?"active":"pending"}}function bp(e,t){let r=xn(e.consumed_at),o=String(e.expires_at),m=Number(e.attempts);return{id:String(e.id),identityId:String(e.identity_id),purpose:String(e.purpose),attempts:m,expiresAt:o,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":m>=5?"locked":o<=t?"expired":"pending"}}function yh(e){let t=Sh(e);return Array.isArray(t)?t.filter((r)=>typeof r==="string"):[]}function qc(e){return{id:String(e.id),organizationId:String(e.organization_id),slug:String(e.slug),name:String(e.name),issuer:String(e.issuer),clientId:String(e.client_id),hasClientSecret:typeof e.client_secret_ciphertext==="string"&&e.client_secret_ciphertext.length>0,scopes:yh(e.scopes),allowedDomains:yh(e.allowed_domains),defaultRole:String(e.default_role),enabled:Number(e.enabled)===1,enforceSso:Number(e.enforce_sso)===1,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function vh(e,t){let r=xn(e.consumed_at),o=String(e.expires_at);return{id:String(e.id),providerId:String(e.provider_id),redirectUri:String(e.redirect_uri),returnPath:String(e.return_path),expiresAt:o,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":o<=t?"expired":"pending"}}function Hk(e){return{id:String(e.id),providerId:String(e.provider_id),identityId:String(e.identity_id),subject:String(e.subject),email:String(e.email),linkedAt:String(e.linked_at),lastLoginAt:String(e.last_login_at)}}class bi{controlPlane;nowFn;idFn;encryptionKey;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID()),this.encryptionKey=t.encryptionKey?bh("sha256").update(t.encryptionKey).digest():void 0}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}encrypt(e){if(!this.encryptionKey)throw Error("Authentication encryption key is not configured");let t=yi(12),r=Lk("aes-256-gcm",this.encryptionKey,t),o=Buffer.concat([r.update(e,"utf8"),r.final()]);return`v1.${t.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${o.toString("base64url")}`}decrypt(e){if(!this.encryptionKey)throw Error("Authentication encryption key is not configured");let[t,r,o,m]=e.split(".");if(t!=="v1"||!r||!o||!m)throw Error("Encrypted authentication value is unavailable");let h=Fk("aes-256-gcm",this.encryptionKey,Buffer.from(r,"base64url"));return h.setAuthTag(Buffer.from(o,"base64url")),Buffer.concat([h.update(Buffer.from(m,"base64url")),h.final()]).toString("utf8")}createIdentity(e){if(!this.controlPlane.getActor(e.actorId))throw Error("Authentication actor was not found");let t=zk(e.username),r=yp(e.email),o=e.id??this.idFn(),m=this.now();return this.run(`INSERT INTO auth_identities (id, actor_id, username, email, email_verified_at, password_hash, requires_password_upgrade, created_at, updated_at)
64
+ `))}catch{if(It=!0,Ne)clearInterval(Ne);Le.close()}},1000),z.signal.addEventListener("abort",()=>{if(It=!0,Ne)clearInterval(Ne);try{Le.close()}catch{}},{once:!0})},cancel(){if(It=!0,Ne)clearInterval(Ne)}});return new Response(Ut,{status:200,headers:{"content-type":"text/event-stream","cache-control":"no-store",connection:"keep-alive","x-accel-buffering":"no","x-request-id":X,...Ue}})}me=yn(Y,K,X,["sequence","id"])}else if(z.method==="POST"&&K.pathname==="/api/v1/deployments"){let Y=z.headers.get("idempotency-key")??"";if(!Y)throw new i("idempotency_required","Idempotency-Key is required for deployment requests.",428);let be=await z.text();if(be.length>1048576)throw new i("payload_too_large","Request body exceeds 1 MB.",413);let Ee;try{Ee=JSON.parse(be)}catch{throw new i("invalid_json","Request body must be valid JSON.",400)}if(!Ee||typeof Ee.projectId!=="string"||typeof Ee.environmentId!=="string"||Ee.action!==void 0&&!["deploy","rollback"].includes(Ee.action))throw new i("validation_error","projectId, environmentId, and a valid action are required.",422);let Ne=t.createDeployment(ne,Ee,Y);return N({operation:Ne.operation,idempotentReplay:Ne.replay,requestId:X},202,X,{...Ue,...Ne.replay?{"idempotent-replayed":"true"}:{}})}else{let Y=await Fs({...R,authorization:t,now:E},ne,{method:z.method,url:K,body:He});if(Y===void 0)throw new i("not_found","API resource was not found.",404);me=Y}return N(me,200,X,Ue)}catch(me){if(me instanceof i)return F(me.code,me.message,me.status,X,me.details,Ue);if(K.pathname.startsWith("/api/v1/source/")||K.pathname.startsWith("/api/v1/application")||K.pathname.startsWith("/api/v1/compose-")||K.pathname==="/api/v1/registry-connections")return F("validation_error",me instanceof Error?me.message:"Integration request could not be completed.",422,X,void 0,Ue);return F("internal_error","The API request could not be completed.",500,X,void 0,Ue)}}}import{createCipheriv as Lk,createDecipheriv as Fk,createHash as bh,randomBytes as yi}from"node:crypto";import{createHmac as Mk,timingSafeEqual as Bk}from"node:crypto";var hp="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function Ci(e){let t=0,r=0,o="";for(let m of e){r=r<<8|m,t+=8;while(t>=5)o+=hp[r>>>t-5&31],t-=5}if(t>0)o+=hp[r<<5-t&31];return o}function Rd(e){let t=e.toUpperCase().replace(/[^A-Z2-7]/g,""),r=0,o=0,m=[];for(let h of t){let I=hp.indexOf(h);if(I<0)throw Error("Invalid base32 secret");if(o=o<<5|I,r+=5,r>=8)m.push(o>>>r-8&255),r-=8}return Buffer.from(m)}function lo(e,t,r=6){let o=Buffer.alloc(8);o.writeBigUInt64BE(BigInt(t));let m=Mk("sha1",Rd(e)).update(o).digest(),h=m[m.length-1]&15,I=(m[h]&127)<<24|(m[h+1]&255)<<16|(m[h+2]&255)<<8|m[h+3]&255;return String(I%10**r).padStart(r,"0")}function Vg(e,t=Date.now(),r=30){return lo(e,Math.floor(t/1000/r))}function jg(e,t,r=Date.now(),o=1){return Or(e,t,r,o)!==void 0}function Or(e,t,r=Date.now(),o=1){let m=t.replace(/[\s-]/g,"");if(!/^\d{6}$/.test(m))return;let h=Buffer.from(m),I=Math.floor(r/1000/30);for(let R=-o;R<=o;R++){if(I+R<0)continue;let A=Buffer.from(lo(e,I+R));if(h.length===A.length&&Bk(h,A))return I+R}return}function uo(e){let t=e.issuer?.trim()||"ts-cloud",r=`${t}:${e.account}`;return`otpauth://totp/${encodeURIComponent(r)}?secret=${encodeURIComponent(e.secret)}&issuer=${encodeURIComponent(t)}&algorithm=SHA1&digits=6&period=30`}var Dd=1800000,qe=43200000,Pd=3600000,Nd=300000,kd=600000;function xn(e){return typeof e==="string"?e:void 0}function Sh(e){if(typeof e!=="string")return{};try{return JSON.parse(e)}catch{return{}}}function zk(e){let t=e.trim();if(!/^[a-z0-9][a-z0-9._-]{1,31}$/i.test(t))throw Error("Username must be 2-32 characters: letters, numbers, dot, dash or underscore");return t}function yp(e){if(e===void 0||!e.trim())return;let t=e.trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)||t.length>254)throw Error("A valid email address is required");return t}function Uk(e){let t=e.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(t))throw Error("OIDC provider slug must be 2-48 lowercase letters, numbers or dashes");return t}function qk(e){let t=new URL(e.trim());if(t.search||t.hash||t.username||t.password)throw Error("OIDC issuer cannot contain credentials, a query, or a fragment");if(t.protocol!=="https:"&&!(t.protocol==="http:"&&["127.0.0.1","::1","localhost"].includes(t.hostname)))throw Error("OIDC issuer must use HTTPS");return t.href.replace(/\/$/,"")}function Vk(e){let t=[...new Set(e.map((r)=>r.trim().toLowerCase()).filter(Boolean))];if(t.length===0)throw Error("At least one explicit OIDC email domain is required");if(t.some((r)=>!/^[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?$/.test(r)||!r.includes(".")||r.includes("..")))throw Error("OIDC email domains must be explicit DNS names without wildcards");return t}function Wk(e){let t=[...new Set(["openid",...e??["email","profile"]].map((r)=>r.trim()).filter(Boolean))];if(t.some((r)=>!/^[\x21\x23-\x5B\x5D-\x7E]+$/.test(r)))throw Error("OIDC scopes contain unsupported characters");return t}function Wn(e){return bh("sha256").update(e).digest("hex")}function sc(e){return{id:String(e.id),actorId:String(e.actor_id),username:String(e.username),email:xn(e.email),emailVerifiedAt:xn(e.email_verified_at),passwordHash:String(e.password_hash),credentialVersion:Number(e.credential_version),requiresPasswordUpgrade:Number(e.requires_password_upgrade)===1,disabledAt:xn(e.disabled_at),lastLoginAt:xn(e.last_login_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function fh(e,t){let r=xn(e.consumed_at),o=String(e.expires_at);return{id:String(e.id),identityId:String(e.identity_id),type:String(e.type),metadata:Sh(e.metadata),expiresAt:o,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":o<=t?"expired":"pending"}}function vp(e,t){let r=xn(e.revoked_at),o=String(e.idle_expires_at),m=String(e.absolute_expires_at);return{id:String(e.id),identityId:String(e.identity_id),credentialVersion:Number(e.credential_version),authMethod:String(e.auth_method),userAgent:xn(e.user_agent),networkHint:xn(e.network_hint),createdAt:String(e.created_at),lastUsedAt:String(e.last_used_at),idleExpiresAt:o,absoluteExpiresAt:m,recentAuthAt:String(e.recent_auth_at),mfaAt:xn(e.mfa_at),revokedAt:r,state:r?"revoked":o<=t||m<=t?"expired":"active"}}function hh(e){let t=xn(e.verified_at),r=xn(e.disabled_at);return{id:String(e.id),identityId:String(e.identity_id),type:"totp",label:String(e.label),createdAt:String(e.created_at),verifiedAt:t,disabledAt:r,state:r?"disabled":t?"active":"pending"}}function bp(e,t){let r=xn(e.consumed_at),o=String(e.expires_at),m=Number(e.attempts);return{id:String(e.id),identityId:String(e.identity_id),purpose:String(e.purpose),attempts:m,expiresAt:o,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":m>=5?"locked":o<=t?"expired":"pending"}}function yh(e){let t=Sh(e);return Array.isArray(t)?t.filter((r)=>typeof r==="string"):[]}function qc(e){return{id:String(e.id),organizationId:String(e.organization_id),slug:String(e.slug),name:String(e.name),issuer:String(e.issuer),clientId:String(e.client_id),hasClientSecret:typeof e.client_secret_ciphertext==="string"&&e.client_secret_ciphertext.length>0,scopes:yh(e.scopes),allowedDomains:yh(e.allowed_domains),defaultRole:String(e.default_role),enabled:Number(e.enabled)===1,enforceSso:Number(e.enforce_sso)===1,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function vh(e,t){let r=xn(e.consumed_at),o=String(e.expires_at);return{id:String(e.id),providerId:String(e.provider_id),redirectUri:String(e.redirect_uri),returnPath:String(e.return_path),expiresAt:o,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":o<=t?"expired":"pending"}}function Hk(e){return{id:String(e.id),providerId:String(e.provider_id),identityId:String(e.identity_id),subject:String(e.subject),email:String(e.email),linkedAt:String(e.linked_at),lastLoginAt:String(e.last_login_at)}}class bi{controlPlane;nowFn;idFn;encryptionKey;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID()),this.encryptionKey=t.encryptionKey?bh("sha256").update(t.encryptionKey).digest():void 0}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}encrypt(e){if(!this.encryptionKey)throw Error("Authentication encryption key is not configured");let t=yi(12),r=Lk("aes-256-gcm",this.encryptionKey,t),o=Buffer.concat([r.update(e,"utf8"),r.final()]);return`v1.${t.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${o.toString("base64url")}`}decrypt(e){if(!this.encryptionKey)throw Error("Authentication encryption key is not configured");let[t,r,o,m]=e.split(".");if(t!=="v1"||!r||!o||!m)throw Error("Encrypted authentication value is unavailable");let h=Fk("aes-256-gcm",this.encryptionKey,Buffer.from(r,"base64url"));return h.setAuthTag(Buffer.from(o,"base64url")),Buffer.concat([h.update(Buffer.from(m,"base64url")),h.final()]).toString("utf8")}createIdentity(e){if(!this.controlPlane.getActor(e.actorId))throw Error("Authentication actor was not found");let t=zk(e.username),r=yp(e.email),o=e.id??this.idFn(),m=this.now();return this.run(`INSERT INTO auth_identities (id, actor_id, username, email, email_verified_at, password_hash, requires_password_upgrade, created_at, updated_at)
65
65
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[o,e.actorId,t,r??null,e.emailVerified&&r?m:null,e.passwordHash,e.requiresPasswordUpgrade?1:0,m,m]),this.getIdentity(o)}getIdentity(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE id = ?").get(e);return t?sc(t):void 0}getIdentityByActor(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE actor_id = ?").get(e);return t?sc(t):void 0}getIdentityByUsername(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE username = ? COLLATE NOCASE").get(e.trim());return t?sc(t):void 0}getIdentityByEmail(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE email = ? COLLATE NOCASE").get(e.trim().toLowerCase());return t?sc(t):void 0}listIdentities(){return this.controlPlane.database.query("SELECT * FROM auth_identities ORDER BY username COLLATE NOCASE").all().map(sc)}updatePassword(e,t,r={}){if(!this.getIdentity(e))throw Error("Authentication identity was not found");let m=this.now();return this.controlPlane.transaction(()=>{if(this.run(`UPDATE auth_identities SET password_hash = ?, credential_version = credential_version + 1,
66
- requires_password_upgrade = ?, updated_at = ? WHERE id = ?`,[t,r.requiresUpgrade?1:0,m,e]),r.revokeSessions!==!1)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[m,e])}),this.getIdentity(e)}rehashPassword(e,t){let r=this.now();this.run("UPDATE auth_identities SET password_hash = ?, requires_password_upgrade = 0, updated_at = ? WHERE id = ?",[t,r,e]);let o=this.getIdentity(e);if(!o)throw Error("Authentication identity was not found");return o}setVerifiedEmail(e,t){let r=yp(t),o=this.now();this.run("UPDATE auth_identities SET email = ?, email_verified_at = ?, updated_at = ? WHERE id = ?",[r,o,o,e]);let m=this.getIdentity(e);if(!m)throw Error("Authentication identity was not found");return m}recordLogin(e){let t=this.now();this.run("UPDATE auth_identities SET last_login_at = ?, updated_at = ? WHERE id = ?",[t,t,e]);let r=this.getIdentity(e);if(!r)throw Error("Authentication identity was not found");return r}setDisabled(e,t){let r=this.now();this.controlPlane.transaction(()=>{if(this.run("UPDATE auth_identities SET disabled_at = ?, credential_version = credential_version + 1, updated_at = ? WHERE id = ?",[t?r:null,r,e]),t)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[r,e])});let o=this.getIdentity(e);if(!o)throw Error("Authentication identity was not found");return o}createActionToken(e,t,r={}){if(!this.getIdentity(e))throw Error("Authentication identity was not found");let o=yi(32).toString("base64url"),m=this.idFn(),h=this.now(),I=new Date(this.nowFn().getTime()+Math.min(86400000,Math.max(60000,r.ttlMs??Pd))).toISOString();return this.run("INSERT INTO auth_action_tokens (id, identity_id, type, token_hash, metadata, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[m,e,t,Wn(o),JSON.stringify(r.metadata??{}),I,h]),{actionToken:this.getActionToken(m),token:o}}getActionToken(e){let t=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE id = ?").get(e);return t?fh(t,this.now()):void 0}consumeActionToken(e,t){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE token_hash = ? AND type = ?").get(Wn(e),t);if(!r)throw Error("Action token is invalid");let o=fh(r,this.now());if(o.state!=="pending")throw Error(`Action token is ${o.state}`);if(this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),o.id,this.now()]).changes!==1)throw Error("Action token is no longer available");return this.getActionToken(o.id)})}revokeActionTokens(e,t){return this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE identity_id = ? AND type = ? AND consumed_at IS NULL",[this.now(),e,t]).changes}createSession(e){let t=this.getIdentity(e.identityId);if(!t||t.disabledAt)throw Error("Authentication identity is unavailable");let r=this.idFn(),o=yi(32).toString("base64url"),m=`v2.${r}.${o}`,h=this.now(),I=Math.min(86400000,Math.max(60000,e.idleTtlMs??Dd)),R=Math.min(2592000000,Math.max(I,e.absoluteTtlMs??Ge));return this.run(`INSERT INTO auth_sessions (id, identity_id, token_hash, credential_version, auth_method, user_agent, network_hint,
66
+ requires_password_upgrade = ?, updated_at = ? WHERE id = ?`,[t,r.requiresUpgrade?1:0,m,e]),r.revokeSessions!==!1)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[m,e])}),this.getIdentity(e)}rehashPassword(e,t){let r=this.now();this.run("UPDATE auth_identities SET password_hash = ?, requires_password_upgrade = 0, updated_at = ? WHERE id = ?",[t,r,e]);let o=this.getIdentity(e);if(!o)throw Error("Authentication identity was not found");return o}setVerifiedEmail(e,t){let r=yp(t),o=this.now();this.run("UPDATE auth_identities SET email = ?, email_verified_at = ?, updated_at = ? WHERE id = ?",[r,o,o,e]);let m=this.getIdentity(e);if(!m)throw Error("Authentication identity was not found");return m}recordLogin(e){let t=this.now();this.run("UPDATE auth_identities SET last_login_at = ?, updated_at = ? WHERE id = ?",[t,t,e]);let r=this.getIdentity(e);if(!r)throw Error("Authentication identity was not found");return r}setDisabled(e,t){let r=this.now();this.controlPlane.transaction(()=>{if(this.run("UPDATE auth_identities SET disabled_at = ?, credential_version = credential_version + 1, updated_at = ? WHERE id = ?",[t?r:null,r,e]),t)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[r,e])});let o=this.getIdentity(e);if(!o)throw Error("Authentication identity was not found");return o}createActionToken(e,t,r={}){if(!this.getIdentity(e))throw Error("Authentication identity was not found");let o=yi(32).toString("base64url"),m=this.idFn(),h=this.now(),I=new Date(this.nowFn().getTime()+Math.min(86400000,Math.max(60000,r.ttlMs??Pd))).toISOString();return this.run("INSERT INTO auth_action_tokens (id, identity_id, type, token_hash, metadata, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[m,e,t,Wn(o),JSON.stringify(r.metadata??{}),I,h]),{actionToken:this.getActionToken(m),token:o}}getActionToken(e){let t=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE id = ?").get(e);return t?fh(t,this.now()):void 0}consumeActionToken(e,t){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE token_hash = ? AND type = ?").get(Wn(e),t);if(!r)throw Error("Action token is invalid");let o=fh(r,this.now());if(o.state!=="pending")throw Error(`Action token is ${o.state}`);if(this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),o.id,this.now()]).changes!==1)throw Error("Action token is no longer available");return this.getActionToken(o.id)})}revokeActionTokens(e,t){return this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE identity_id = ? AND type = ? AND consumed_at IS NULL",[this.now(),e,t]).changes}createSession(e){let t=this.getIdentity(e.identityId);if(!t||t.disabledAt)throw Error("Authentication identity is unavailable");let r=this.idFn(),o=yi(32).toString("base64url"),m=`v2.${r}.${o}`,h=this.now(),I=Math.min(86400000,Math.max(60000,e.idleTtlMs??Dd)),R=Math.min(2592000000,Math.max(I,e.absoluteTtlMs??qe));return this.run(`INSERT INTO auth_sessions (id, identity_id, token_hash, credential_version, auth_method, user_agent, network_hint,
67
67
  created_at, last_used_at, idle_expires_at, absolute_expires_at, recent_auth_at, mfa_at)
68
68
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,t.id,Wn(m),t.credentialVersion,e.authMethod??"local",e.userAgent?.slice(0,256)??null,e.networkHint?.slice(0,128)??null,h,h,new Date(this.nowFn().getTime()+I).toISOString(),new Date(this.nowFn().getTime()+R).toISOString(),e.recentAuthAt??h,e.mfaAt??null]),{session:this.getSession(r),token:m}}getSession(e){let t=this.controlPlane.database.query("SELECT * FROM auth_sessions WHERE id = ?").get(e);return t?vp(t,this.now()):void 0}verifySessionToken(e){let t=/^v2\.([^.]+)\.[A-Za-z0-9_-]{40,}$/.exec(e);if(!t)return;let r=this.controlPlane.database.query("SELECT * FROM auth_sessions WHERE id = ? AND token_hash = ?").get(t[1],Wn(e));if(!r)return;let o=vp(r,this.now()),m=this.getIdentity(o.identityId);if(!m||m.disabledAt||o.state!=="active"||o.credentialVersion!==m.credentialVersion)return;let h=this.now(),I=new Date(r.idle_expires_at).getTime()-new Date(r.last_used_at).getTime();return this.run("UPDATE auth_sessions SET last_used_at = ?, idle_expires_at = ? WHERE id = ?",[h,new Date(Math.min(this.nowFn().getTime()+I,new Date(o.absoluteExpiresAt).getTime())).toISOString(),o.id]),{identity:m,session:this.getSession(o.id)}}listSessions(e,t={}){let r=this.controlPlane.database.query("SELECT * FROM auth_sessions WHERE identity_id = ? ORDER BY last_used_at DESC").all(e).map((o)=>vp(o,this.now()));return t.includeInactive?r:r.filter((o)=>o.state==="active")}revokeSession(e,t){return this.controlPlane.database.run("UPDATE auth_sessions SET revoked_at = ? WHERE id = ? AND identity_id = ? AND revoked_at IS NULL",[this.now(),t,e]).changes===1}revokeOtherSessions(e,t){return this.controlPlane.database.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND id != ? AND revoked_at IS NULL",[this.now(),e,t]).changes}getMfaFactor(e){let t=this.controlPlane.database.query("SELECT * FROM auth_mfa_factors WHERE identity_id = ?").get(e);return t?hh(t):void 0}beginTotpEnrollment(e,t={}){let r=this.getIdentity(e);if(!r)throw Error("Authentication identity was not found");let o=this.getMfaFactor(e);if(o?.state==="active")throw Error("MFA is already enabled");let m=Ci(yi(20)),h=t.label?.trim().slice(0,80)||r.email||r.username,I=o?.id??this.idFn(),R=this.now();return this.controlPlane.transaction(()=>{if(o)this.run("UPDATE auth_mfa_factors SET label = ?, secret_ciphertext = ?, created_at = ?, verified_at = NULL, disabled_at = NULL WHERE id = ?",[h,this.encrypt(m),R,I]);else this.run("INSERT INTO auth_mfa_factors (id, identity_id, label, secret_ciphertext, created_at) VALUES (?, ?, ?, ?, ?)",[I,e,h,this.encrypt(m),R]);this.run("DELETE FROM auth_recovery_codes WHERE identity_id = ?",[e])}),{factor:this.getMfaFactor(e),secret:m,uri:uo({secret:m,account:h,issuer:t.issuer})}}verifyTotpEnrollment(e,t){let r=this.controlPlane.database.query("SELECT * FROM auth_mfa_factors WHERE identity_id = ?").get(e);if(!r||hh(r).state!=="pending")throw Error("MFA enrollment is not pending");let o=Or(this.decrypt(String(r.secret_ciphertext)),t,this.nowFn().getTime());if(o===void 0)throw Error("Authenticator code is invalid");let m=Array.from({length:10},()=>{let I=Ci(yi(8)).slice(0,12);return`${I.slice(0,4)}-${I.slice(4,8)}-${I.slice(8)}`}),h=this.now();return this.controlPlane.transaction(()=>{this.run("UPDATE auth_mfa_factors SET verified_at = ?, disabled_at = NULL, last_used_step = ? WHERE identity_id = ?",[h,o,e]),this.run("DELETE FROM auth_recovery_codes WHERE identity_id = ?",[e]);for(let I of m)this.run("INSERT INTO auth_recovery_codes (id, identity_id, code_hash, created_at) VALUES (?, ?, ?, ?)",[this.idFn(),e,Wn(`${e}:${I.replace(/-/g,"").toUpperCase()}`),h])}),{factor:this.getMfaFactor(e),recoveryCodes:m}}verifyMfaCode(e,t,r={}){let o=this.controlPlane.database.query("SELECT * FROM auth_mfa_factors WHERE identity_id = ? AND verified_at IS NOT NULL AND disabled_at IS NULL").get(e);if(!o)return{valid:!1};let m=Or(this.decrypt(String(o.secret_ciphertext)),t,this.nowFn().getTime());if(m!==void 0){if(this.controlPlane.database.run("UPDATE auth_mfa_factors SET last_used_step = ? WHERE identity_id = ? AND (last_used_step IS NULL OR last_used_step < ?)",[m,e,m]).changes===1)return{valid:!0,method:"totp"}}let h=t.replace(/[-\s]/g,"").toUpperCase();if(!/^[A-Z2-7]{12}$/.test(h))return{valid:!1};let I=Wn(`${e}:${h}`),R=this.controlPlane.database.query("SELECT * FROM auth_recovery_codes WHERE identity_id = ? AND code_hash = ? AND consumed_at IS NULL").get(e,I);if(!R)return{valid:!1};if(r.consumeRecovery!==!1){if(this.controlPlane.database.run("UPDATE auth_recovery_codes SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL",[this.now(),String(R.id)]).changes!==1)return{valid:!1}}return{valid:!0,method:"recovery"}}remainingRecoveryCodes(e){return Number(this.controlPlane.database.query("SELECT COUNT(*) AS count FROM auth_recovery_codes WHERE identity_id = ? AND consumed_at IS NULL").get(e)?.count??0)}disableMfa(e){let t=this.now();this.controlPlane.transaction(()=>{this.run("UPDATE auth_mfa_factors SET disabled_at = ? WHERE identity_id = ? AND disabled_at IS NULL",[t,e]),this.run("DELETE FROM auth_recovery_codes WHERE identity_id = ?",[e]),this.run("UPDATE auth_mfa_challenges SET consumed_at = ? WHERE identity_id = ? AND consumed_at IS NULL",[t,e])})}createMfaChallenge(e,t){if(this.getMfaFactor(e)?.state!=="active")throw Error("MFA is not enabled");let r=yi(32).toString("base64url"),o=this.idFn(),m=this.now(),h=new Date(this.nowFn().getTime()+Nd).toISOString();return this.controlPlane.transaction(()=>{this.run("UPDATE auth_mfa_challenges SET consumed_at = ? WHERE identity_id = ? AND purpose = ? AND consumed_at IS NULL",[m,e,t]),this.run("INSERT INTO auth_mfa_challenges (id, identity_id, purpose, token_hash, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?)",[o,e,t,Wn(r),h,m])}),{challenge:this.getMfaChallenge(o),token:r}}getMfaChallenge(e){let t=this.controlPlane.database.query("SELECT * FROM auth_mfa_challenges WHERE id = ?").get(e);return t?bp(t,this.now()):void 0}inspectMfaChallengeToken(e,t){let r=this.controlPlane.database.query("SELECT * FROM auth_mfa_challenges WHERE token_hash = ? AND purpose = ?").get(Wn(e),t);return r?bp(r,this.now()):void 0}completeMfaChallenge(e,t,r){let o=this.controlPlane.database.query("SELECT * FROM auth_mfa_challenges WHERE token_hash = ? AND purpose = ?").get(Wn(e),r);if(!o)throw Error("MFA challenge is invalid");let m=bp(o,this.now());if(m.state!=="pending")throw Error(`MFA challenge is ${m.state}`);let h=this.verifyMfaCode(m.identityId,t);if(!h.valid||!h.method)throw this.run("UPDATE auth_mfa_challenges SET attempts = attempts + 1 WHERE id = ?",[m.id]),Error("Authenticator or recovery code is invalid");if(this.controlPlane.database.run("UPDATE auth_mfa_challenges SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND attempts < 5 AND expires_at > ?",[this.now(),m.id,this.now()]).changes!==1)throw Error("MFA challenge is no longer available");return{identity:this.getIdentity(m.identityId),challenge:this.getMfaChallenge(m.id),method:h.method}}markSessionStepUp(e,t=!1){let r=this.now();this.run("UPDATE auth_sessions SET recent_auth_at = ?, mfa_at = CASE WHEN ? = 1 THEN ? ELSE mfa_at END WHERE id = ? AND revoked_at IS NULL",[r,t?1:0,r,e]);let o=this.getSession(e);if(!o)throw Error("Authentication session was not found");return o}isRecentlyAuthenticated(e,t=600000){return this.nowFn().getTime()-new Date(e.recentAuthAt).getTime()<=t}upsertOidcProvider(e){if(!this.controlPlane.getOrganization(e.organizationId))throw Error("OIDC provider organization was not found");let t=Uk(e.slug),r=e.name.trim().slice(0,80);if(!r)throw Error("OIDC provider name is required");let o=qk(e.issuer),m=e.clientId.trim();if(!m||m.length>512)throw Error("OIDC client ID is required");let h=Wk(e.scopes),I=Vk(e.allowedDomains),R=e.id?this.getOidcProvider(e.id):this.getOidcProviderBySlug(t),A=this.now();if(R){if(R.organizationId!==e.organizationId)throw Error("OIDC provider belongs to another organization");return this.run(`UPDATE auth_oidc_providers SET slug = ?, name = ?, issuer = ?, client_id = ?,
69
69
  client_secret_ciphertext = COALESCE(?, client_secret_ciphertext), scopes = ?, allowed_domains = ?,
70
70
  default_role = ?, enabled = ?, enforce_sso = ?, updated_at = ? WHERE id = ?`,[t,r,o,m,e.clientSecret?this.encrypt(e.clientSecret):null,JSON.stringify(h),JSON.stringify(I),e.defaultRole??R.defaultRole,e.enabled??R.enabled?1:0,e.enforceSso??R.enforceSso?1:0,A,R.id]),this.getOidcProvider(R.id)}if(!e.clientSecret)throw Error("OIDC client secret is required for a new provider");let E=e.id??this.idFn();return this.run(`INSERT INTO auth_oidc_providers (id, organization_id, slug, name, issuer, client_id,
71
71
  client_secret_ciphertext, scopes, allowed_domains, default_role, enabled, enforce_sso, created_at, updated_at)
72
72
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[E,e.organizationId,t,r,o,m,this.encrypt(e.clientSecret),JSON.stringify(h),JSON.stringify(I),e.defaultRole??"viewer",e.enabled===!1?0:1,e.enforceSso?1:0,A,A]),this.getOidcProvider(E)}getOidcProvider(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE id = ?").get(e);return t?qc(t):void 0}getOidcProviderBySlug(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE slug = ? COLLATE NOCASE").get(e.trim());return t?qc(t):void 0}listOidcProviders(e,t={}){return(e?this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE organization_id = ? ORDER BY name COLLATE NOCASE").all(e):this.controlPlane.database.query("SELECT * FROM auth_oidc_providers ORDER BY name COLLATE NOCASE").all()).map(qc).filter((o)=>t.includeDisabled||o.enabled)}setOidcProviderEnabled(e,t){let r=this.now();if(this.controlPlane.database.run("UPDATE auth_oidc_providers SET enabled = ?, enforce_sso = CASE WHEN ? = 0 THEN 0 ELSE enforce_sso END, updated_at = ? WHERE id = ?",[t?1:0,t?1:0,r,e]).changes!==1)throw Error("OIDC provider was not found");if(!t)this.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE provider_id = ? AND consumed_at IS NULL",[r,e]);return this.getOidcProvider(e)}getOidcProviderCredentials(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE id = ?").get(e);if(!t||typeof t.client_secret_ciphertext!=="string")throw Error("OIDC provider credentials are unavailable");return{provider:qc(t),clientSecret:this.decrypt(t.client_secret_ciphertext)}}beginOidcTransaction(e,t,r){if(!this.getOidcProvider(e)?.enabled)throw Error("OIDC provider is unavailable");let m=this.idFn(),h=yi(32).toString("base64url"),I=yi(32).toString("base64url"),R=yi(64).toString("base64url"),A=this.now(),E=new Date(this.nowFn().getTime()+kd).toISOString();return this.run(`INSERT INTO auth_oidc_transactions (id, provider_id, state_hash, nonce_ciphertext, verifier_ciphertext,
73
- redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[m,e,Wn(h),this.encrypt(I),this.encrypt(R),t,r,E,A]),{transaction:this.getOidcTransaction(m),state:h,nonce:I,verifier:R}}getOidcTransaction(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE id = ?").get(e);return t?vh(t,this.now()):void 0}consumeOidcTransaction(e,t){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE provider_id = ? AND state_hash = ?").get(e,Wn(t));if(!r)throw Error("OIDC transaction is invalid");let o=vh(r,this.now());if(o.state!=="pending")throw Error(`OIDC transaction is ${o.state}`);if(this.controlPlane.database.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),o.id,this.now()]).changes!==1)throw Error("OIDC transaction is no longer available");return{transaction:this.getOidcTransaction(o.id),nonce:this.decrypt(String(r.nonce_ciphertext)),verifier:this.decrypt(String(r.verifier_ciphertext))}})}getOidcSubject(e,t){let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_subjects WHERE provider_id = ? AND subject = ?").get(e,t);return r?Hk(r):void 0}linkOidcSubject(e,t,r,o){let m=this.getOidcProvider(e),h=this.getIdentity(t);if(!m||!h)throw Error("OIDC provider or identity was not found");let I=yp(o);if(!r.trim()||r.length>512)throw Error("OIDC subject is invalid");let R=this.getOidcSubject(e,r);if(R&&R.identityId!==t)throw Error("OIDC subject is already linked to another identity");let A=this.now();if(R)return this.run("UPDATE auth_oidc_subjects SET email = ?, last_login_at = ? WHERE id = ?",[I,A,R.id]),this.getOidcSubject(e,r);let E=this.idFn();return this.run("INSERT INTO auth_oidc_subjects (id, provider_id, identity_id, subject, email, linked_at, last_login_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[E,e,t,r,I,A,A]),this.getOidcSubject(e,r)}purgeExpired(){let e=this.now(),t=this.controlPlane.database.run("DELETE FROM auth_action_tokens WHERE expires_at < ? OR consumed_at IS NOT NULL",[e]).changes,r=this.controlPlane.database.run("DELETE FROM auth_sessions WHERE revoked_at IS NOT NULL OR idle_expires_at < ? OR absolute_expires_at < ?",[e,e]).changes;return this.controlPlane.database.run("DELETE FROM auth_mfa_challenges WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),this.controlPlane.database.run("DELETE FROM auth_oidc_transactions WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),{actionTokens:t,sessions:r}}}async function Lr(e,t){let r=e.notifications?.email?.from;if(!r)return!1;try{let{EmailClient:o}=await import("./chunk-v46b25w9.js");return await new o({region:e.project.region,defaultFrom:r}).send(t),!0}catch{return!1}}import{randomBytes as Kk}from"node:crypto";import{chmodSync as Jk,existsSync as Gk,mkdirSync as Qk,readFileSync as Yk,writeFileSync as Zk}from"node:fs";import{dirname as Xk}from"node:path";function zg(){return _("auth-encryption-key")}function qe(e){let t=process.env.TS_CLOUD_AUTH_ENCRYPTION_KEY?.trim();if(t)return t;let r=d(e,"auth-encryption-key");try{if(Gk(r)){let m=Yk(r,"utf8").trim();if(m)return m}}catch{}let o=Kk(32).toString("base64url");try{Qk(Xk(r),{recursive:!0,mode:448}),Zk(r,`${o}
73
+ redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[m,e,Wn(h),this.encrypt(I),this.encrypt(R),t,r,E,A]),{transaction:this.getOidcTransaction(m),state:h,nonce:I,verifier:R}}getOidcTransaction(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE id = ?").get(e);return t?vh(t,this.now()):void 0}consumeOidcTransaction(e,t){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE provider_id = ? AND state_hash = ?").get(e,Wn(t));if(!r)throw Error("OIDC transaction is invalid");let o=vh(r,this.now());if(o.state!=="pending")throw Error(`OIDC transaction is ${o.state}`);if(this.controlPlane.database.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),o.id,this.now()]).changes!==1)throw Error("OIDC transaction is no longer available");return{transaction:this.getOidcTransaction(o.id),nonce:this.decrypt(String(r.nonce_ciphertext)),verifier:this.decrypt(String(r.verifier_ciphertext))}})}getOidcSubject(e,t){let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_subjects WHERE provider_id = ? AND subject = ?").get(e,t);return r?Hk(r):void 0}linkOidcSubject(e,t,r,o){let m=this.getOidcProvider(e),h=this.getIdentity(t);if(!m||!h)throw Error("OIDC provider or identity was not found");let I=yp(o);if(!r.trim()||r.length>512)throw Error("OIDC subject is invalid");let R=this.getOidcSubject(e,r);if(R&&R.identityId!==t)throw Error("OIDC subject is already linked to another identity");let A=this.now();if(R)return this.run("UPDATE auth_oidc_subjects SET email = ?, last_login_at = ? WHERE id = ?",[I,A,R.id]),this.getOidcSubject(e,r);let E=this.idFn();return this.run("INSERT INTO auth_oidc_subjects (id, provider_id, identity_id, subject, email, linked_at, last_login_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[E,e,t,r,I,A,A]),this.getOidcSubject(e,r)}purgeExpired(){let e=this.now(),t=this.controlPlane.database.run("DELETE FROM auth_action_tokens WHERE expires_at < ? OR consumed_at IS NOT NULL",[e]).changes,r=this.controlPlane.database.run("DELETE FROM auth_sessions WHERE revoked_at IS NOT NULL OR idle_expires_at < ? OR absolute_expires_at < ?",[e,e]).changes;return this.controlPlane.database.run("DELETE FROM auth_mfa_challenges WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),this.controlPlane.database.run("DELETE FROM auth_oidc_transactions WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),{actionTokens:t,sessions:r}}}async function Lr(e,t){let r=e.notifications?.email?.from;if(!r)return!1;try{let{EmailClient:o}=await import("./chunk-w7710vzg.js");return await new o({region:e.project.region,defaultFrom:r}).send(t),!0}catch{return!1}}import{randomBytes as Kk}from"node:crypto";import{chmodSync as Jk,existsSync as Gk,mkdirSync as Qk,readFileSync as Yk,writeFileSync as Zk}from"node:fs";import{dirname as Xk}from"node:path";function zg(){return _("auth-encryption-key")}function Ve(e){let t=process.env.TS_CLOUD_AUTH_ENCRYPTION_KEY?.trim();if(t)return t;let r=d(e,"auth-encryption-key");try{if(Gk(r)){let m=Yk(r,"utf8").trim();if(m)return m}}catch{}let o=Kk(32).toString("base64url");try{Qk(Xk(r),{recursive:!0,mode:448}),Zk(r,`${o}
74
74
  `,{mode:384}),Jk(r,384)}catch{}return o}import{constants as eI,createHash as Sp,createPublicKey as tI,createVerify as rI,timingSafeEqual as nI}from"node:crypto";var kh=new Set(["RS256","PS256","ES256"]),wh=60;function Vc(e,t){let r=new URL(e),o=["127.0.0.1","::1","localhost"].includes(r.hostname);if(r.protocol!=="https:"&&!(r.protocol==="http:"&&o))throw Error(`${t} must use HTTPS`);if(r.username||r.password||r.hash)throw Error(`${t} contains unsupported URL components`);return r}function wp(e,t){if(!e||typeof e!=="object"||Array.isArray(e))throw Error(`${t} is invalid`);return e}async function kp(e,t){if(!e.ok)throw Error(`${t} failed with HTTP ${e.status}`);if(!(e.headers.get("content-type")??"").toLowerCase().includes("application/json"))throw Error(`${t} returned an unsupported content type`);if(Number(e.headers.get("content-length")??0)>1048576)throw Error(`${t} response is too large`);let m=await e.text();if(m.length>1048576)throw Error(`${t} response is too large`);try{return wp(JSON.parse(m),t)}catch(h){if(h instanceof Error&&h.message===`${t} is invalid`)throw h;throw Error(`${t} returned invalid JSON`)}}function iI(e,t){let r=Sp("sha256").update(e).digest(),o=Sp("sha256").update(t).digest();return nI(r,o)}function Bd(e){if(!e)return"/";let t=e.trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("\\")||/[\r\n]/.test(t))return"/";try{let r=new URL(t,"https://local.invalid");return r.origin==="https://local.invalid"?`${r.pathname}${r.search}${r.hash}`:"/"}catch{return"/"}}async function po(e,t=fetch){let r=Vc(e.issuer,"OIDC issuer"),o=new URL(`${r.pathname.replace(/\/$/,"")}/.well-known/openid-configuration`,r.origin),m=await kp(await t(o,{headers:{accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC discovery");if(m.issuer!==e.issuer)throw Error("OIDC discovery issuer does not match the configured issuer");for(let I of["authorization_endpoint","token_endpoint","jwks_uri"]){if(typeof m[I]!=="string")throw Error(`OIDC discovery is missing ${I}`);Vc(m[I],`OIDC ${I}`)}if(Array.isArray(m.response_types_supported)&&!m.response_types_supported.includes("code"))throw Error("OIDC provider does not support authorization code flow");if(Array.isArray(m.code_challenge_methods_supported)&&!m.code_challenge_methods_supported.includes("S256"))throw Error("OIDC provider does not support PKCE S256");let h=Array.isArray(m.id_token_signing_alg_values_supported)?m.id_token_signing_alg_values_supported.filter((I)=>typeof I==="string"):[];if(h.length>0&&!h.some((I)=>kh.has(I)))throw Error("OIDC provider does not offer a supported ID-token signing algorithm");return m}async function go(e,t,r,o,m=fetch){let h=e.getOidcProviderBySlug(t);if(!h?.enabled)throw Error("OIDC provider is unavailable");let I=Vc(r,"Application origin").origin,R=await po(h,m),A=`${I}/auth/oidc/${encodeURIComponent(h.slug)}/callback`,E=e.beginOidcTransaction(h.id,A,Bd(o)),x=new URL(R.authorization_endpoint);return x.searchParams.set("response_type","code"),x.searchParams.set("client_id",h.clientId),x.searchParams.set("redirect_uri",A),x.searchParams.set("scope",h.scopes.join(" ")),x.searchParams.set("state",E.state),x.searchParams.set("nonce",E.nonce),x.searchParams.set("code_challenge",Sp("sha256").update(E.verifier).digest("base64url")),x.searchParams.set("code_challenge_method","S256"),{authorizationUrl:x.href,expiresAt:E.transaction.expiresAt}}function oI(e){if(e.length>32768)throw Error("OIDC ID token is too large");let t=e.split(".");if(t.length!==3||t.some((r)=>!r))throw Error("OIDC ID token is malformed");try{return{header:wp(JSON.parse(Buffer.from(t[0],"base64url").toString("utf8")),"OIDC ID-token header"),claims:wp(JSON.parse(Buffer.from(t[1],"base64url").toString("utf8")),"OIDC ID-token claims"),signingInput:`${t[0]}.${t[1]}`,signature:Buffer.from(t[2],"base64url")}}catch(r){if(r instanceof Error&&r.message.startsWith("OIDC"))throw r;throw Error("OIDC ID token is malformed")}}async function sI(e,t,r){let o=oI(e),m=typeof o.header.alg==="string"?o.header.alg:"",h=typeof o.header.kid==="string"?o.header.kid:"";if(!kh.has(m)||!h)throw Error("OIDC ID token uses an unsupported signing key");if(t.id_token_signing_alg_values_supported&&!t.id_token_signing_alg_values_supported.includes(m))throw Error("OIDC ID-token algorithm was not advertised by the provider");let I=await kp(await r(t.jwks_uri,{headers:{accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC signing-key request");if(!Array.isArray(I.keys))throw Error("OIDC signing-key response is invalid");let R=I.keys.find((N)=>{if(!N||typeof N!=="object"||Array.isArray(N))return!1;let F=N;return F.kid===h&&(!F.alg||F.alg===m)&&(!F.use||F.use==="sig")});if(!R)throw Error("OIDC ID-token signing key was not found");let A=tI({key:R,format:"jwk"}),E=rI("SHA256").update(o.signingInput).end();if(!(m==="PS256"?E.verify({key:A,padding:eI.RSA_PKCS1_PSS_PADDING,saltLength:32},o.signature):m==="ES256"?E.verify({key:A,dsaEncoding:"ieee-p1363"},o.signature):E.verify(A,o.signature)))throw Error("OIDC ID-token signature is invalid");return o.claims}function aI(e,t,r,o){if(e.iss!==t.issuer)throw Error("OIDC ID-token issuer is invalid");let m=typeof e.aud==="string"?[e.aud]:Array.isArray(e.aud)?e.aud.filter((A)=>typeof A==="string"):[];if(!m.includes(t.clientId))throw Error("OIDC ID-token audience is invalid");if((m.length>1||e.azp!==void 0)&&e.azp!==t.clientId)throw Error("OIDC ID-token authorized party is invalid");let h=Math.floor(o.getTime()/1000);if(typeof e.exp!=="number"||e.exp<h-wh)throw Error("OIDC ID token is expired");if(typeof e.iat!=="number"||e.iat>h+wh)throw Error("OIDC ID-token issued-at time is invalid");if(typeof e.nonce!=="string"||!iI(e.nonce,r))throw Error("OIDC ID-token nonce is invalid");if(typeof e.sub!=="string"||!e.sub||e.sub.length>512)throw Error("OIDC ID-token subject is invalid");if(e.email_verified!==!0||typeof e.email!=="string")throw Error("OIDC provider did not return a verified email address");let I=e.email.trim().toLowerCase();if(I.length>254||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(I))throw Error("OIDC provider returned an invalid email address");let R=I.split("@")[1];if(!R||!t.allowedDomains.includes(R))throw Error("OIDC email domain is not allowed for this organization");return{provider:t,subject:e.sub,email:I,name:typeof e.name==="string"?e.name.slice(0,120):void 0,claims:e}}async function mo(e,t,r=fetch){let o=e.getOidcProviderBySlug(t.providerSlug);if(!o?.enabled)throw Error("OIDC provider is unavailable");if(!t.state||t.state.length>512||!t.code||t.code.length>4096)throw Error("OIDC callback is incomplete");let m=Vc(t.origin,"Application origin").origin,h=e.consumeOidcTransaction(o.id,t.state),I=`${m}/auth/oidc/${encodeURIComponent(o.slug)}/callback`;if(h.transaction.redirectUri!==I)throw Error("OIDC callback redirect URI does not match the original request");let{clientSecret:R}=e.getOidcProviderCredentials(o.id),A=await po(o,r),E=new URLSearchParams({grant_type:"authorization_code",code:t.code,redirect_uri:h.transaction.redirectUri,code_verifier:h.verifier}),x={accept:"application/json","content-type":"application/x-www-form-urlencoded"},N=A.token_endpoint_auth_methods_supported??["client_secret_basic"];if(N.includes("client_secret_basic")){let H=(X)=>new URLSearchParams({value:X}).toString().slice(6),K=`${H(o.clientId)}:${H(R)}`;x.authorization=`Basic ${Buffer.from(K).toString("base64")}`}else if(N.includes("client_secret_post"))E.set("client_id",o.clientId),E.set("client_secret",R);else throw Error("OIDC provider does not support a configured client authentication method");let F=await kp(await r(A.token_endpoint,{method:"POST",headers:x,body:E,redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC token exchange");if(typeof F.id_token!=="string")throw Error("OIDC token response did not include an ID token");let z=await sI(F.id_token,A,r);return{identity:aI(z,o,h.nonce,t.now??new Date),returnPath:h.transaction.returnPath}}import{createHash as cI,randomBytes as dI}from"node:crypto";var Eh=new Set(ae),xd=7776000000,_d=31536000000,Od=86400000;function Si(e){return typeof e==="string"?e:void 0}function Ih(e){return cI("sha256").update(e).digest("hex")}function lI(e){try{let t=JSON.parse(String(e));return Array.isArray(t)?t.filter((r)=>typeof r==="string"&&Eh.has(r)):[]}catch{return[]}}function uI(e){let t=String(e.scope_type);return t==="organization"?{type:t}:{type:t,id:String(e.scope_id)}}function Ip(e){let t=Si(e.disabled_at);return{id:String(e.id),organizationId:String(e.organization_id),actorId:String(e.actor_id),slug:String(e.slug),name:String(e.name),description:Si(e.description),createdByActorId:Si(e.created_by_actor_id),disabledAt:t,createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:t?"disabled":"active"}}function Ep(e,t){let r=Si(e.revoked_at),o=String(e.expires_at);return{id:String(e.id),serviceAccountId:String(e.service_account_id),name:String(e.name),prefix:String(e.token_prefix),capabilities:lI(e.capabilities),scope:uI(e),expiresAt:o,lastUsedAt:Si(e.last_used_at),lastNetworkHint:Si(e.last_network_hint),revokedAt:r,rotatedFromTokenId:Si(e.rotated_from_token_id),createdByActorId:Si(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:r?"revoked":o<=t?"expired":"active"}}function pI(e){let t={};try{t=JSON.parse(String(e.response_body))}catch{}return{id:String(e.id),tokenId:String(e.token_id),key:String(e.idempotency_key),requestHash:String(e.request_hash),operationId:Si(e.operation_id),responseStatus:Number(e.response_status),responseBody:t,expiresAt:String(e.expires_at),createdAt:String(e.created_at)}}class Ei{controlPlane;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}createServiceAccount(e){if(!this.controlPlane.getOrganization(e.organizationId))throw Error("Service-account organization was not found");let t=e.slug.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(t))throw Error("Service-account slug must be 2-48 lowercase letters, numbers or dashes");let r=e.name.trim().slice(0,100);if(!r)throw Error("Service-account name is required");let o=this.controlPlane.createActor({kind:"service_account",externalId:`service-account:${e.organizationId}:${t}`,displayName:r,metadata:{source:"api",serviceAccountSlug:t}}),m=this.idFn(),h=this.now();this.run(`INSERT INTO service_accounts (id, organization_id, actor_id, slug, name, description, created_by_actor_id, created_at, updated_at)
75
75
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[m,e.organizationId,o.id,t,r,e.description?.trim().slice(0,500)||null,e.createdByActorId??null,h,h]);let I=this.controlPlane.createMembership({organizationId:e.organizationId,actorId:o.id,roleTemplate:e.roleTemplate,scope:e.scope,source:"manual",performedByActorId:e.createdByActorId}),R=e.scope??{type:"organization"};return this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.createdByActorId,type:"api.service_account.created",payload:{serviceAccountId:m,roleTemplate:e.roleTemplate,scope:{type:R.type,id:R.id??null}}}),{serviceAccount:this.getServiceAccount(m),membership:I}}getServiceAccount(e){let t=this.controlPlane.database.query("SELECT * FROM service_accounts WHERE id = ?").get(e);return t?Ip(t):void 0}getServiceAccountBySlug(e,t){let r=this.controlPlane.database.query("SELECT * FROM service_accounts WHERE organization_id = ? AND slug = ? COLLATE NOCASE").get(e,t.trim());return r?Ip(r):void 0}listServiceAccounts(e,t={}){return this.controlPlane.database.query("SELECT * FROM service_accounts WHERE organization_id = ? ORDER BY name COLLATE NOCASE").all(e).map(Ip).filter((r)=>t.includeDisabled||r.state==="active")}disableServiceAccount(e,t){let r=this.getServiceAccount(e);if(!r)throw Error("Service account was not found");let o=this.now();return this.controlPlane.transaction(()=>{this.run("UPDATE service_accounts SET disabled_at = ?, updated_at = ? WHERE id = ?",[o,o,e]),this.run("UPDATE api_tokens SET revoked_at = ?, updated_at = ? WHERE service_account_id = ? AND revoked_at IS NULL",[o,o,e]);let m=this.controlPlane.getMembershipForActor(r.organizationId,r.actorId);if(m?.status==="active")this.controlPlane.revokeMembership(m.id)}),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"api.service_account.disabled",payload:{serviceAccountId:e}}),this.getServiceAccount(e)}createToken(e){let t=this.getServiceAccount(e.serviceAccountId);if(!t||t.state!=="active")throw Error("Service account is unavailable");let r=this.controlPlane.getMembershipForActor(t.organizationId,t.actorId);if(!r||r.status!=="active")throw Error("Service-account membership is unavailable");let o=[...new Set(e.capabilities)];if(o.length===0||o.some((F)=>!Eh.has(F)))throw Error("API token requires valid explicit capabilities");let m=e.scope??r.scope,h=this.controlPlane.resolveAuthorizationTarget(t.organizationId,m);if(!h)throw Error("API token scope was not found in this organization");for(let F of o)if(!w({membership:r,grants:this.controlPlane.listGrants(r.id),capability:F,target:h}).allowed)throw Error(`Service-account membership does not grant ${F} at the token scope`);let I=e.expiresAt?new Date(e.expiresAt):new Date(this.nowFn().getTime()+xd);if(!Number.isFinite(I.getTime())||I.getTime()<=this.nowFn().getTime()+60000||I.getTime()>this.nowFn().getTime()+_d)throw Error("API token expiry must be between one minute and one year from now");let R=this.idFn(),A=dI(32).toString("base64url"),E=`tsc_v1.${R}.${A}`,x=`tsc_v1.${R.slice(0,8)}`,N=this.now();return this.run(`INSERT INTO api_tokens (id, service_account_id, name, token_hash, token_prefix, capabilities, scope_type, scope_id,
76
76
  expires_at, rotated_from_token_id, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[R,t.id,e.name.trim().slice(0,100)||"API token",Ih(E),x,JSON.stringify(o.sort()),m.type,m.type==="organization"?null:m.id??null,I.toISOString(),e.rotatedFromTokenId??null,e.createdByActorId??null,N,N]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:e.createdByActorId,type:"api.token.created",payload:{serviceAccountId:t.id,tokenId:R,prefix:x,capabilities:o,scope:{type:m.type,id:m.id??null},expiresAt:I.toISOString(),rotatedFromTokenId:e.rotatedFromTokenId??null}}),{token:this.getToken(R),secret:E}}getToken(e){let t=this.controlPlane.database.query("SELECT * FROM api_tokens WHERE id = ?").get(e);return t?Ep(t,this.now()):void 0}listTokens(e,t={}){return this.controlPlane.database.query("SELECT * FROM api_tokens WHERE service_account_id = ? ORDER BY created_at DESC").all(e).map((r)=>Ep(r,this.now())).filter((r)=>t.includeInactive||r.state==="active")}verifyToken(e,t){let r=/^tsc_v1\.([^.]+)\.[A-Za-z0-9_-]{40,}$/.exec(e);if(!r)return;let o=this.controlPlane.database.query("SELECT * FROM api_tokens WHERE id = ? AND token_hash = ?").get(r[1],Ih(e));if(!o)return;let m=Ep(o,this.now()),h=this.getServiceAccount(m.serviceAccountId);if(!h||h.state!=="active"||m.state!=="active")return;let I=this.controlPlane.getActor(h.actorId),R=this.controlPlane.getMembershipForActor(h.organizationId,h.actorId);if(!I||I.disabledAt||!R||R.status!=="active")return;let A=this.now(),E=!m.lastUsedAt||this.nowFn().getTime()-new Date(m.lastUsedAt).getTime()>=3600000;if(this.run("UPDATE api_tokens SET last_used_at = ?, last_network_hint = ?, updated_at = ? WHERE id = ?",[A,t?.slice(0,128)??null,A,m.id]),E)this.controlPlane.appendEvent({organizationId:h.organizationId,actorId:I.id,type:"api.token.used",payload:{serviceAccountId:h.id,tokenId:m.id,prefix:m.prefix}});return{serviceAccount:h,token:this.getToken(m.id),actor:I,membership:R}}rotateToken(e,t){let r=this.getToken(e);if(!r||r.state!=="active")throw Error("Active API token was not found");let o=this.createToken({serviceAccountId:r.serviceAccountId,name:`${r.name} (rotated)`,capabilities:r.capabilities,scope:r.scope,expiresAt:r.expiresAt,createdByActorId:t,rotatedFromTokenId:r.id}),m=this.getServiceAccount(r.serviceAccountId);return this.controlPlane.appendEvent({organizationId:m?.organizationId,actorId:t,type:"api.token.rotated",payload:{serviceAccountId:r.serviceAccountId,previousTokenId:r.id,tokenId:o.token.id}}),o}revokeToken(e,t){let r=this.getToken(e);if(!r)throw Error("API token was not found");if(r.state==="active"){let o=this.now();this.run("UPDATE api_tokens SET revoked_at = ?, updated_at = ? WHERE id = ?",[o,o,e]);let m=this.getServiceAccount(r.serviceAccountId);this.controlPlane.appendEvent({organizationId:m?.organizationId,actorId:t,type:"api.token.revoked",payload:{serviceAccountId:r.serviceAccountId,tokenId:e}})}return this.getToken(e)}getIdempotency(e,t){let r=this.controlPlane.database.query("SELECT * FROM api_idempotency_records WHERE token_id = ? AND idempotency_key = ? AND expires_at > ?").get(e,t,this.now());return r?pI(r):void 0}saveIdempotency(e){if(!/^[A-Za-z0-9._:-]{8,128}$/.test(e.key))throw Error("Idempotency-Key must contain 8-128 safe characters");let t=this.getIdempotency(e.tokenId,e.key);if(t){if(t.requestHash!==e.requestHash)throw Error("Idempotency-Key was already used for a different request");return t}let r=this.idFn(),o=this.now(),m=new Date(this.nowFn().getTime()+Od).toISOString();return this.run(`INSERT INTO api_idempotency_records (id, token_id, idempotency_key, request_hash, operation_id, response_status, response_body, expires_at, created_at)
77
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,e.tokenId,e.key,e.requestHash,e.operationId??null,e.responseStatus,JSON.stringify(e.responseBody),m,o]),this.getIdempotency(e.tokenId,e.key)}purgeExpired(){let e=this.now(),t=this.controlPlane.database.run("DELETE FROM api_tokens WHERE (expires_at < ? OR revoked_at IS NOT NULL) AND created_at < ?",[e,new Date(this.nowFn().getTime()-2592000000).toISOString()]).changes,r=this.controlPlane.database.run("DELETE FROM api_idempotency_records WHERE expires_at < ?",[e]).changes;return{tokens:t,idempotency:r}}}import{isIP as Th}from"node:net";var mI={every_minute:"* * * * *",every_five_minutes:"*/5 * * * *",hourly:"0 * * * *",daily:"0 0 * * *",weekly:"0 0 * * 0"},gI={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},Rh={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function Ah(e){try{return new Intl.DateTimeFormat("en",{timeZone:e}).format(new Date),e}catch{throw Error(`Unknown schedule timezone: ${e}`)}}function Kc(e,t,r,o){let m=t[e.toUpperCase()]??Number(e);if(!Number.isInteger(m)||m<r||m>o)throw Error(`Schedule field value ${e} is outside ${r}-${o}.`);return m}function Sa(e,t,r,o={},m){if(e==="*"||e==="?")return;let h=new Set;for(let I of e.split(",")){let[R,A]=I.split("/"),E=A?Kc(A,{},1,r-t+1):1,x,N;if(R==="*")x=t,N=r;else if(R.includes("-")){let F=R.split("-");x=Kc(F[0],o,t,r),N=Kc(F[1],o,t,r)}else x=Kc(R,o,t,r),N=x;if(N<x)throw Error("Schedule ranges must be ascending.");for(let F=x;F<=N;F+=E)h.add(m?m(F):F===7&&r===7?0:F)}return h}function fI(e,t){let r=Object.fromEntries(new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"numeric",day:"numeric",weekday:"short",hour:"numeric",minute:"numeric",hourCycle:"h23"}).formatToParts(e).map((o)=>[o.type,o.value]));return{minute:Number(r.minute),hour:Number(r.hour),day:Number(r.day),month:Number(r.month),weekday:Rh[r.weekday.toUpperCase()],year:Number(r.year),key:`${r.year}-${r.month}-${r.day} ${r.hour}:${r.minute}`}}function Ch(e){let r=(e.startsWith("cron(")?e.slice(5,-1).trim():e.trim()).split(/\s+/);if(r.length!==5&&r.length!==6)throw Error("Cron schedules require five standard fields or six EventBridge fields.");let[o,m,h,I,R,A]=r,E=r.length===6;return{minute:Sa(o,0,59),hour:Sa(m,0,23),day:Sa(h,1,31),month:Sa(I,1,12,gI),weekday:Sa(R,E?1:0,7,Rh,E?(x)=>x===7?6:x-1:void 0),year:A?Sa(A,1970,2199):void 0,dayWildcard:h==="*"||h==="?",weekdayWildcard:R==="*"||R==="?"}}function hI(e,t){if(!((!t.minute||t.minute.has(e.minute))&&(!t.hour||t.hour.has(e.hour))&&(!t.month||t.month.has(e.month))&&(!t.year||t.year.has(e.year))))return!1;let o=!t.day||t.day.has(e.day),m=!t.weekday||t.weekday.has(e.weekday);return t.dayWildcard?m:t.weekdayWildcard?o:o||m}function Ph(e){let t=/^rate\(\s*(\d+)\s+(minute|minutes|hour|hours|day|days)\s*\)$/i.exec(e);if(!t)return;let r=Number(t[1]);if(r<1)throw Error("Rate amount must be positive.");return r*(t[2].toLowerCase().startsWith("minute")?60000:t[2].toLowerCase().startsWith("hour")?3600000:86400000)}function je(e){let t=e.trim(),r=mI[t.toLowerCase()]??t;if(!r)throw Error("Schedule expression is required.");let o=Ph(r);if(o){let m=o/60000;return{original:t,normalized:`rate(${m} minutes)`,kind:"rate",description:m%1440===0?`Every ${m/1440} day(s)`:m%60===0?`Every ${m/60} hour(s)`:`Every ${m} minute(s)`}}return Ch(r),{original:t,normalized:r.startsWith("cron(")?r:`cron(${r})`,kind:"cron",description:`Cron ${r.replace(/^cron\(|\)$/g,"")}`}}function mt(e,t,r=new Date,o=5){let m=je(e),h=Ah(t),I=Math.min(20,Math.max(1,o)),R=Ph(m.normalized);if(R)return Array.from({length:I},(z,H)=>new Date(r.getTime()+R*(H+1)).toISOString());let A=Ch(m.normalized),E=[],x=new Set,N=new Date(Math.floor(r.getTime()/60000)*60000+60000),F=0;while(E.length<I&&F<1100000){let z=fI(N,h);if(hI(z,A)&&!x.has(z.key))E.push(N.toISOString()),x.add(z.key);N=new Date(N.getTime()+60000),F++}if(E.length<I)throw Error("Schedule produced no runs within the bounded preview horizon.");return E}function ht(e,t="UTC",r=new Date,o=5){let m=je(e),h=mt(m.normalized,t,r,o),I=m.kind==="cron"?["Server cron and EventBridge use the same wall-clock preview; provider-specific extensions are retained only when supported."]:["Rate schedules use elapsed-time intervals and are not shifted by DST."];return{...m,timezone:Ah(t),nextRuns:h,capabilities:{server:m.kind==="cron",eventbridge:!0,notes:I}}}function Hr(e){let t=je(e.expression),r=t.normalized.slice(5,-1).trim().split(/\s+/),o=t.kind==="cron"&&r.length===5;if(e.provider==="server")return{provider:"server",supported:o,features:{timezone:!0,flexibleWindow:!1,catchUp:!1,replaceOverlap:!1},notes:[t.kind==="rate"?"Server cron requires a cron expression; use an equivalent cron schedule.":r.length!==5?"EventBridge six-field cron extensions cannot be installed as server cron.":"Cron is reconciled through a root-owned ts-cloud entry.",e.missedRunPolicy==="catch_up"?"Catch-up is handled by the control plane, not cron.":"Missed runs are skipped by cron."]};if(e.provider==="eventbridge")return{provider:"eventbridge",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["Five-field cron is translated explicitly to EventBridge six-field syntax. Flexible windows are provider-native; overlap and catch-up remain control-plane policies."]};if(e.provider==="lambda")return{provider:"lambda",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["The schedule invokes one immutable Lambda target."]};return{provider:"platform",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!0,replaceOverlap:!0},notes:["The durable control-plane worker enforces all configured policies."]}}function Ni(e){let t=Hr({...e,provider:"server"});if(!t.supported)throw Error(t.notes.join(" "));let o=je(e.expression).normalized.slice(5,-1);return{path:`/etc/cron.d/ts-cloud-${e.id}`,content:`CRON_TZ=${e.timezone}
77
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,e.tokenId,e.key,e.requestHash,e.operationId??null,e.responseStatus,JSON.stringify(e.responseBody),m,o]),this.getIdempotency(e.tokenId,e.key)}purgeExpired(){let e=this.now(),t=this.controlPlane.database.run("DELETE FROM api_tokens WHERE (expires_at < ? OR revoked_at IS NOT NULL) AND created_at < ?",[e,new Date(this.nowFn().getTime()-2592000000).toISOString()]).changes,r=this.controlPlane.database.run("DELETE FROM api_idempotency_records WHERE expires_at < ?",[e]).changes;return{tokens:t,idempotency:r}}}import{isIP as Th}from"node:net";var mI={every_minute:"* * * * *",every_five_minutes:"*/5 * * * *",hourly:"0 * * * *",daily:"0 0 * * *",weekly:"0 0 * * 0"},gI={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},Rh={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function Ah(e){try{return new Intl.DateTimeFormat("en",{timeZone:e}).format(new Date),e}catch{throw Error(`Unknown schedule timezone: ${e}`)}}function Kc(e,t,r,o){let m=t[e.toUpperCase()]??Number(e);if(!Number.isInteger(m)||m<r||m>o)throw Error(`Schedule field value ${e} is outside ${r}-${o}.`);return m}function Sa(e,t,r,o={},m){if(e==="*"||e==="?")return;let h=new Set;for(let I of e.split(",")){let[R,A]=I.split("/"),E=A?Kc(A,{},1,r-t+1):1,x,N;if(R==="*")x=t,N=r;else if(R.includes("-")){let F=R.split("-");x=Kc(F[0],o,t,r),N=Kc(F[1],o,t,r)}else x=Kc(R,o,t,r),N=x;if(N<x)throw Error("Schedule ranges must be ascending.");for(let F=x;F<=N;F+=E)h.add(m?m(F):F===7&&r===7?0:F)}return h}function fI(e,t){let r=Object.fromEntries(new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"numeric",day:"numeric",weekday:"short",hour:"numeric",minute:"numeric",hourCycle:"h23"}).formatToParts(e).map((o)=>[o.type,o.value]));return{minute:Number(r.minute),hour:Number(r.hour),day:Number(r.day),month:Number(r.month),weekday:Rh[r.weekday.toUpperCase()],year:Number(r.year),key:`${r.year}-${r.month}-${r.day} ${r.hour}:${r.minute}`}}function Ch(e){let r=(e.startsWith("cron(")?e.slice(5,-1).trim():e.trim()).split(/\s+/);if(r.length!==5&&r.length!==6)throw Error("Cron schedules require five standard fields or six EventBridge fields.");let[o,m,h,I,R,A]=r,E=r.length===6;return{minute:Sa(o,0,59),hour:Sa(m,0,23),day:Sa(h,1,31),month:Sa(I,1,12,gI),weekday:Sa(R,E?1:0,7,Rh,E?(x)=>x===7?6:x-1:void 0),year:A?Sa(A,1970,2199):void 0,dayWildcard:h==="*"||h==="?",weekdayWildcard:R==="*"||R==="?"}}function hI(e,t){if(!((!t.minute||t.minute.has(e.minute))&&(!t.hour||t.hour.has(e.hour))&&(!t.month||t.month.has(e.month))&&(!t.year||t.year.has(e.year))))return!1;let o=!t.day||t.day.has(e.day),m=!t.weekday||t.weekday.has(e.weekday);return t.dayWildcard?m:t.weekdayWildcard?o:o||m}function Ph(e){let t=/^rate\(\s*(\d+)\s+(minute|minutes|hour|hours|day|days)\s*\)$/i.exec(e);if(!t)return;let r=Number(t[1]);if(r<1)throw Error("Rate amount must be positive.");return r*(t[2].toLowerCase().startsWith("minute")?60000:t[2].toLowerCase().startsWith("hour")?3600000:86400000)}function ze(e){let t=e.trim(),r=mI[t.toLowerCase()]??t;if(!r)throw Error("Schedule expression is required.");let o=Ph(r);if(o){let m=o/60000;return{original:t,normalized:`rate(${m} minutes)`,kind:"rate",description:m%1440===0?`Every ${m/1440} day(s)`:m%60===0?`Every ${m/60} hour(s)`:`Every ${m} minute(s)`}}return Ch(r),{original:t,normalized:r.startsWith("cron(")?r:`cron(${r})`,kind:"cron",description:`Cron ${r.replace(/^cron\(|\)$/g,"")}`}}function mt(e,t,r=new Date,o=5){let m=ze(e),h=Ah(t),I=Math.min(20,Math.max(1,o)),R=Ph(m.normalized);if(R)return Array.from({length:I},(z,H)=>new Date(r.getTime()+R*(H+1)).toISOString());let A=Ch(m.normalized),E=[],x=new Set,N=new Date(Math.floor(r.getTime()/60000)*60000+60000),F=0;while(E.length<I&&F<1100000){let z=fI(N,h);if(hI(z,A)&&!x.has(z.key))E.push(N.toISOString()),x.add(z.key);N=new Date(N.getTime()+60000),F++}if(E.length<I)throw Error("Schedule produced no runs within the bounded preview horizon.");return E}function ht(e,t="UTC",r=new Date,o=5){let m=ze(e),h=mt(m.normalized,t,r,o),I=m.kind==="cron"?["Server cron and EventBridge use the same wall-clock preview; provider-specific extensions are retained only when supported."]:["Rate schedules use elapsed-time intervals and are not shifted by DST."];return{...m,timezone:Ah(t),nextRuns:h,capabilities:{server:m.kind==="cron",eventbridge:!0,notes:I}}}function Hr(e){let t=ze(e.expression),r=t.normalized.slice(5,-1).trim().split(/\s+/),o=t.kind==="cron"&&r.length===5;if(e.provider==="server")return{provider:"server",supported:o,features:{timezone:!0,flexibleWindow:!1,catchUp:!1,replaceOverlap:!1},notes:[t.kind==="rate"?"Server cron requires a cron expression; use an equivalent cron schedule.":r.length!==5?"EventBridge six-field cron extensions cannot be installed as server cron.":"Cron is reconciled through a root-owned ts-cloud entry.",e.missedRunPolicy==="catch_up"?"Catch-up is handled by the control plane, not cron.":"Missed runs are skipped by cron."]};if(e.provider==="eventbridge")return{provider:"eventbridge",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["Five-field cron is translated explicitly to EventBridge six-field syntax. Flexible windows are provider-native; overlap and catch-up remain control-plane policies."]};if(e.provider==="lambda")return{provider:"lambda",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["The schedule invokes one immutable Lambda target."]};return{provider:"platform",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!0,replaceOverlap:!0},notes:["The durable control-plane worker enforces all configured policies."]}}function Ni(e){let t=Hr({...e,provider:"server"});if(!t.supported)throw Error(t.notes.join(" "));let o=ze(e.expression).normalized.slice(5,-1);return{path:`/etc/cron.d/ts-cloud-${e.id}`,content:`CRON_TZ=${e.timezone}
78
78
  ${o} root /usr/local/bin/cloud jobs:dispatch ${e.id} --scheduled >/dev/null 2>&1
79
- `}}function yI(e){let t=je(e);if(t.kind==="rate")return e;let r=t.normalized.slice(5,-1).trim().split(/\s+/);if(r.length===6)return t.normalized;let[o,m,h,I,R]=r,A=R==="*"?"?":R.replace(/(^|[,-])0(?=$|[,-])/g,(E,x)=>`${x}1`);return h==="*"&&R!=="*"?`cron(${o} ${m} ? ${I} ${A} *)`:`cron(${o} ${m} ${h} ${I} ? *)`}function ol(e){let t=Hr(e);if(!t.supported)throw Error(t.notes.join(" "));return{Name:`ts-cloud-${e.id}`,ScheduleExpression:yI(e.expression),ScheduleExpressionTimezone:e.timezone,State:e.enabled?"ENABLED":"DISABLED",FlexibleTimeWindow:e.flexibleMinutes?{Mode:"FLEXIBLE",MaximumWindowInMinutes:e.flexibleMinutes}:{Mode:"OFF"},Target:{kind:e.target.kind,functionName:e.target.functionName??null,payloadRefs:e.payloadRefs},RetryPolicy:{MaximumRetryAttempts:e.retryPolicy.maxAttempts,MaximumEventAgeInSeconds:e.timeoutSeconds},DeadLetterRef:e.retryPolicy.deadLetterRef??null}}function AA(e,t){if(!t)return{status:"unavailable",observedState:{message:"Provider observation is unavailable."}};let r=String(t.expression??""),o=t.enabled;return{status:r&&r!==e.normalizedExpression||typeof o==="boolean"&&o!==e.enabled?"drifted":"in_sync",observedState:t}}function am(e){if(e.provider==="server"){let t=Ni(e);return{path:t.path,content:t.content,enabled:e.enabled}}if(e.provider==="eventbridge")return ol(e);throw Error(`No reconciliation adapter is configured for ${e.provider} schedules.`)}function Rp(e,t){if(Array.isArray(e))return Array.isArray(t)&&e.length===t.length&&e.every((r,o)=>Rp(r,t[o]));if(e&&typeof e==="object"){if(!t||typeof t!=="object"||Array.isArray(t))return!1;return Object.entries(e).every(([r,o])=>Rp(o,t[r]))}return e===t}class cm{transport;provider="server";constructor(e){this.transport=e}async observe(e){let t=Ni(e),r=await this.transport.read(t.path);return r==null?void 0:{path:t.path,content:r,enabled:!0}}async apply(e,t){let r=String(t.path??"");if(!e.enabled){await this.transport.removeRootOwned(r);return}await this.transport.writeRootOwned(r,String(t.content??""))}async remove(e){await this.transport.removeRootOwned(Ni(e).path)}matches(e,t){if(e.enabled===!1)return!1;return e.path===t.path&&e.content===t.content}}class dm{transport;provider="eventbridge";constructor(e){this.transport=e}observe(e){return this.transport.get(`ts-cloud-${e.id}`)}apply(e,t){return this.transport.put(t)}remove(e){return this.transport.remove(`ts-cloud-${e.id}`)}matches(e,t){return Rp(e,t)}}class lm{store;constructor(e){this.store=e}async reconcile(e,t,r={}){if(t.provider!==e.provider)return this.store.reconcile(e.id,"unsupported",{provider:t.provider,message:`Adapter ${t.provider} cannot reconcile ${e.provider}.`});try{let o=am(e),m=await t.observe(e);if(m&&t.matches(o,m))return this.store.reconcile(e.id,"in_sync",{provider:t.provider,observed:m});if(r.apply===!1)return this.store.reconcile(e.id,m?"drifted":"unavailable",{provider:t.provider,observed:m??null,applyRequired:!0});if(await t.apply(e,o),!e.enabled)return this.store.reconcile(e.id,"in_sync",{provider:t.provider,observed:null,disabled:!0});let h=await t.observe(e);return this.store.reconcile(e.id,h&&t.matches(o,h)?"in_sync":"drifted",{provider:t.provider,observed:h??null,applied:!0})}catch(o){return this.store.reconcile(e.id,"unavailable",{provider:t.provider,error:o instanceof Error?o.message:String(o)})}}async remove(e,t){if(e.origin==="config")throw Error("Config-defined jobs must be removed from configuration, not destructively deleted.");if(t.provider!==e.provider)throw Error(`Adapter ${t.provider} cannot remove ${e.provider}.`);await t.remove(e),this.store.remove(e.id)}}function vI(e){if(e.queues===!0)return[{queue:"default",processes:e.queueConcurrency??1}];if(!Array.isArray(e.queues))return[];return e.queues.map((t)=>{if(typeof t==="string")return{queue:t,processes:e.queueConcurrency??1};let[r,o]=Object.entries(t)[0]??["default",e.queueConcurrency??1];return{queue:r,processes:o}})}function Po(e,t,r){let o=new Set,m=new Set,h=new Map(r.resources.map((N)=>[N.slug,N])),I=0,R=0;for(let[N,F]of Object.entries(t.sites??{})){let z=h.get(N);if(F.scheduler){let X=`config:site:${N}:scheduler`;o.add(X),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:z?.id,name:`${N} scheduler`,provider:"server",expression:"* * * * *",timezone:"UTC",flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:`scheduler:run:${N}`},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:300,enabled:!0,origin:"config",sourceKey:X,observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),I++}let H=F,K=Array.isArray(H.queues??H.workers)?H.queues??H.workers:[];for(let[X,oe]of K.entries()){let ye=typeof oe==="string"?{queue:oe}:oe,ne=String(ye.queue??ye.name??"default"),fe=`config:site:${N}:worker:${X}:${ne}`;m.add(fe),e.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:z?.id,name:`${N}:${ne}`,provider:"systemd",queue:ne,processes:Number(ye.processes)||1,timeoutSeconds:Number(ye.timeout)||60,restartPolicy:"always",target:{operationId:`worker:restart:${N}`,site:N},enabled:!0,origin:"config",sourceKey:fe,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),R++}}let A=t.infrastructure?.compute?.backups;if(A?.enabled)o.add("config:platform:backup"),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:"Scheduled backup",provider:"server",expression:String(A.schedule??"0 2 * * *"),timezone:String(A.timezone??"UTC"),flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:"backup:run"},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:60},timeoutSeconds:3600,enabled:!0,origin:"config",sourceKey:"config:platform:backup",observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),I++;let E=t.environments?.[r.environment.slug]?.app;if(E){if(E.scheduler!=="off"){let N=`config:serverless:${r.environment.slug}:scheduler`;o.add(N),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name} serverless scheduler`,provider:"eventbridge",expression:"rate(1 minute)",timezone:"UTC",flexibleMinutes:0,target:{kind:"serverless_scheduler",action:"schedule:run"},payloadRefs:{},missedRunPolicy:E.scheduler==="sub-minute"?"catch_up":"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:E.cliTimeout??900,enabled:!0,origin:"config",sourceKey:N,observedState:{source:"cloud.config.ts",mode:E.scheduler??"on"},reconciliationStatus:"pending"}),I++}for(let{queue:N,processes:F}of vI(E)){let z=`config:serverless:${r.environment.slug}:worker:${N}`;m.add(z),e.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name}:${N}`,provider:"lambda",queue:N,processes:F,timeoutSeconds:E.queueTimeout??120,restartPolicy:"on_failure",target:{function:"queue",queue:N},enabled:!0,origin:"config",sourceKey:z,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),R++}}let x=0;for(let N of e.list(r.project.id,{environmentId:r.environment.id}).filter((F)=>F.origin==="config"&&F.sourceKey&&!o.has(F.sourceKey)))e.reconcile(N.id,"drifted",{...N.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),x++;for(let N of e.listWorkers(r.project.id,r.environment.id).filter((F)=>F.origin==="config"&&F.sourceKey&&!m.has(F.sourceKey)))e.reconcileWorker(N.id,"drifted",{...N.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),x++;return{jobs:I,workers:R,drifted:x}}class No{store;queue;constructor(e,t={}){this.store=e;this.queue=t.queue??new c(e.controlPlane)}enqueue(e,t){let r=new Date(t.scheduledFor??this.store.now()).toISOString(),o=`${e.id}:${t.trigger==="manual"?crypto.randomUUID():r}`,m=this.store.activeExecution(e.id);if(m&&e.overlapPolicy==="forbid")return this.store.createExecution({jobId:e.id,trigger:t.trigger,scheduledFor:r,idempotencyKey:o,status:"skipped",output:{reason:"overlap_forbidden",activeExecutionId:m.id}});if(m&&e.overlapPolicy==="replace"&&m.operationId)try{this.queue.requestCancellation(m.operationId,t.actorId)}catch{}let h=this.store.createExecution({jobId:e.id,trigger:t.trigger,scheduledFor:r,idempotencyKey:o,status:"queued",output:{semantics:"at_least_once"}});if(h.operationId)return h;let I=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:t.actorId,kind:"job.execute",input:{jobId:e.id,executionId:h.id},idempotencyKey:`job-execution:${h.id}`,lockKey:e.overlapPolicy==="allow"?`job-execution:${h.id}`:`job:${e.id}`,maxAttempts:e.retryPolicy.maxAttempts,timeoutSeconds:e.timeoutSeconds,retryClasses:["job_transient"],resumePolicy:"requeue"}).operation;return this.store.attachOperation(h.id,I.id)}tick(e=this.store.now()){let t=[];for(let r of this.store.due(e.toISOString())){let o=r.nextRunAt,m=mt(r.normalizedExpression,r.timezone,e,1)[0];if(r.missedRunPolicy==="catch_up"){let h=o,I=0;while(h<=e.toISOString()&&I<10)t.push(this.enqueue(r,{trigger:h===o?"scheduled":"catch_up",scheduledFor:h})),h=mt(r.normalizedExpression,r.timezone,new Date(h),1)[0],I++}else t.push(this.enqueue(r,{trigger:"scheduled",scheduledFor:o}));this.store.markScheduled(r.id,o,m)}return t}}function al(e){return{"job.execute":async(r)=>{let o=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},m=e.store.get(String(o.jobId??"")),h=e.store.getExecution(String(o.executionId??""));if(!m||!h)throw Error("Scheduled job execution is no longer available.");e.store.transitionExecution(h.id,"running",{attempt:r.operation.attempt}),r.checkpoint("execute",`Running ${m.name} on ${m.provider}.`),r.log(`Trigger ${h.trigger}; scheduled for ${h.scheduledFor}; semantics at-least-once.`,{stream:"system"});let I=await e.executor(m,m.target,r);if(I.stdout)r.log(I.stdout,{stream:"stdout"});if(I.stderr)r.log(I.stderr,{stream:"stderr"});if(!I.ok){if(e.store.transitionExecution(h.id,r.operation.attempt>=m.retryPolicy.maxAttempts?"dead":"failed",{attempt:r.operation.attempt,error:I.stderr??"Job execution failed."}),I.retryable)throw new J(I.stderr??"Scheduled job failed transiently.","job_transient");throw Error(I.stderr??"Scheduled job failed.")}return e.store.transitionExecution(h.id,"succeeded",{attempt:r.operation.attempt,output:I.output??{}}),{jobId:m.id,executionId:h.id,provider:m.provider}}}}var pn=(e)=>typeof e==="string"&&e?e:void 0,_h=(e)=>Number(e)===1,Ds=(e)=>{try{return JSON.parse(String(e))}catch{return{}}},is=(e,t,r,o)=>{let m=Number(e);return Number.isFinite(m)?Math.min(o,Math.max(r,Math.floor(m))):t};function Jc(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:pn(e.environment_id),resourceId:pn(e.resource_id),name:String(e.name),provider:String(e.provider),expression:String(e.expression),normalizedExpression:String(e.normalized_expression),timezone:String(e.timezone),startsAt:pn(e.starts_at),endsAt:pn(e.ends_at),flexibleMinutes:Number(e.flexible_minutes),target:Ds(e.target),payloadRefs:Ds(e.payload_refs),missedRunPolicy:String(e.missed_run_policy),overlapPolicy:String(e.overlap_policy),retryPolicy:Ds(e.retry_policy),timeoutSeconds:Number(e.timeout_seconds),enabled:_h(e.enabled),origin:String(e.origin),sourceKey:pn(e.source_key),ownerActorId:pn(e.owner_actor_id),observedState:Ds(e.observed_state),reconciliationStatus:String(e.reconciliation_status),nextRunAt:pn(e.next_run_at),lastScheduledFor:pn(e.last_scheduled_for),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Qc(e){return{id:String(e.id),jobId:String(e.job_id),operationId:pn(e.operation_id),trigger:String(e.trigger),scheduledFor:String(e.scheduled_for),idempotencyKey:String(e.idempotency_key),status:String(e.status),attempt:Number(e.attempt),startedAt:pn(e.started_at),finishedAt:pn(e.finished_at),output:Ds(e.output),error:pn(e.error),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Ap(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:pn(e.environment_id),resourceId:pn(e.resource_id),name:String(e.name),provider:String(e.provider),queue:String(e.queue),processes:Number(e.processes),timeoutSeconds:Number(e.timeout_seconds),restartPolicy:String(e.restart_policy),target:Ds(e.target),enabled:_h(e.enabled),origin:String(e.origin),sourceKey:pn(e.source_key),ownerActorId:pn(e.owner_actor_id),observedState:Ds(e.observed_state),reconciliationStatus:String(e.reconciliation_status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class Do{controlPlane;options;constructor(e,t={}){this.controlPlane=e;this.options=t}now(){return this.options.now?.()??new Date}create(e){if(!e.name.trim())throw Error("Scheduled jobs require a name.");let t=ht(e.expression,e.timezone,this.now(),1),r=crypto.randomUUID(),o=this.now().toISOString(),m=e.startsAt?new Date(e.startsAt).toISOString():void 0,h=e.endsAt?new Date(e.endsAt).toISOString():void 0;if(m&&h&&m>=h)throw Error("Schedule start must be before end.");let I=t.nextRuns.find((R)=>(!m||R>=m)&&(!h||R<=h));return this.controlPlane.database.run("INSERT INTO scheduled_jobs (id,organization_id,project_id,environment_id,resource_id,name,provider,expression,normalized_expression,timezone,starts_at,ends_at,flexible_minutes,target,payload_refs,missed_run_policy,overlap_policy,retry_policy,timeout_seconds,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,next_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name.trim().slice(0,120),e.provider,e.expression,t.normalized,e.timezone,m??null,h??null,is(e.flexibleMinutes,0,0,1440),JSON.stringify(e.target),JSON.stringify(e.payloadRefs),e.missedRunPolicy,e.overlapPolicy,JSON.stringify({maxAttempts:is(e.retryPolicy.maxAttempts,3,1,20),backoffSeconds:is(e.retryPolicy.backoffSeconds,30,0,86400),deadLetterRef:e.retryPolicy.deadLetterRef}),is(e.timeoutSeconds,900,1,86400),e.enabled?1:0,e.origin,e.sourceKey??null,e.ownerActorId??null,JSON.stringify(e.observedState),e.reconciliationStatus,I??null,1,o,o]),this.get(r)}get(e){let t=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE id=?").get(e);return t?Jc(t):void 0}getBySource(e,t,r){let o=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE project_id=? AND environment_id IS ? AND source_key=?").get(e,t??null,r);return o?Jc(o):void 0}list(e,t={}){let r=["project_id=?"],o=[e];if(t.environmentId)r.push("environment_id=?"),o.push(t.environmentId);if(t.resourceIds?.length)r.push(`resource_id IN (${t.resourceIds.map(()=>"?").join(",")})`),o.push(...t.resourceIds);if(t.enabled!=null)r.push("enabled=?"),o.push(t.enabled?1:0);return this.controlPlane.database.query(`SELECT * FROM scheduled_jobs WHERE ${r.join(" AND ")} ORDER BY next_run_at IS NULL,next_run_at,name`).all(...o).map(Jc)}setEnabled(e,t){this.controlPlane.database.run("UPDATE scheduled_jobs SET enabled=?,version=version+1,updated_at=? WHERE id=?",[t?1:0,this.now().toISOString(),e]);let r=this.get(e);if(!r)throw Error("Scheduled job was not found.");return r}updateSchedule(e,t){let r=this.get(e);if(!r)throw Error("Scheduled job was not found.");let o=t.expression??r.expression,m=t.timezone??r.timezone,h=ht(o,m,this.now(),1),I=this.now().toISOString();return this.controlPlane.database.run("UPDATE scheduled_jobs SET expression=?,normalized_expression=?,timezone=?,missed_run_policy=?,overlap_policy=?,timeout_seconds=?,next_run_at=?,reconciliation_status=?,version=version+1,updated_at=? WHERE id=?",[o,h.normalized,m,t.missedRunPolicy??r.missedRunPolicy,t.overlapPolicy??r.overlapPolicy,is(t.timeoutSeconds,r.timeoutSeconds,1,86400),h.nextRuns[0],"pending",I,e]),this.get(e)}remove(e){let t=this.get(e);if(!t)throw Error("Scheduled job was not found.");if(t.origin==="config")throw Error("Config-defined jobs must be removed from configuration, not destructively deleted.");this.controlPlane.database.run("DELETE FROM scheduled_jobs WHERE id=?",[e])}markScheduled(e,t,r){this.controlPlane.database.run("UPDATE scheduled_jobs SET last_scheduled_for=?,next_run_at=?,updated_at=? WHERE id=?",[t,r??null,this.now().toISOString(),e])}reconcile(e,t,r){return this.controlPlane.database.run("UPDATE scheduled_jobs SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[t,JSON.stringify(r),this.now().toISOString(),e]),this.get(e)}upsertConfigJob(e){let t=this.getBySource(e.projectId,e.environmentId,e.sourceKey);if(!t)return this.create(e);let r=ht(e.expression,e.timezone,this.now(),1),o=this.now().toISOString();if(t.resourceId===e.resourceId&&t.name===e.name&&t.provider===e.provider&&t.expression===e.expression&&t.normalizedExpression===r.normalized&&t.timezone===e.timezone&&JSON.stringify(t.target)===JSON.stringify(e.target)&&JSON.stringify(t.payloadRefs)===JSON.stringify(e.payloadRefs)&&t.missedRunPolicy===e.missedRunPolicy&&t.overlapPolicy===e.overlapPolicy&&JSON.stringify(t.retryPolicy)===JSON.stringify(e.retryPolicy)&&t.timeoutSeconds===e.timeoutSeconds&&t.enabled===e.enabled)return t;return this.controlPlane.database.run("UPDATE scheduled_jobs SET resource_id=?,name=?,provider=?,expression=?,normalized_expression=?,timezone=?,target=?,payload_refs=?,missed_run_policy=?,overlap_policy=?,retry_policy=?,timeout_seconds=?,enabled=?,observed_state=?,reconciliation_status=?,next_run_at=COALESCE(next_run_at,?),version=version+1,updated_at=? WHERE id=?",[e.resourceId??null,e.name,e.provider,e.expression,r.normalized,e.timezone,JSON.stringify(e.target),JSON.stringify(e.payloadRefs),e.missedRunPolicy,e.overlapPolicy,JSON.stringify(e.retryPolicy),e.timeoutSeconds,e.enabled?1:0,JSON.stringify(e.observedState),e.reconciliationStatus,r.nextRuns[0],o,t.id]),this.get(t.id)}due(e=this.now().toISOString()){return this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE enabled=1 AND next_run_at IS NOT NULL AND next_run_at<=? AND (starts_at IS NULL OR starts_at<=?) AND (ends_at IS NULL OR ends_at>=?) ORDER BY next_run_at LIMIT 200").all(e,e,e).map(Jc)}createExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE idempotency_key=?").get(e.idempotencyKey);if(t)return Qc(t);let r=crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO job_executions (id,job_id,operation_id,trigger,scheduled_for,idempotency_key,status,attempt,output,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)",[r,e.jobId,e.operationId??null,e.trigger,e.scheduledFor,e.idempotencyKey,e.status,0,JSON.stringify(e.output),o,o]),this.getExecution(r)}getExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE id=?").get(e);return t?Qc(t):void 0}listExecutions(e,t=100){return this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? ORDER BY scheduled_for DESC,created_at DESC LIMIT ?").all(e,Math.min(1000,Math.max(1,t))).map(Qc)}activeExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? AND status IN ('queued','running') ORDER BY created_at DESC LIMIT 1").get(e);return t?Qc(t):void 0}attachOperation(e,t){return this.controlPlane.database.run("UPDATE job_executions SET operation_id=?,updated_at=? WHERE id=?",[t,this.now().toISOString(),e]),this.getExecution(e)}transitionExecution(e,t,r={}){let o=this.now().toISOString(),m=t==="running"?o:null,h=["succeeded","failed","skipped","dead"].includes(t)?o:null;return this.controlPlane.database.run("UPDATE job_executions SET status=?,attempt=COALESCE(?,attempt),started_at=COALESCE(started_at,?),finished_at=?,output=COALESCE(?,output),error=?,updated_at=? WHERE id=?",[t,r.attempt??null,m,h,r.output?JSON.stringify(r.output):null,r.error?.slice(0,2000)??null,o,e]),this.getExecution(e)}upsertWorker(e){let t=e.sourceKey?this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE project_id=? AND source_key=? AND environment_id IS ?").get(e.projectId,e.sourceKey,e.environmentId??null):void 0,r=t?Ap(t):void 0,o=r?.id??crypto.randomUUID(),m=this.now().toISOString(),h=is(e.processes,1,0,1000),I=is(e.timeoutSeconds,60,1,86400);if(r&&r.resourceId===e.resourceId&&r.name===e.name.slice(0,120)&&r.provider===e.provider&&r.queue===e.queue.slice(0,200)&&r.processes===h&&r.timeoutSeconds===I&&r.restartPolicy===e.restartPolicy&&JSON.stringify(r.target)===JSON.stringify(e.target)&&r.enabled===e.enabled)return r;return this.controlPlane.database.run("INSERT INTO worker_definitions (id,organization_id,project_id,environment_id,resource_id,name,provider,queue,processes,timeout_seconds,restart_policy,target,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET name=excluded.name,resource_id=excluded.resource_id,provider=excluded.provider,queue=excluded.queue,processes=excluded.processes,timeout_seconds=excluded.timeout_seconds,restart_policy=excluded.restart_policy,target=excluded.target,enabled=excluded.enabled,observed_state=excluded.observed_state,reconciliation_status=excluded.reconciliation_status,version=worker_definitions.version+1,updated_at=excluded.updated_at",[o,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name.slice(0,120),e.provider,e.queue.slice(0,200),h,I,e.restartPolicy,JSON.stringify(e.target),e.enabled?1:0,e.origin,e.sourceKey??null,e.ownerActorId??null,JSON.stringify(e.observedState),e.reconciliationStatus,1,r?.createdAt??m,m]),this.getWorker(o)}getWorker(e){let t=this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE id=?").get(e);return t?Ap(t):void 0}listWorkers(e,t){return this.controlPlane.database.query(`SELECT * FROM worker_definitions WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(Ap)}setWorkerProcesses(e,t){this.controlPlane.database.run("UPDATE worker_definitions SET processes=?,reconciliation_status='pending',version=version+1,updated_at=? WHERE id=?",[is(t,1,0,1000),this.now().toISOString(),e]);let r=this.getWorker(e);if(!r)throw Error("Worker was not found.");return r}reconcileWorker(e,t,r){this.controlPlane.database.run("UPDATE worker_definitions SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[t,JSON.stringify(r),this.now().toISOString(),e]);let o=this.getWorker(e);if(!o)throw Error("Worker was not found.");return o}}var _t=(e)=>e==null?void 0:String(e),Yc=(e)=>Number(e)===1,os=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}};function xh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),name:String(e.name),provider:String(e.provider),endpoint:_t(e.endpoint),endpointPolicy:String(e.endpoint_policy),bucket:_t(e.bucket),prefix:String(e.prefix),region:_t(e.region),forcePathStyle:Yc(e.force_path_style),credentialRef:_t(e.credential_ref),encryption:String(e.encryption),encryptionKeyRef:_t(e.encryption_key_ref),immutability:os(e.immutability,{}),status:String(e.status),lastTestedAt:_t(e.last_tested_at),lastSuccessAt:_t(e.last_success_at),lastFailureAt:_t(e.last_failure_at),lastError:_t(e.last_error),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Cp(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:_t(e.environment_id),resourceId:_t(e.resource_id),dataServiceId:_t(e.data_service_id),destinationId:String(e.destination_id),name:String(e.name),resourceKind:String(e.resource_kind),schedule:String(e.schedule),timezone:String(e.timezone),retention:os(e.retention,{}),compression:String(e.compression),encryption:String(e.encryption),includePatterns:os(e.include_patterns,[]),excludePatterns:os(e.exclude_patterns,[]),expectedRpoMinutes:Number(e.expected_rpo_minutes),expectedRtoMinutes:Number(e.expected_rto_minutes),healthCheckId:_t(e.health_check_id),enabled:Yc(e.enabled),nextRunAt:_t(e.next_run_at),lastRunAt:_t(e.last_run_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Pp(e){return{id:String(e.id),projectId:String(e.project_id),policyId:_t(e.policy_id),destinationId:String(e.destination_id),resourceId:_t(e.resource_id),dataServiceId:_t(e.data_service_id),backupJobId:_t(e.backup_job_id),kind:String(e.kind),pointInTime:String(e.point_in_time),uri:String(e.uri),sizeBytes:Number(e.size_bytes),checksum:String(e.checksum),manifest:os(e.manifest,{}),toolVersion:_t(e.tool_version),engineVersion:_t(e.engine_version),expiresAt:_t(e.expires_at),lockedUntil:_t(e.locked_until),held:Yc(e.held),pinned:Yc(e.pinned),status:String(e.status),verificationState:String(e.verification_state),verifiedAt:_t(e.verified_at),durationMs:e.duration_ms==null?void 0:Number(e.duration_ms),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function _p(e){return{id:String(e.id),projectId:String(e.project_id),policyId:_t(e.policy_id),recoveryPointId:_t(e.recovery_point_id),operationId:_t(e.operation_id),kind:String(e.kind),status:String(e.status),idempotencyKey:String(e.idempotency_key),target:os(e.target,{}),restoreMode:_t(e.restore_mode),cancellability:String(e.cancellability),safetyBackupId:_t(e.safety_backup_id),healthResult:e.health_result?os(e.health_result,{}):void 0,progress:os(e.progress,{}),error:_t(e.error),startedAt:_t(e.started_at),finishedAt:_t(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function bI(e){let t=e.toLowerCase();if(t==="localhost"||t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".internal"))return!0;if(Th(t)===6)return t==="::1"||t.startsWith("fe80:");if(Th(t)!==4)return!1;let[r,o]=t.split(".").map(Number);return r===10||r===127||r===0||r===169&&o===254||r===172&&o>=16&&o<=31||r===192&&o===168}function Em(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Backup destination names must be 2-63 lowercase letters, numbers, or dashes.");if(e.provider!=="aws_backup"&&!e.bucket)throw Error("S3 backup destinations require a bucket.");if(e.provider==="s3_compatible"&&!e.endpoint)throw Error("S3-compatible destinations require an explicit endpoint.");if(e.provider==="s3_compatible"&&!e.credentialRef)throw Error("S3-compatible destinations require a credential reference.");if(e.encryption!=="provider"&&!e.encryptionKeyRef)throw Error("Client-side encryption requires an encryption key reference.");if(e.endpoint){let t=new URL(e.endpoint);if(t.protocol!=="https:"||t.username||t.password||t.search||t.hash||t.pathname!=="/")throw Error("Backup endpoints must be origin-only HTTPS URLs without credentials, paths, queries, or fragments.");if(bI(t.hostname)&&e.endpointPolicy!=="allow_private")throw Error("Private backup endpoints require endpointPolicy allow_private.")}}class ea{controlPlane;now;constructor(e,t=()=>new Date){this.controlPlane=e;this.now=t}createDestination(e){Em(e);let t=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_destinations (id,organization_id,project_id,name,provider,endpoint,endpoint_policy,bucket,prefix,region,force_path_style,credential_ref,encryption,encryption_key_ref,immutability,status,last_tested_at,last_success_at,last_failure_at,last_error,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.name,e.provider,e.endpoint??null,e.endpointPolicy,e.bucket??null,e.prefix,e.region??null,e.forcePathStyle?1:0,e.credentialRef??null,e.encryption,e.encryptionKeyRef??null,JSON.stringify(e.immutability),e.status,e.lastTestedAt??null,e.lastSuccessAt??null,e.lastFailureAt??null,e.lastError??null,1,r,r]),this.getDestination(t)}getDestination(e){let t=this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE id=?").get(e);return t?xh(t):void 0}listDestinations(e){return this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE project_id=? ORDER BY name").all(e).map(xh)}recordDestinationTest(e,t){let r=this.now().toISOString();return this.controlPlane.database.run("UPDATE backup_destinations SET status=?,last_tested_at=?,last_success_at=CASE WHEN ? THEN ? ELSE last_success_at END,last_failure_at=CASE WHEN ? THEN last_failure_at ELSE ? END,last_error=?,version=version+1,updated_at=? WHERE id=?",[t.ok?"healthy":"failing",r,t.ok?1:0,r,t.ok?1:0,r,t.ok?null:String(t.error??"Destination test failed.").slice(0,1000),r,e]),this.getDestination(e)}createPolicy(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Backup policy names must be lowercase slugs.");if(!e.resourceId&&!e.dataServiceId&&!["control_plane","infrastructure"].includes(e.resourceKind))throw Error("A backup policy requires a resource or data service target.");let t=this.getDestination(e.destinationId);if(!t||t.projectId!==e.projectId)throw Error("Backup destination was not found.");if(e.resourceKind==="control_plane"&&t.encryption==="provider")throw Error("Control-plane backups require client-side destination encryption.");if(["logical_database","volume","files","control_plane"].includes(e.resourceKind)&&t.provider==="aws_backup")throw Error(`${e.resourceKind} backups require an object-storage destination.`);if(e.resourceKind==="infrastructure"&&t.provider!=="aws_backup")throw Error("Infrastructure backups require an AWS Backup destination.");let r=je(e.schedule),o=mt(r.normalized,e.timezone,this.now(),1)[0],m=crypto.randomUUID(),h=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_policies (id,organization_id,project_id,environment_id,resource_id,data_service_id,destination_id,name,resource_kind,schedule,timezone,retention,compression,encryption,include_patterns,exclude_patterns,expected_rpo_minutes,expected_rto_minutes,health_check_id,enabled,next_run_at,last_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[m,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.dataServiceId??null,e.destinationId,e.name,e.resourceKind,r.normalized,e.timezone,JSON.stringify(e.retention),e.compression,e.encryption,JSON.stringify(e.includePatterns),JSON.stringify(e.excludePatterns),e.expectedRpoMinutes,e.expectedRtoMinutes,e.healthCheckId??null,e.enabled?1:0,o,e.lastRunAt??null,1,h,h]),this.getPolicy(m)}getPolicy(e){let t=this.controlPlane.database.query("SELECT * FROM backup_policies WHERE id=?").get(e);return t?Cp(t):void 0}listPolicies(e,t){return this.controlPlane.database.query(`SELECT * FROM backup_policies WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(Cp)}duePolicies(e=this.now()){return this.controlPlane.database.query("SELECT * FROM backup_policies WHERE enabled=1 AND next_run_at<=? ORDER BY next_run_at,id").all(e.toISOString()).map(Cp)}advancePolicy(e,t){let r=this.getPolicy(e);if(!r)throw Error("Backup policy was not found.");let o=mt(r.schedule,r.timezone,new Date(t),1)[0];return this.controlPlane.database.run("UPDATE backup_policies SET last_run_at=?,next_run_at=?,version=version+1,updated_at=? WHERE id=?",[t,o,this.now().toISOString(),e]),this.getPolicy(e)}createJob(e){let t=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE idempotency_key=?").get(e.idempotencyKey);if(t)return _p(t);let r=crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_jobs (id,project_id,policy_id,recovery_point_id,operation_id,kind,status,idempotency_key,target,restore_mode,cancellability,safety_backup_id,health_result,progress,error,started_at,finished_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.projectId,e.policyId??null,e.recoveryPointId??null,e.operationId??null,e.kind,e.status,e.idempotencyKey,JSON.stringify(e.target),e.restoreMode??null,e.cancellability,e.safetyBackupId??null,e.healthResult?JSON.stringify(e.healthResult):null,JSON.stringify(e.progress),e.error??null,e.startedAt??null,e.finishedAt??null,o,o]),this.getJob(r)}getJob(e){let t=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE id=?").get(e);return t?_p(t):void 0}listJobs(e){return this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE project_id=? ORDER BY created_at DESC").all(e).map(_p)}updateJob(e,t){let r=this.getJob(e);if(!r)throw Error("Backup job was not found.");let o={...r,...t};return this.controlPlane.database.run("UPDATE backup_jobs SET status=?,operation_id=?,recovery_point_id=?,progress=?,health_result=?,error=?,started_at=?,finished_at=?,safety_backup_id=?,updated_at=? WHERE id=?",[o.status,o.operationId??null,o.recoveryPointId??null,JSON.stringify(o.progress),o.healthResult?JSON.stringify(o.healthResult):null,o.error??null,o.startedAt??null,o.finishedAt??null,o.safetyBackupId??null,this.now().toISOString(),e]),this.getJob(e)}createRecoveryPoint(e){if(!/^sha256:[a-f0-9]{64}$/i.test(e.checksum))throw Error("Recovery points require a SHA-256 checksum.");if(typeof e.uri!=="string"||!["s3:","aws-backup:","file:"].some((o)=>e.uri.startsWith(o)))throw Error("Recovery point URI uses an unsupported destination scheme.");let t=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO recovery_points (id,project_id,policy_id,destination_id,resource_id,data_service_id,backup_job_id,kind,point_in_time,uri,size_bytes,checksum,manifest,tool_version,engine_version,expires_at,locked_until,held,pinned,status,verification_state,verified_at,duration_ms,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.projectId,e.policyId??null,e.destinationId,e.resourceId??null,e.dataServiceId??null,e.backupJobId??null,e.kind,e.pointInTime,e.uri,e.sizeBytes,e.checksum,JSON.stringify(e.manifest),e.toolVersion??null,e.engineVersion??null,e.expiresAt??null,e.lockedUntil??null,e.held?1:0,e.pinned?1:0,e.status,e.verificationState,e.verifiedAt??null,e.durationMs??null,r,r]),this.getRecoveryPoint(t)}getRecoveryPoint(e){let t=this.controlPlane.database.query("SELECT * FROM recovery_points WHERE id=?").get(e);return t?Pp(t):void 0}listRecoveryPoints(e,t){return this.controlPlane.database.query(`SELECT * FROM recovery_points WHERE project_id=?${t?" AND policy_id=?":""} ORDER BY point_in_time DESC`).all(e,...t?[t]:[]).map(Pp)}updateRecoveryPoint(e,t){let r=this.getRecoveryPoint(e);if(!r)throw Error("Recovery point was not found.");let o={...r,...t};return this.controlPlane.database.run("UPDATE recovery_points SET status=?,verification_state=?,verified_at=?,held=?,pinned=?,manifest=?,duration_ms=?,updated_at=? WHERE id=?",[o.status,o.verificationState,o.verifiedAt??null,o.held?1:0,o.pinned?1:0,JSON.stringify(o.manifest),o.durationMs??null,this.now().toISOString(),e]),this.getRecoveryPoint(e)}retentionCandidates(e=this.now()){let t=this.controlPlane.database.query(`SELECT rp.* FROM recovery_points rp
79
+ `}}function yI(e){let t=ze(e);if(t.kind==="rate")return e;let r=t.normalized.slice(5,-1).trim().split(/\s+/);if(r.length===6)return t.normalized;let[o,m,h,I,R]=r,A=R==="*"?"?":R.replace(/(^|[,-])0(?=$|[,-])/g,(E,x)=>`${x}1`);return h==="*"&&R!=="*"?`cron(${o} ${m} ? ${I} ${A} *)`:`cron(${o} ${m} ${h} ${I} ? *)`}function ol(e){let t=Hr(e);if(!t.supported)throw Error(t.notes.join(" "));return{Name:`ts-cloud-${e.id}`,ScheduleExpression:yI(e.expression),ScheduleExpressionTimezone:e.timezone,State:e.enabled?"ENABLED":"DISABLED",FlexibleTimeWindow:e.flexibleMinutes?{Mode:"FLEXIBLE",MaximumWindowInMinutes:e.flexibleMinutes}:{Mode:"OFF"},Target:{kind:e.target.kind,functionName:e.target.functionName??null,payloadRefs:e.payloadRefs},RetryPolicy:{MaximumRetryAttempts:e.retryPolicy.maxAttempts,MaximumEventAgeInSeconds:e.timeoutSeconds},DeadLetterRef:e.retryPolicy.deadLetterRef??null}}function AA(e,t){if(!t)return{status:"unavailable",observedState:{message:"Provider observation is unavailable."}};let r=String(t.expression??""),o=t.enabled;return{status:r&&r!==e.normalizedExpression||typeof o==="boolean"&&o!==e.enabled?"drifted":"in_sync",observedState:t}}function am(e){if(e.provider==="server"){let t=Ni(e);return{path:t.path,content:t.content,enabled:e.enabled}}if(e.provider==="eventbridge")return ol(e);throw Error(`No reconciliation adapter is configured for ${e.provider} schedules.`)}function Rp(e,t){if(Array.isArray(e))return Array.isArray(t)&&e.length===t.length&&e.every((r,o)=>Rp(r,t[o]));if(e&&typeof e==="object"){if(!t||typeof t!=="object"||Array.isArray(t))return!1;return Object.entries(e).every(([r,o])=>Rp(o,t[r]))}return e===t}class cm{transport;provider="server";constructor(e){this.transport=e}async observe(e){let t=Ni(e),r=await this.transport.read(t.path);return r==null?void 0:{path:t.path,content:r,enabled:!0}}async apply(e,t){let r=String(t.path??"");if(!e.enabled){await this.transport.removeRootOwned(r);return}await this.transport.writeRootOwned(r,String(t.content??""))}async remove(e){await this.transport.removeRootOwned(Ni(e).path)}matches(e,t){if(e.enabled===!1)return!1;return e.path===t.path&&e.content===t.content}}class dm{transport;provider="eventbridge";constructor(e){this.transport=e}observe(e){return this.transport.get(`ts-cloud-${e.id}`)}apply(e,t){return this.transport.put(t)}remove(e){return this.transport.remove(`ts-cloud-${e.id}`)}matches(e,t){return Rp(e,t)}}class lm{store;constructor(e){this.store=e}async reconcile(e,t,r={}){if(t.provider!==e.provider)return this.store.reconcile(e.id,"unsupported",{provider:t.provider,message:`Adapter ${t.provider} cannot reconcile ${e.provider}.`});try{let o=am(e),m=await t.observe(e);if(m&&t.matches(o,m))return this.store.reconcile(e.id,"in_sync",{provider:t.provider,observed:m});if(r.apply===!1)return this.store.reconcile(e.id,m?"drifted":"unavailable",{provider:t.provider,observed:m??null,applyRequired:!0});if(await t.apply(e,o),!e.enabled)return this.store.reconcile(e.id,"in_sync",{provider:t.provider,observed:null,disabled:!0});let h=await t.observe(e);return this.store.reconcile(e.id,h&&t.matches(o,h)?"in_sync":"drifted",{provider:t.provider,observed:h??null,applied:!0})}catch(o){return this.store.reconcile(e.id,"unavailable",{provider:t.provider,error:o instanceof Error?o.message:String(o)})}}async remove(e,t){if(e.origin==="config")throw Error("Config-defined jobs must be removed from configuration, not destructively deleted.");if(t.provider!==e.provider)throw Error(`Adapter ${t.provider} cannot remove ${e.provider}.`);await t.remove(e),this.store.remove(e.id)}}function vI(e){if(e.queues===!0)return[{queue:"default",processes:e.queueConcurrency??1}];if(!Array.isArray(e.queues))return[];return e.queues.map((t)=>{if(typeof t==="string")return{queue:t,processes:e.queueConcurrency??1};let[r,o]=Object.entries(t)[0]??["default",e.queueConcurrency??1];return{queue:r,processes:o}})}function Po(e,t,r){let o=new Set,m=new Set,h=new Map(r.resources.map((N)=>[N.slug,N])),I=0,R=0;for(let[N,F]of Object.entries(t.sites??{})){let z=h.get(N);if(F.scheduler){let X=`config:site:${N}:scheduler`;o.add(X),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:z?.id,name:`${N} scheduler`,provider:"server",expression:"* * * * *",timezone:"UTC",flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:`scheduler:run:${N}`},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:300,enabled:!0,origin:"config",sourceKey:X,observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),I++}let H=F,K=Array.isArray(H.queues??H.workers)?H.queues??H.workers:[];for(let[X,oe]of K.entries()){let ye=typeof oe==="string"?{queue:oe}:oe,ne=String(ye.queue??ye.name??"default"),fe=`config:site:${N}:worker:${X}:${ne}`;m.add(fe),e.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:z?.id,name:`${N}:${ne}`,provider:"systemd",queue:ne,processes:Number(ye.processes)||1,timeoutSeconds:Number(ye.timeout)||60,restartPolicy:"always",target:{operationId:`worker:restart:${N}`,site:N},enabled:!0,origin:"config",sourceKey:fe,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),R++}}let A=t.infrastructure?.compute?.backups;if(A?.enabled)o.add("config:platform:backup"),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:"Scheduled backup",provider:"server",expression:String(A.schedule??"0 2 * * *"),timezone:String(A.timezone??"UTC"),flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:"backup:run"},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:60},timeoutSeconds:3600,enabled:!0,origin:"config",sourceKey:"config:platform:backup",observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),I++;let E=t.environments?.[r.environment.slug]?.app;if(E){if(E.scheduler!=="off"){let N=`config:serverless:${r.environment.slug}:scheduler`;o.add(N),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name} serverless scheduler`,provider:"eventbridge",expression:"rate(1 minute)",timezone:"UTC",flexibleMinutes:0,target:{kind:"serverless_scheduler",action:"schedule:run"},payloadRefs:{},missedRunPolicy:E.scheduler==="sub-minute"?"catch_up":"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:E.cliTimeout??900,enabled:!0,origin:"config",sourceKey:N,observedState:{source:"cloud.config.ts",mode:E.scheduler??"on"},reconciliationStatus:"pending"}),I++}for(let{queue:N,processes:F}of vI(E)){let z=`config:serverless:${r.environment.slug}:worker:${N}`;m.add(z),e.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name}:${N}`,provider:"lambda",queue:N,processes:F,timeoutSeconds:E.queueTimeout??120,restartPolicy:"on_failure",target:{function:"queue",queue:N},enabled:!0,origin:"config",sourceKey:z,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),R++}}let x=0;for(let N of e.list(r.project.id,{environmentId:r.environment.id}).filter((F)=>F.origin==="config"&&F.sourceKey&&!o.has(F.sourceKey)))e.reconcile(N.id,"drifted",{...N.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),x++;for(let N of e.listWorkers(r.project.id,r.environment.id).filter((F)=>F.origin==="config"&&F.sourceKey&&!m.has(F.sourceKey)))e.reconcileWorker(N.id,"drifted",{...N.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),x++;return{jobs:I,workers:R,drifted:x}}class No{store;queue;constructor(e,t={}){this.store=e;this.queue=t.queue??new c(e.controlPlane)}enqueue(e,t){let r=new Date(t.scheduledFor??this.store.now()).toISOString(),o=`${e.id}:${t.trigger==="manual"?crypto.randomUUID():r}`,m=this.store.activeExecution(e.id);if(m&&e.overlapPolicy==="forbid")return this.store.createExecution({jobId:e.id,trigger:t.trigger,scheduledFor:r,idempotencyKey:o,status:"skipped",output:{reason:"overlap_forbidden",activeExecutionId:m.id}});if(m&&e.overlapPolicy==="replace"&&m.operationId)try{this.queue.requestCancellation(m.operationId,t.actorId)}catch{}let h=this.store.createExecution({jobId:e.id,trigger:t.trigger,scheduledFor:r,idempotencyKey:o,status:"queued",output:{semantics:"at_least_once"}});if(h.operationId)return h;let I=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:t.actorId,kind:"job.execute",input:{jobId:e.id,executionId:h.id},idempotencyKey:`job-execution:${h.id}`,lockKey:e.overlapPolicy==="allow"?`job-execution:${h.id}`:`job:${e.id}`,maxAttempts:e.retryPolicy.maxAttempts,timeoutSeconds:e.timeoutSeconds,retryClasses:["job_transient"],resumePolicy:"requeue"}).operation;return this.store.attachOperation(h.id,I.id)}tick(e=this.store.now()){let t=[];for(let r of this.store.due(e.toISOString())){let o=r.nextRunAt,m=mt(r.normalizedExpression,r.timezone,e,1)[0];if(r.missedRunPolicy==="catch_up"){let h=o,I=0;while(h<=e.toISOString()&&I<10)t.push(this.enqueue(r,{trigger:h===o?"scheduled":"catch_up",scheduledFor:h})),h=mt(r.normalizedExpression,r.timezone,new Date(h),1)[0],I++}else t.push(this.enqueue(r,{trigger:"scheduled",scheduledFor:o}));this.store.markScheduled(r.id,o,m)}return t}}function al(e){return{"job.execute":async(r)=>{let o=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},m=e.store.get(String(o.jobId??"")),h=e.store.getExecution(String(o.executionId??""));if(!m||!h)throw Error("Scheduled job execution is no longer available.");e.store.transitionExecution(h.id,"running",{attempt:r.operation.attempt}),r.checkpoint("execute",`Running ${m.name} on ${m.provider}.`),r.log(`Trigger ${h.trigger}; scheduled for ${h.scheduledFor}; semantics at-least-once.`,{stream:"system"});let I=await e.executor(m,m.target,r);if(I.stdout)r.log(I.stdout,{stream:"stdout"});if(I.stderr)r.log(I.stderr,{stream:"stderr"});if(!I.ok){if(e.store.transitionExecution(h.id,r.operation.attempt>=m.retryPolicy.maxAttempts?"dead":"failed",{attempt:r.operation.attempt,error:I.stderr??"Job execution failed."}),I.retryable)throw new J(I.stderr??"Scheduled job failed transiently.","job_transient");throw Error(I.stderr??"Scheduled job failed.")}return e.store.transitionExecution(h.id,"succeeded",{attempt:r.operation.attempt,output:I.output??{}}),{jobId:m.id,executionId:h.id,provider:m.provider}}}}var pn=(e)=>typeof e==="string"&&e?e:void 0,_h=(e)=>Number(e)===1,Ds=(e)=>{try{return JSON.parse(String(e))}catch{return{}}},is=(e,t,r,o)=>{let m=Number(e);return Number.isFinite(m)?Math.min(o,Math.max(r,Math.floor(m))):t};function Jc(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:pn(e.environment_id),resourceId:pn(e.resource_id),name:String(e.name),provider:String(e.provider),expression:String(e.expression),normalizedExpression:String(e.normalized_expression),timezone:String(e.timezone),startsAt:pn(e.starts_at),endsAt:pn(e.ends_at),flexibleMinutes:Number(e.flexible_minutes),target:Ds(e.target),payloadRefs:Ds(e.payload_refs),missedRunPolicy:String(e.missed_run_policy),overlapPolicy:String(e.overlap_policy),retryPolicy:Ds(e.retry_policy),timeoutSeconds:Number(e.timeout_seconds),enabled:_h(e.enabled),origin:String(e.origin),sourceKey:pn(e.source_key),ownerActorId:pn(e.owner_actor_id),observedState:Ds(e.observed_state),reconciliationStatus:String(e.reconciliation_status),nextRunAt:pn(e.next_run_at),lastScheduledFor:pn(e.last_scheduled_for),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Qc(e){return{id:String(e.id),jobId:String(e.job_id),operationId:pn(e.operation_id),trigger:String(e.trigger),scheduledFor:String(e.scheduled_for),idempotencyKey:String(e.idempotency_key),status:String(e.status),attempt:Number(e.attempt),startedAt:pn(e.started_at),finishedAt:pn(e.finished_at),output:Ds(e.output),error:pn(e.error),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Ap(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:pn(e.environment_id),resourceId:pn(e.resource_id),name:String(e.name),provider:String(e.provider),queue:String(e.queue),processes:Number(e.processes),timeoutSeconds:Number(e.timeout_seconds),restartPolicy:String(e.restart_policy),target:Ds(e.target),enabled:_h(e.enabled),origin:String(e.origin),sourceKey:pn(e.source_key),ownerActorId:pn(e.owner_actor_id),observedState:Ds(e.observed_state),reconciliationStatus:String(e.reconciliation_status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class Do{controlPlane;options;constructor(e,t={}){this.controlPlane=e;this.options=t}now(){return this.options.now?.()??new Date}create(e){if(!e.name.trim())throw Error("Scheduled jobs require a name.");let t=ht(e.expression,e.timezone,this.now(),1),r=crypto.randomUUID(),o=this.now().toISOString(),m=e.startsAt?new Date(e.startsAt).toISOString():void 0,h=e.endsAt?new Date(e.endsAt).toISOString():void 0;if(m&&h&&m>=h)throw Error("Schedule start must be before end.");let I=t.nextRuns.find((R)=>(!m||R>=m)&&(!h||R<=h));return this.controlPlane.database.run("INSERT INTO scheduled_jobs (id,organization_id,project_id,environment_id,resource_id,name,provider,expression,normalized_expression,timezone,starts_at,ends_at,flexible_minutes,target,payload_refs,missed_run_policy,overlap_policy,retry_policy,timeout_seconds,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,next_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name.trim().slice(0,120),e.provider,e.expression,t.normalized,e.timezone,m??null,h??null,is(e.flexibleMinutes,0,0,1440),JSON.stringify(e.target),JSON.stringify(e.payloadRefs),e.missedRunPolicy,e.overlapPolicy,JSON.stringify({maxAttempts:is(e.retryPolicy.maxAttempts,3,1,20),backoffSeconds:is(e.retryPolicy.backoffSeconds,30,0,86400),deadLetterRef:e.retryPolicy.deadLetterRef}),is(e.timeoutSeconds,900,1,86400),e.enabled?1:0,e.origin,e.sourceKey??null,e.ownerActorId??null,JSON.stringify(e.observedState),e.reconciliationStatus,I??null,1,o,o]),this.get(r)}get(e){let t=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE id=?").get(e);return t?Jc(t):void 0}getBySource(e,t,r){let o=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE project_id=? AND environment_id IS ? AND source_key=?").get(e,t??null,r);return o?Jc(o):void 0}list(e,t={}){let r=["project_id=?"],o=[e];if(t.environmentId)r.push("environment_id=?"),o.push(t.environmentId);if(t.resourceIds?.length)r.push(`resource_id IN (${t.resourceIds.map(()=>"?").join(",")})`),o.push(...t.resourceIds);if(t.enabled!=null)r.push("enabled=?"),o.push(t.enabled?1:0);return this.controlPlane.database.query(`SELECT * FROM scheduled_jobs WHERE ${r.join(" AND ")} ORDER BY next_run_at IS NULL,next_run_at,name`).all(...o).map(Jc)}setEnabled(e,t){this.controlPlane.database.run("UPDATE scheduled_jobs SET enabled=?,version=version+1,updated_at=? WHERE id=?",[t?1:0,this.now().toISOString(),e]);let r=this.get(e);if(!r)throw Error("Scheduled job was not found.");return r}updateSchedule(e,t){let r=this.get(e);if(!r)throw Error("Scheduled job was not found.");let o=t.expression??r.expression,m=t.timezone??r.timezone,h=ht(o,m,this.now(),1),I=this.now().toISOString();return this.controlPlane.database.run("UPDATE scheduled_jobs SET expression=?,normalized_expression=?,timezone=?,missed_run_policy=?,overlap_policy=?,timeout_seconds=?,next_run_at=?,reconciliation_status=?,version=version+1,updated_at=? WHERE id=?",[o,h.normalized,m,t.missedRunPolicy??r.missedRunPolicy,t.overlapPolicy??r.overlapPolicy,is(t.timeoutSeconds,r.timeoutSeconds,1,86400),h.nextRuns[0],"pending",I,e]),this.get(e)}remove(e){let t=this.get(e);if(!t)throw Error("Scheduled job was not found.");if(t.origin==="config")throw Error("Config-defined jobs must be removed from configuration, not destructively deleted.");this.controlPlane.database.run("DELETE FROM scheduled_jobs WHERE id=?",[e])}markScheduled(e,t,r){this.controlPlane.database.run("UPDATE scheduled_jobs SET last_scheduled_for=?,next_run_at=?,updated_at=? WHERE id=?",[t,r??null,this.now().toISOString(),e])}reconcile(e,t,r){return this.controlPlane.database.run("UPDATE scheduled_jobs SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[t,JSON.stringify(r),this.now().toISOString(),e]),this.get(e)}upsertConfigJob(e){let t=this.getBySource(e.projectId,e.environmentId,e.sourceKey);if(!t)return this.create(e);let r=ht(e.expression,e.timezone,this.now(),1),o=this.now().toISOString();if(t.resourceId===e.resourceId&&t.name===e.name&&t.provider===e.provider&&t.expression===e.expression&&t.normalizedExpression===r.normalized&&t.timezone===e.timezone&&JSON.stringify(t.target)===JSON.stringify(e.target)&&JSON.stringify(t.payloadRefs)===JSON.stringify(e.payloadRefs)&&t.missedRunPolicy===e.missedRunPolicy&&t.overlapPolicy===e.overlapPolicy&&JSON.stringify(t.retryPolicy)===JSON.stringify(e.retryPolicy)&&t.timeoutSeconds===e.timeoutSeconds&&t.enabled===e.enabled)return t;return this.controlPlane.database.run("UPDATE scheduled_jobs SET resource_id=?,name=?,provider=?,expression=?,normalized_expression=?,timezone=?,target=?,payload_refs=?,missed_run_policy=?,overlap_policy=?,retry_policy=?,timeout_seconds=?,enabled=?,observed_state=?,reconciliation_status=?,next_run_at=COALESCE(next_run_at,?),version=version+1,updated_at=? WHERE id=?",[e.resourceId??null,e.name,e.provider,e.expression,r.normalized,e.timezone,JSON.stringify(e.target),JSON.stringify(e.payloadRefs),e.missedRunPolicy,e.overlapPolicy,JSON.stringify(e.retryPolicy),e.timeoutSeconds,e.enabled?1:0,JSON.stringify(e.observedState),e.reconciliationStatus,r.nextRuns[0],o,t.id]),this.get(t.id)}due(e=this.now().toISOString()){return this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE enabled=1 AND next_run_at IS NOT NULL AND next_run_at<=? AND (starts_at IS NULL OR starts_at<=?) AND (ends_at IS NULL OR ends_at>=?) ORDER BY next_run_at LIMIT 200").all(e,e,e).map(Jc)}createExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE idempotency_key=?").get(e.idempotencyKey);if(t)return Qc(t);let r=crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO job_executions (id,job_id,operation_id,trigger,scheduled_for,idempotency_key,status,attempt,output,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)",[r,e.jobId,e.operationId??null,e.trigger,e.scheduledFor,e.idempotencyKey,e.status,0,JSON.stringify(e.output),o,o]),this.getExecution(r)}getExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE id=?").get(e);return t?Qc(t):void 0}listExecutions(e,t=100){return this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? ORDER BY scheduled_for DESC,created_at DESC LIMIT ?").all(e,Math.min(1000,Math.max(1,t))).map(Qc)}activeExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? AND status IN ('queued','running') ORDER BY created_at DESC LIMIT 1").get(e);return t?Qc(t):void 0}attachOperation(e,t){return this.controlPlane.database.run("UPDATE job_executions SET operation_id=?,updated_at=? WHERE id=?",[t,this.now().toISOString(),e]),this.getExecution(e)}transitionExecution(e,t,r={}){let o=this.now().toISOString(),m=t==="running"?o:null,h=["succeeded","failed","skipped","dead"].includes(t)?o:null;return this.controlPlane.database.run("UPDATE job_executions SET status=?,attempt=COALESCE(?,attempt),started_at=COALESCE(started_at,?),finished_at=?,output=COALESCE(?,output),error=?,updated_at=? WHERE id=?",[t,r.attempt??null,m,h,r.output?JSON.stringify(r.output):null,r.error?.slice(0,2000)??null,o,e]),this.getExecution(e)}upsertWorker(e){let t=e.sourceKey?this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE project_id=? AND source_key=? AND environment_id IS ?").get(e.projectId,e.sourceKey,e.environmentId??null):void 0,r=t?Ap(t):void 0,o=r?.id??crypto.randomUUID(),m=this.now().toISOString(),h=is(e.processes,1,0,1000),I=is(e.timeoutSeconds,60,1,86400);if(r&&r.resourceId===e.resourceId&&r.name===e.name.slice(0,120)&&r.provider===e.provider&&r.queue===e.queue.slice(0,200)&&r.processes===h&&r.timeoutSeconds===I&&r.restartPolicy===e.restartPolicy&&JSON.stringify(r.target)===JSON.stringify(e.target)&&r.enabled===e.enabled)return r;return this.controlPlane.database.run("INSERT INTO worker_definitions (id,organization_id,project_id,environment_id,resource_id,name,provider,queue,processes,timeout_seconds,restart_policy,target,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET name=excluded.name,resource_id=excluded.resource_id,provider=excluded.provider,queue=excluded.queue,processes=excluded.processes,timeout_seconds=excluded.timeout_seconds,restart_policy=excluded.restart_policy,target=excluded.target,enabled=excluded.enabled,observed_state=excluded.observed_state,reconciliation_status=excluded.reconciliation_status,version=worker_definitions.version+1,updated_at=excluded.updated_at",[o,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name.slice(0,120),e.provider,e.queue.slice(0,200),h,I,e.restartPolicy,JSON.stringify(e.target),e.enabled?1:0,e.origin,e.sourceKey??null,e.ownerActorId??null,JSON.stringify(e.observedState),e.reconciliationStatus,1,r?.createdAt??m,m]),this.getWorker(o)}getWorker(e){let t=this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE id=?").get(e);return t?Ap(t):void 0}listWorkers(e,t){return this.controlPlane.database.query(`SELECT * FROM worker_definitions WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(Ap)}setWorkerProcesses(e,t){this.controlPlane.database.run("UPDATE worker_definitions SET processes=?,reconciliation_status='pending',version=version+1,updated_at=? WHERE id=?",[is(t,1,0,1000),this.now().toISOString(),e]);let r=this.getWorker(e);if(!r)throw Error("Worker was not found.");return r}reconcileWorker(e,t,r){this.controlPlane.database.run("UPDATE worker_definitions SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[t,JSON.stringify(r),this.now().toISOString(),e]);let o=this.getWorker(e);if(!o)throw Error("Worker was not found.");return o}}var _t=(e)=>e==null?void 0:String(e),Yc=(e)=>Number(e)===1,os=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}};function xh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),name:String(e.name),provider:String(e.provider),endpoint:_t(e.endpoint),endpointPolicy:String(e.endpoint_policy),bucket:_t(e.bucket),prefix:String(e.prefix),region:_t(e.region),forcePathStyle:Yc(e.force_path_style),credentialRef:_t(e.credential_ref),encryption:String(e.encryption),encryptionKeyRef:_t(e.encryption_key_ref),immutability:os(e.immutability,{}),status:String(e.status),lastTestedAt:_t(e.last_tested_at),lastSuccessAt:_t(e.last_success_at),lastFailureAt:_t(e.last_failure_at),lastError:_t(e.last_error),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Cp(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:_t(e.environment_id),resourceId:_t(e.resource_id),dataServiceId:_t(e.data_service_id),destinationId:String(e.destination_id),name:String(e.name),resourceKind:String(e.resource_kind),schedule:String(e.schedule),timezone:String(e.timezone),retention:os(e.retention,{}),compression:String(e.compression),encryption:String(e.encryption),includePatterns:os(e.include_patterns,[]),excludePatterns:os(e.exclude_patterns,[]),expectedRpoMinutes:Number(e.expected_rpo_minutes),expectedRtoMinutes:Number(e.expected_rto_minutes),healthCheckId:_t(e.health_check_id),enabled:Yc(e.enabled),nextRunAt:_t(e.next_run_at),lastRunAt:_t(e.last_run_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Pp(e){return{id:String(e.id),projectId:String(e.project_id),policyId:_t(e.policy_id),destinationId:String(e.destination_id),resourceId:_t(e.resource_id),dataServiceId:_t(e.data_service_id),backupJobId:_t(e.backup_job_id),kind:String(e.kind),pointInTime:String(e.point_in_time),uri:String(e.uri),sizeBytes:Number(e.size_bytes),checksum:String(e.checksum),manifest:os(e.manifest,{}),toolVersion:_t(e.tool_version),engineVersion:_t(e.engine_version),expiresAt:_t(e.expires_at),lockedUntil:_t(e.locked_until),held:Yc(e.held),pinned:Yc(e.pinned),status:String(e.status),verificationState:String(e.verification_state),verifiedAt:_t(e.verified_at),durationMs:e.duration_ms==null?void 0:Number(e.duration_ms),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function _p(e){return{id:String(e.id),projectId:String(e.project_id),policyId:_t(e.policy_id),recoveryPointId:_t(e.recovery_point_id),operationId:_t(e.operation_id),kind:String(e.kind),status:String(e.status),idempotencyKey:String(e.idempotency_key),target:os(e.target,{}),restoreMode:_t(e.restore_mode),cancellability:String(e.cancellability),safetyBackupId:_t(e.safety_backup_id),healthResult:e.health_result?os(e.health_result,{}):void 0,progress:os(e.progress,{}),error:_t(e.error),startedAt:_t(e.started_at),finishedAt:_t(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function bI(e){let t=e.toLowerCase();if(t==="localhost"||t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".internal"))return!0;if(Th(t)===6)return t==="::1"||t.startsWith("fe80:");if(Th(t)!==4)return!1;let[r,o]=t.split(".").map(Number);return r===10||r===127||r===0||r===169&&o===254||r===172&&o>=16&&o<=31||r===192&&o===168}function Em(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Backup destination names must be 2-63 lowercase letters, numbers, or dashes.");if(e.provider!=="aws_backup"&&!e.bucket)throw Error("S3 backup destinations require a bucket.");if(e.provider==="s3_compatible"&&!e.endpoint)throw Error("S3-compatible destinations require an explicit endpoint.");if(e.provider==="s3_compatible"&&!e.credentialRef)throw Error("S3-compatible destinations require a credential reference.");if(e.encryption!=="provider"&&!e.encryptionKeyRef)throw Error("Client-side encryption requires an encryption key reference.");if(e.endpoint){let t=new URL(e.endpoint);if(t.protocol!=="https:"||t.username||t.password||t.search||t.hash||t.pathname!=="/")throw Error("Backup endpoints must be origin-only HTTPS URLs without credentials, paths, queries, or fragments.");if(bI(t.hostname)&&e.endpointPolicy!=="allow_private")throw Error("Private backup endpoints require endpointPolicy allow_private.")}}class ea{controlPlane;now;constructor(e,t=()=>new Date){this.controlPlane=e;this.now=t}createDestination(e){Em(e);let t=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_destinations (id,organization_id,project_id,name,provider,endpoint,endpoint_policy,bucket,prefix,region,force_path_style,credential_ref,encryption,encryption_key_ref,immutability,status,last_tested_at,last_success_at,last_failure_at,last_error,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.name,e.provider,e.endpoint??null,e.endpointPolicy,e.bucket??null,e.prefix,e.region??null,e.forcePathStyle?1:0,e.credentialRef??null,e.encryption,e.encryptionKeyRef??null,JSON.stringify(e.immutability),e.status,e.lastTestedAt??null,e.lastSuccessAt??null,e.lastFailureAt??null,e.lastError??null,1,r,r]),this.getDestination(t)}getDestination(e){let t=this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE id=?").get(e);return t?xh(t):void 0}listDestinations(e){return this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE project_id=? ORDER BY name").all(e).map(xh)}recordDestinationTest(e,t){let r=this.now().toISOString();return this.controlPlane.database.run("UPDATE backup_destinations SET status=?,last_tested_at=?,last_success_at=CASE WHEN ? THEN ? ELSE last_success_at END,last_failure_at=CASE WHEN ? THEN last_failure_at ELSE ? END,last_error=?,version=version+1,updated_at=? WHERE id=?",[t.ok?"healthy":"failing",r,t.ok?1:0,r,t.ok?1:0,r,t.ok?null:String(t.error??"Destination test failed.").slice(0,1000),r,e]),this.getDestination(e)}createPolicy(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Backup policy names must be lowercase slugs.");if(!e.resourceId&&!e.dataServiceId&&!["control_plane","infrastructure"].includes(e.resourceKind))throw Error("A backup policy requires a resource or data service target.");let t=this.getDestination(e.destinationId);if(!t||t.projectId!==e.projectId)throw Error("Backup destination was not found.");if(e.resourceKind==="control_plane"&&t.encryption==="provider")throw Error("Control-plane backups require client-side destination encryption.");if(["logical_database","volume","files","control_plane"].includes(e.resourceKind)&&t.provider==="aws_backup")throw Error(`${e.resourceKind} backups require an object-storage destination.`);if(e.resourceKind==="infrastructure"&&t.provider!=="aws_backup")throw Error("Infrastructure backups require an AWS Backup destination.");let r=ze(e.schedule),o=mt(r.normalized,e.timezone,this.now(),1)[0],m=crypto.randomUUID(),h=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_policies (id,organization_id,project_id,environment_id,resource_id,data_service_id,destination_id,name,resource_kind,schedule,timezone,retention,compression,encryption,include_patterns,exclude_patterns,expected_rpo_minutes,expected_rto_minutes,health_check_id,enabled,next_run_at,last_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[m,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.dataServiceId??null,e.destinationId,e.name,e.resourceKind,r.normalized,e.timezone,JSON.stringify(e.retention),e.compression,e.encryption,JSON.stringify(e.includePatterns),JSON.stringify(e.excludePatterns),e.expectedRpoMinutes,e.expectedRtoMinutes,e.healthCheckId??null,e.enabled?1:0,o,e.lastRunAt??null,1,h,h]),this.getPolicy(m)}getPolicy(e){let t=this.controlPlane.database.query("SELECT * FROM backup_policies WHERE id=?").get(e);return t?Cp(t):void 0}listPolicies(e,t){return this.controlPlane.database.query(`SELECT * FROM backup_policies WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(Cp)}duePolicies(e=this.now()){return this.controlPlane.database.query("SELECT * FROM backup_policies WHERE enabled=1 AND next_run_at<=? ORDER BY next_run_at,id").all(e.toISOString()).map(Cp)}advancePolicy(e,t){let r=this.getPolicy(e);if(!r)throw Error("Backup policy was not found.");let o=mt(r.schedule,r.timezone,new Date(t),1)[0];return this.controlPlane.database.run("UPDATE backup_policies SET last_run_at=?,next_run_at=?,version=version+1,updated_at=? WHERE id=?",[t,o,this.now().toISOString(),e]),this.getPolicy(e)}createJob(e){let t=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE idempotency_key=?").get(e.idempotencyKey);if(t)return _p(t);let r=crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_jobs (id,project_id,policy_id,recovery_point_id,operation_id,kind,status,idempotency_key,target,restore_mode,cancellability,safety_backup_id,health_result,progress,error,started_at,finished_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.projectId,e.policyId??null,e.recoveryPointId??null,e.operationId??null,e.kind,e.status,e.idempotencyKey,JSON.stringify(e.target),e.restoreMode??null,e.cancellability,e.safetyBackupId??null,e.healthResult?JSON.stringify(e.healthResult):null,JSON.stringify(e.progress),e.error??null,e.startedAt??null,e.finishedAt??null,o,o]),this.getJob(r)}getJob(e){let t=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE id=?").get(e);return t?_p(t):void 0}listJobs(e){return this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE project_id=? ORDER BY created_at DESC").all(e).map(_p)}updateJob(e,t){let r=this.getJob(e);if(!r)throw Error("Backup job was not found.");let o={...r,...t};return this.controlPlane.database.run("UPDATE backup_jobs SET status=?,operation_id=?,recovery_point_id=?,progress=?,health_result=?,error=?,started_at=?,finished_at=?,safety_backup_id=?,updated_at=? WHERE id=?",[o.status,o.operationId??null,o.recoveryPointId??null,JSON.stringify(o.progress),o.healthResult?JSON.stringify(o.healthResult):null,o.error??null,o.startedAt??null,o.finishedAt??null,o.safetyBackupId??null,this.now().toISOString(),e]),this.getJob(e)}createRecoveryPoint(e){if(!/^sha256:[a-f0-9]{64}$/i.test(e.checksum))throw Error("Recovery points require a SHA-256 checksum.");if(typeof e.uri!=="string"||!["s3:","aws-backup:","file:"].some((o)=>e.uri.startsWith(o)))throw Error("Recovery point URI uses an unsupported destination scheme.");let t=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO recovery_points (id,project_id,policy_id,destination_id,resource_id,data_service_id,backup_job_id,kind,point_in_time,uri,size_bytes,checksum,manifest,tool_version,engine_version,expires_at,locked_until,held,pinned,status,verification_state,verified_at,duration_ms,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.projectId,e.policyId??null,e.destinationId,e.resourceId??null,e.dataServiceId??null,e.backupJobId??null,e.kind,e.pointInTime,e.uri,e.sizeBytes,e.checksum,JSON.stringify(e.manifest),e.toolVersion??null,e.engineVersion??null,e.expiresAt??null,e.lockedUntil??null,e.held?1:0,e.pinned?1:0,e.status,e.verificationState,e.verifiedAt??null,e.durationMs??null,r,r]),this.getRecoveryPoint(t)}getRecoveryPoint(e){let t=this.controlPlane.database.query("SELECT * FROM recovery_points WHERE id=?").get(e);return t?Pp(t):void 0}listRecoveryPoints(e,t){return this.controlPlane.database.query(`SELECT * FROM recovery_points WHERE project_id=?${t?" AND policy_id=?":""} ORDER BY point_in_time DESC`).all(e,...t?[t]:[]).map(Pp)}updateRecoveryPoint(e,t){let r=this.getRecoveryPoint(e);if(!r)throw Error("Recovery point was not found.");let o={...r,...t};return this.controlPlane.database.run("UPDATE recovery_points SET status=?,verification_state=?,verified_at=?,held=?,pinned=?,manifest=?,duration_ms=?,updated_at=? WHERE id=?",[o.status,o.verificationState,o.verifiedAt??null,o.held?1:0,o.pinned?1:0,JSON.stringify(o.manifest),o.durationMs??null,this.now().toISOString(),e]),this.getRecoveryPoint(e)}retentionCandidates(e=this.now()){let t=this.controlPlane.database.query(`SELECT rp.* FROM recovery_points rp
80
80
  WHERE rp.status='available' AND rp.held=0 AND rp.pinned=0
81
81
  AND rp.expires_at IS NOT NULL AND rp.expires_at<=?
82
82
  AND (rp.locked_until IS NULL OR rp.locked_until<=?)
@@ -84,7 +84,7 @@ ${o} root /usr/local/bin/cloud jobs:dispatch ${e.id} --scheduled >/dev/null 2>&1
84
84
  SELECT 1 FROM backup_jobs bj WHERE bj.recovery_point_id=rp.id
85
85
  AND bj.kind IN ('restore','drill') AND bj.status IN ('queued','running','cleanup_required')
86
86
  )
87
- ORDER BY rp.expires_at,rp.id`).all(e.toISOString(),e.toISOString()).map(Pp),r=new Set;for(let o of new Set(t.map((m)=>m.projectId)))for(let m of this.listPolicies(o)){let h=this.listRecoveryPoints(m.projectId,m.id).filter((R)=>R.status==="available").sort((R,A)=>A.pointInTime.localeCompare(R.pointInTime));for(let R of h.slice(0,Math.max(0,m.retention.keepLast??0)))r.add(R.id);let I=[[m.retention.hourly,(R)=>R.toISOString().slice(0,13)],[m.retention.daily,(R)=>R.toISOString().slice(0,10)],[m.retention.weekly,(R)=>new Date(Date.UTC(R.getUTCFullYear(),R.getUTCMonth(),R.getUTCDate()-(R.getUTCDay()+6)%7)).toISOString().slice(0,10)],[m.retention.monthly,(R)=>R.toISOString().slice(0,7)]];for(let[R,A]of I){let E=new Set;for(let x of h){let N=A(new Date(x.pointInTime));if(E.has(N))continue;if(E.add(N),E.size<=Math.max(0,R??0))r.add(x.id)}}}return t.filter((o)=>!r.has(o.id))}coverage(e,t=this.now()){let r=new Map(this.listDestinations(e).map((o)=>[o.id,o]));return this.listPolicies(e).map((o)=>{let m=this.listRecoveryPoints(e,o.id).filter((R)=>R.status==="available"),h=m[0],I=h?(t.getTime()-new Date(h.pointInTime).getTime())/60000:Number.POSITIVE_INFINITY;return{policy:o,lastRecoveryPoint:h,missedRpo:o.enabled&&I>o.expectedRpoMinutes,unverified:m.filter((R)=>R.verificationState!=="verified").length,destinationHealthy:r.get(o.destinationId)?.status==="healthy"}})}}import{createCipheriv as SI,createDecipheriv as wI,createHash as Dh,randomBytes as Oh}from"node:crypto";var Tp=Buffer.from("TSCB1"),Zc=(e)=>`sha256:${Dh("sha256").update(e).digest("hex")}`;function $h(e){return Dh("sha256").update(e).digest()}function vm(e,t,r){let o=r?Buffer.from(r):Oh(12);if(o.length!==12)throw Error("Backup encryption IV must contain 12 bytes.");let m=SI("aes-256-gcm",$h(t),o),h=Buffer.concat([m.update(e),m.final()]),I=m.getAuthTag();return Buffer.concat([Tp,o,I,h])}function Tm(e,t){let r=Buffer.from(e);if(!r.subarray(0,Tp.length).equals(Tp))throw Error("Backup does not contain a valid encrypted envelope.");let o=r.subarray(5,17),m=r.subarray(17,33),h=r.subarray(33),I=wI("aes-256-gcm",$h(t),o);return I.setAuthTag(m),Buffer.concat([I.update(h),I.final()])}function kI(e){let t;try{t=JSON.parse(e)}catch{throw Error("Backup destination credential must be a JSON object with accessKeyId and secretAccessKey.")}if(!t.accessKeyId||!t.secretAccessKey)throw Error("Backup destination credential requires accessKeyId and secretAccessKey.");if(t.expiresAt){let r=new Date(String(t.expiresAt));if(!Number.isFinite(r.getTime()))throw Error("Backup destination credential expiresAt must be an ISO timestamp.");if(r.getTime()<=Date.now())throw Error("Backup destination credential has expired.")}return{accessKeyId:String(t.accessKeyId),secretAccessKey:String(t.secretAccessKey),sessionToken:t.sessionToken?String(t.sessionToken):void 0}}async function xl(e,t,r=new Date){if(!e.credentialRef)return{status:"default"};try{let o=JSON.parse(await t.resolve(e.credentialRef));if(!o.accessKeyId||!o.secretAccessKey)return{status:"invalid"};if(!o.expiresAt)return{status:"static"};let m=new Date(String(o.expiresAt));if(!Number.isFinite(m.getTime()))return{status:"invalid"};let h=m.getTime()-r.getTime();return{status:h<=0?"expired":h<=604800000?"expiring":"valid",expiresAt:m.toISOString()}}catch{return{status:"invalid"}}}class ta{secrets;clientFactory;multipartThreshold;partSize;constructor(e,t=(m,h)=>new a(m.region??"us-east-1",void 0,{endpoint:m.endpoint?new URL(m.endpoint).host:void 0,forcePathStyle:m.forcePathStyle,credentials:h}),r=8388608,o=8388608){this.secrets=e;this.clientFactory=t;this.multipartThreshold=r;this.partSize=o}async client(e){let t=e.credentialRef?kI(await this.secrets.resolve(e.credentialRef)):void 0;return this.clientFactory(e,t)}async test(e){if(!e.bucket)throw Error("S3 destination has no configured bucket.");let t=await this.client(e),r=`${e.prefix?`${e.prefix.replace(/\/$/,"")}/`:""}.ts-cloud-health/${crypto.randomUUID()}`;await t.putObject({bucket:e.bucket,key:r,body:"ts-cloud backup destination health check",contentType:"text/plain"});try{let o=await t.getObjectBytes(e.bucket,r);if(Buffer.from(o.body).toString()!=="ts-cloud backup destination health check")throw Error("Backup destination health object was corrupted.")}finally{await t.deleteObject(e.bucket,r)}}async upload(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(e),o=Zc(t.body),m=e.encryption!=="provider"?await this.secrets.resolve(e.encryptionKeyRef):void 0,h=m?t.resume?.encryptionIv?Buffer.from(t.resume.encryptionIv,"base64url"):Oh(12):void 0,I=m?vm(t.body,m,h):Buffer.from(t.body),R=Zc(I),A=`${e.prefix?`${e.prefix.replace(/\/$/,"")}/`:""}${t.key.replace(/^\/+/,"")}`,E=t.contentType??"application/octet-stream",x={"ts-cloud-format":"v1","ts-cloud-sha256":R.slice(7),"ts-cloud-encrypted":m?"true":"false"};if(t.resume&&t.resume.key!==A)throw Error("Multipart checkpoint does not match the requested backup key.");if(t.resume&&m&&!t.resume.encryptionIv)throw Error("Encrypted multipart checkpoint has no resumable envelope state.");if(t.resume&&m&&t.resume.plaintextChecksum!==o)throw Error("Encrypted multipart checkpoint does not match the backup payload.");if(I.length<this.multipartThreshold)await r.putObject({bucket:e.bucket,key:A,body:I,contentType:E,metadata:x});else{let N=t.resume?void 0:await r.createMultipartUpload(e.bucket,A,{contentType:E,metadata:x}),F=t.resume??{uploadId:N.UploadId,key:A,parts:[],bytesUploaded:0,encryptionIv:h?.toString("base64url"),plaintextChecksum:o},z=new Map(F.parts.map((K)=>[K.PartNumber,K])),H=Math.ceil(I.length/this.partSize);for(let K=0;K<H;K++){let X=K+1;if(!z.has(X)){let oe=K*this.partSize,ye=await r.uploadPart(e.bucket,A,F.uploadId,X,I.subarray(oe,Math.min(I.length,oe+this.partSize)));z.set(X,{PartNumber:X,ETag:ye.ETag})}F.parts=[...z.values()].sort((oe,ye)=>oe.PartNumber-ye.PartNumber),F.bytesUploaded=Math.min(I.length,X*this.partSize),t.checkpoint?.(F)}await r.completeMultipartUpload(e.bucket,A,F.uploadId,F.parts)}return{uri:`s3://${e.bucket}/${A}`,key:A,sizeBytes:I.length,checksum:R,manifest:{format:"ts-cloud-backup-v1",encrypted:!!m,plaintextChecksum:o,storageChecksum:R,contentType:E}}}async download(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(e),o=await r.getObjectBytes(e.bucket,t.key),m=Buffer.from(o.body);if(Zc(m)!==t.checksum)throw Error("Backup checksum verification failed; object is corrupt.");let h=t.manifest.encrypted?Tm(m,await this.secrets.resolve(e.encryptionKeyRef)):m;if(Zc(h)!==t.manifest.plaintextChecksum)throw Error("Backup plaintext checksum verification failed.");return h}async abortPartial(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(e)).abortMultipartUpload(e.bucket,t.key,t.uploadId)}async delete(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(e)).deleteObject(e.bucket,t)}}import{createHash as II}from"node:crypto";var EI=(e)=>`sha256:${II("sha256").update(e).digest("hex")}`;class Mi{store;queue;now;constructor(e,t,r=()=>new Date){this.store=e;this.queue=t;this.now=r}enqueueBackup(e,t=this.now().toISOString(),r){if(!e.enabled)throw Error("Backup policy is disabled.");let o=this.store.createJob({projectId:e.projectId,policyId:e.id,kind:"backup",status:"queued",idempotencyKey:`backup:${e.id}:${t}`,target:{scheduledFor:t},cancellability:"checkpoint_only",progress:{phase:"queued"}});if(!o.operationId){let m=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:r,kind:"backup.run",input:{backupJobId:o.id},lockKey:e.dataServiceId?`data-service:${e.dataServiceId}`:e.resourceId?`resource:${e.resourceId}`:`backup-policy:${e.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:14400,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(o.id,{operationId:m.operation.id})}return o}enqueueDue(e=this.now()){return this.store.duePolicies(e).map((t)=>{let r=t.nextRunAt;return this.store.advancePolicy(t.id,r),this.enqueueBackup(t,r)})}enqueueVerification(e){let t=this.store.createJob({projectId:e.projectId,policyId:e.policyId,recoveryPointId:e.id,kind:"verify",status:"queued",idempotencyKey:`verify:${e.id}:${e.checksum}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!t.operationId){let r=this.queue.enqueue({projectId:e.projectId,resourceId:e.resourceId,kind:"backup.verify",input:{backupJobId:t.id},lockKey:`recovery-point:${e.id}`,providerKey:"backup",maxAttempts:2,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(t.id,{operationId:r.operation.id})}return t}planRestore(e,t){if(e.status!=="available")throw Error("Only available recovery points can be restored.");if(e.verificationState!=="verified")throw Error("Restore requires a verified recovery point.");if(t.mode==="in_place"){if(!t.recentAuth)throw Error("In-place restore requires recent authentication.");if(t.confirm!==t.targetName)throw Error(`Type ${t.targetName} to confirm in-place restore.`);if(!t.downtimeAcknowledged)throw Error("In-place restore requires downtime acknowledgement.");let r=t.safetyBackupId?this.store.getRecoveryPoint(t.safetyBackupId):void 0;if(!r||r.id===e.id||r.status!=="available"||r.verificationState!=="verified"||r.resourceId!==e.resourceId||r.dataServiceId!==e.dataServiceId)throw Error("In-place restore requires a distinct verified safety backup for the same target.")}return{point:e,mode:t.mode,target:{...t.target,inPlace:t.mode==="in_place",restoreMode:t.mode},warnings:t.mode==="in_place"?["The target is locked against deployments and backup work.","Downtime and data replacement are expected.","Provider cancellation may stop only at a checkpoint."]:["An isolated target is created and health-validated before cleanup."]}}enqueueRestore(e,t){let r=this.planRestore(e,t),o=t.drill?"drill":"restore",m=EI(JSON.stringify({point:e.id,mode:t.mode,target:t.target,safety:t.safetyBackupId,drill:!!t.drill})),h=this.store.createJob({projectId:e.projectId,policyId:e.policyId,recoveryPointId:e.id,kind:o,status:"queued",idempotencyKey:`${o}:${m}`,target:r.target,restoreMode:r.mode,cancellability:"checkpoint_only",safetyBackupId:t.safetyBackupId,progress:{phase:"queued",warnings:r.warnings}});if(!h.operationId){let I=this.queue.enqueue({projectId:e.projectId,resourceId:e.resourceId,actorId:t.actorId,kind:t.drill?"backup.drill":"backup.restore",input:{backupJobId:h.id},lockKey:e.dataServiceId?`data-service:${e.dataServiceId}`:e.resourceId?`resource:${e.resourceId}`:`recovery-point:${e.id}`,providerKey:"backup",maxAttempts:1,timeoutSeconds:14400,retryClasses:[],resumePolicy:"fail"});return this.store.updateJob(h.id,{operationId:I.operation.id})}return h}enqueueRetention(e=this.now()){return this.store.retentionCandidates(e).map((t)=>{let r=this.store.createJob({projectId:t.projectId,policyId:t.policyId,recoveryPointId:t.id,kind:"cleanup",status:"queued",idempotencyKey:`cleanup:${t.id}:${t.expiresAt}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!r.operationId){let o=this.queue.enqueue({projectId:t.projectId,resourceId:t.resourceId,kind:"backup.cleanup",input:{backupJobId:r.id},lockKey:`recovery-point:${t.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(r.id,{operationId:o.operation.id})}return r})}}function _l(e){let t=e.now??(()=>new Date),r=new Mi(e.store,e.queue,t),o=(R)=>{let A=R.recoveryPointId?e.store.getRecoveryPoint(R.recoveryPointId):void 0,E=R.policyId?e.store.getPolicy(R.policyId):A?.policyId?e.store.getPolicy(A.policyId):void 0;if(!E)throw Error("Backup policy was not found.");let x=e.store.getDestination(A?.destinationId??E.destinationId),N=e.resolveSource(E);if(!x)throw Error("Backup destination was not found.");if(!N)throw Error(`No ${E.resourceKind} backup adapter is configured.`);return{point:A,policy:E,destination:x,source:N}},m=(R)=>{let A=R.operation.input,E=e.store.getJob(String(A.backupJobId??""));if(!E)throw Error("Backup job was not found.");return e.store.updateJob(E.id,{status:"running",startedAt:E.startedAt??t().toISOString(),progress:{...E.progress,phase:"running"}}),E},h=(R,A)=>{let E=e.store.getJob(R.id)??R;e.store.updateJob(R.id,{status:"failed",finishedAt:t().toISOString(),error:A instanceof Error?A.message:String(A),progress:{...E.progress,phase:"failed"}})};return{"backup.run":async(R)=>{let A=m(R);try{let{policy:E,destination:x,source:N}=o(A),F=await N.create(E,R),z=e.resolveDestination(x),H=F.mode==="object"?await(async()=>{if(!z)throw Error("Backup destination adapter is not configured.");let ye=e.store.getJob(A.id)?.progress,ne=ye?.multipart,fe=ne&&typeof ne==="object"&&!Array.isArray(ne)&&typeof ne.uploadId==="string"&&typeof ne.key==="string"&&Array.isArray(ne.parts)?ne:void 0;return z.upload(x,{key:F.key,body:F.body,contentType:F.contentType,resume:fe,checkpoint:(Ce)=>{R.checkpoint("uploading",`Uploaded ${Number(Ce.bytesUploaded??0)} backup bytes.`),e.store.updateJob(A.id,{progress:{phase:"uploading",multipart:{...Ce}}})}})})():{uri:F.uri,key:F.uri,sizeBytes:F.sizeBytes,checksum:F.checksum,manifest:{format:"ts-cloud-backup-v1",encrypted:!1,plaintextChecksum:F.checksum,storageChecksum:F.checksum,contentType:"application/provider-snapshot"}},K=E.retention.expireAfterDays?new Date(t().getTime()+E.retention.expireAfterDays*86400000).toISOString():void 0,X=e.store.getJob(A.id)?.startedAt,oe=e.store.createRecoveryPoint({projectId:E.projectId,policyId:E.id,destinationId:x.id,resourceId:E.resourceId,dataServiceId:E.dataServiceId,backupJobId:A.id,kind:E.resourceKind,pointInTime:t().toISOString(),uri:H.uri,sizeBytes:H.sizeBytes,checksum:H.checksum,manifest:{...F.manifest,...H.manifest,storageKey:H.key},toolVersion:F.toolVersion,engineVersion:F.engineVersion,expiresAt:K,lockedUntil:x.immutability.defaultRetentionDays?new Date(t().getTime()+x.immutability.defaultRetentionDays*86400000).toISOString():void 0,held:!1,pinned:!1,status:"available",verificationState:"unverified",durationMs:Math.max(0,t().getTime()-new Date(X??t().toISOString()).getTime())});if(F.mode==="external"&&x.provider==="aws_backup")e.store.recordDestinationTest(x.id,{ok:!0});return e.store.updateJob(A.id,{status:"succeeded",recoveryPointId:oe.id,finishedAt:t().toISOString(),progress:{phase:"stored",recoveryPointId:oe.id}}),r.enqueueVerification(oe),{backupJobId:A.id,recoveryPointId:oe.id}}catch(E){let x=e.store.getJob(A.id),N=x?.progress.multipart,F=(()=>{try{return o(A)}catch{return}})();if(F?.destination.provider==="aws_backup")e.store.recordDestinationTest(F.destination.id,{ok:!1,error:E instanceof Error?E.message:String(E)});let z=!1;if(N&&typeof N==="object"&&!Array.isArray(N)&&F){let H=e.resolveDestination(F.destination);if(z=!0,H?.abortPartial)try{await H.abortPartial(F.destination,N),z=!1,e.store.updateJob(A.id,{progress:{...x.progress,partialCleanup:"aborted"}})}catch{e.store.updateJob(A.id,{progress:{...x.progress,partialCleanup:"required"}})}}if(z)e.store.updateJob(A.id,{status:"cleanup_required",finishedAt:t().toISOString(),error:E instanceof Error?E.message:String(E),progress:{...e.store.getJob(A.id)?.progress??{},phase:"cleanup_required"}});else h(A,E);throw E}},"backup.verify":async(R)=>{let A=m(R);try{let{point:E,destination:x,source:N}=o(A);if(!E)throw Error("Recovery point was not found.");e.store.updateRecoveryPoint(E.id,{verificationState:"verifying"});let F;if(E.uri.startsWith("s3:")){let z=e.resolveDestination(x);if(!z)throw Error("Backup destination adapter is not configured.");let H=await z.download(x,{key:String(E.manifest.storageKey??""),checksum:E.checksum,manifest:E.manifest}),K=N.verify?await N.verify(E,H,R):{};F={bytes:H.length,checksum:E.checksum,...K}}else if(N.verifyExternal)F=await N.verifyExternal(E,R);else throw Error("External recovery point verification is not supported.");return e.store.updateRecoveryPoint(E.id,{verificationState:"verified",verifiedAt:t().toISOString(),manifest:{...E.manifest,verification:F}}),e.store.updateJob(A.id,{status:"succeeded",finishedAt:t().toISOString(),progress:{phase:"verified",evidence:F}}),{backupJobId:A.id,recoveryPointId:E.id,evidence:F}}catch(E){if(A.recoveryPointId)e.store.updateRecoveryPoint(A.recoveryPointId,{verificationState:/checksum|corrupt|authentic/i.test(E instanceof Error?E.message:String(E))?"corrupt":"failed"});throw h(A,E),E}},"backup.restore":async(R)=>I(R,!1),"backup.drill":async(R)=>I(R,!0),"backup.cleanup":async(R)=>{let A=m(R);try{let{point:E,destination:x,source:N}=o(A);if(!E)throw Error("Recovery point was not found.");if(!e.store.retentionCandidates(t()).some((F)=>F.id===E.id))throw Error("Recovery point is held, pinned, locked, or in active use.");if(e.store.updateRecoveryPoint(E.id,{status:"deleting"}),E.uri.startsWith("s3:")){let F=e.resolveDestination(x);if(!F)throw Error("Destination cleanup is unavailable.");await F.delete(x,String(E.manifest.storageKey??""))}else if(N.deleteExternal)await N.deleteExternal(E,R);else throw Error("External recovery point cleanup is unavailable.");return e.store.updateRecoveryPoint(E.id,{status:"deleted"}),e.store.updateJob(A.id,{status:"succeeded",finishedAt:t().toISOString(),progress:{phase:"deleted"}}),{backupJobId:A.id,recoveryPointId:E.id,deleted:!0}}catch(E){throw h(A,E),E}}};async function I(R,A){let E=m(R);try{let{point:x,policy:N,destination:F,source:z}=o(E);if(!x)throw Error("Recovery point was not found.");if(A&&!z.cleanup)throw Error("This backup source cannot safely clean a recovery drill target.");let H=x.uri.startsWith("s3:")?e.resolveDestination(F):void 0,K=H?await H.download(F,{key:String(x.manifest.storageKey??""),checksum:x.checksum,manifest:x.manifest}):void 0,X=await z.restore(x,K,E.target,R),oe=z.validateHealth?await z.validateHealth({...E.target,...X},R):{healthy:!0,mode:"adapter"},ye=e.validateHealth?await e.validateHealth(N,E.target):{healthy:!0,mode:"not_configured"},ne={...oe,healthy:oe.healthy===!0&&ye.healthy===!0,configured:ye};if(ne.healthy!==!0)throw Error("Restored target did not pass its configured health check.");if(A&&z.cleanup)await z.cleanup({...E.target,provider:x.manifest.provider??null},R);return e.store.updateJob(E.id,{status:"succeeded",finishedAt:t().toISOString(),healthResult:ne,progress:{phase:A?"drill_cleaned":"restored",restored:X}}),{backupJobId:E.id,recoveryPointId:x.id,restored:X,health:ne,cleaned:A}}catch(x){let N=(()=>{try{return o(E)}catch{return}})(),F=x instanceof Error?x.message:String(x),z=!1;if(A&&N?.source.cleanup)try{await N.source.cleanup({...E.target,provider:N.point?.manifest.provider??null},R)}catch{z=!0}if(z)e.store.updateJob(E.id,{status:"cleanup_required",finishedAt:t().toISOString(),error:F,progress:{...E.progress,phase:"cleanup_required"}});else h(E,x);throw x}}}import{createHash as RI}from"node:crypto";var AI=(e)=>`sha256:${RI("sha256").update(e).digest("hex")}`;class ra{dataServices;client;constructor(e,t=new j){this.dataServices=e;this.client=t}service(e){let t=e.dataServiceId?this.dataServices.get(e.dataServiceId):void 0;if(!t||!["aws_rds","aws_aurora"].includes(t.provider))throw Error("Managed database backup policy requires an RDS or Aurora data service.");return t}async waitForSnapshot(e,t,r){for(;;){r.throwIfCancellationRequested?.(),r.heartbeat?.();let o=e==="aws_aurora"?(await this.client.describeDBClusterSnapshots({DBClusterSnapshotIdentifier:t})).DBClusterSnapshots[0]:(await this.client.describeDBSnapshots({DBSnapshotIdentifier:t})).DBSnapshots?.[0];if(!o)throw Error("Provider snapshot was not found.");let m=o,h=String(m.Status??m.DBSnapshotStatus??"unknown");if(r.checkpoint?.("provider_snapshot",`Database snapshot ${t} is ${h}.`),h==="available")return m;if(["deleted","deleting","failed"].includes(h))throw Error(`Provider snapshot ${t} failed with state ${h}.`);await Bun.sleep(5000)}}async create(e,t){let r=this.service(e),o=String(t.operation?.id??new Date().toISOString()).replace(/[^A-Za-z0-9]/g,"").slice(0,20),m=`${r.placement.slice(0,42).replace(/-+$/,"")}-${o}`;if(r.provider==="aws_aurora")await this.client.createDBClusterSnapshot(r.placement,m);else await this.client.createDBSnapshot({DBInstanceIdentifier:r.placement,DBSnapshotIdentifier:m});await this.waitForSnapshot(r.provider,m,t);let h=`${r.provider}:${r.placement}:${m}`;return{mode:"external",uri:`aws-backup:${h}`,checksum:AI(h),sizeBytes:0,manifest:{provider:r.provider,sourceId:r.placement,snapshotId:m,plan:r.plan,engine:r.engine},engineVersion:r.engineVersion,toolVersion:"aws-rds-api-2014-10-31"}}async verifyExternal(e,t){let r=String(e.manifest.snapshotId??""),o=String(e.manifest.provider??"");if(!r)throw Error("Snapshot recovery point has no snapshot ID.");let m=await this.waitForSnapshot(o,r,t),h=String(m.Status??m.DBSnapshotStatus??"unknown");return{snapshotId:r,status:h,encrypted:m.Encrypted??m.StorageEncrypted??!0}}async restore(e,t,r,o){let m=String(r.targetId??""),h=String(e.manifest.snapshotId??""),I=String(e.manifest.provider??"");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(m))throw Error("Managed restore requires a valid distinct targetId.");if(m===e.manifest.sourceId)throw Error("Managed restore target must differ from its source.");if(I==="aws_aurora"){let R=e.manifest.engine==="postgres"?"aurora-postgresql":"aurora-mysql";await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:m,SnapshotIdentifier:h,Engine:R,EngineVersion:e.engineVersion,DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Number(r.minCapacity)||0.5,MaxCapacity:Number(r.maxCapacity)||4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${m}-writer-1`,DBClusterIdentifier:m,DBInstanceClass:String(r.plan??e.manifest.plan??"db.serverless"),Engine:R,PubliclyAccessible:!1})}else await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:m,DBSnapshotIdentifier:h,DBInstanceClass:String(r.plan??e.manifest.plan??""),PubliclyAccessible:!1,DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud-restore"}]});return{targetId:m,provider:I,status:"creating",isolated:!0}}async validateHealth(e,t){let r=String(e.targetId??""),o=String(e.provider??"");for(;;){t.throwIfCancellationRequested?.(),t.heartbeat?.();let m=o==="aws_aurora"?(await this.client.describeDBClusters({DBClusterIdentifier:r})).DBClusters?.[0]:(await this.client.describeDBInstances({DBInstanceIdentifier:r})).DBInstances?.[0];if(!m)throw Error("Restored managed database was not found.");let h=String(m.Status??m.DBInstanceStatus??"unknown");if(t.checkpoint?.("provider_restore",`Restored database ${r} is ${h}.`),h==="available")return{healthy:!0,targetId:r,provider:o,status:h};if(["deleted","deleting","failed","incompatible-restore"].includes(h))throw Error(`Restored managed database ${r} failed with state ${h}.`);await Bun.sleep(5000)}}async cleanup(e,t){let r=String(e.targetId??""),o=String(e.provider??"");if(!r)throw Error("Restore cleanup target is required.");if(o==="aws_aurora")await this.client.deleteDBInstance({DBInstanceIdentifier:`${r}-writer-1`,SkipFinalSnapshot:!0}),await this.client.modifyDBCluster({DBClusterIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(r);else await this.client.modifyDBInstance({DBInstanceIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:r,SkipFinalSnapshot:!0,DeleteAutomatedBackups:!0})}async deleteExternal(e,t){let r=String(e.manifest.snapshotId??"");if(e.manifest.provider==="aws_aurora")await this.client.deleteDBClusterSnapshot(r);else await this.client.deleteDBSnapshot(r)}}var mn=(e,t="none",r=!1)=>({supported:!0,downtime:t,destructive:r,explanation:e}),on=(e)=>({supported:!1,downtime:"none",destructive:!1,explanation:e});function Gr(e,t){let r=["aws_rds","aws_aurora","aws_elasticache"].includes(t),o=["server","container"].includes(t),m=["postgres","mysql","mariadb"].includes(e),h=e==="redis",I={};return I.create=t==="external"?on("External services can be adopted as read-only inventory."):mn(r?"Provision through the provider API.":"Provision through the owning runtime driver.","possible"),I.observe=t==="external"?on("External observation requires a configured provider adapter."):mn("Provider/runtime health and endpoint metadata are observable."),I.connect=mn("Connection guidance uses secret references and never returns a password by default."),I.backup=m&&(r||o)?mn(r?"Create a provider snapshot.":"Create a consistent engine-native dump.","possible"):on("This cache path is not a durable backup source."),I.restore=r&&m?mn("Restore creates a reviewed provider target.","required",!0):on("Restore requires a configured provider restore runner."),I.restart=t==="external"?on("External restart requires a configured provider adapter."):mn(r?"Provider restart/failover semantics apply.":"Restart the owning service unit.","required"),I.resize=t==="aws_elasticache"?on("ElastiCache resizing requires a replication-group migration runner."):r?mn("Provider plan/storage modification may enter a maintenance window.","possible"):o?mn("Edit host/container resources and reconcile.","required"):on("External resize requires a configured provider adapter."),I.version=o?on("Runtime version upgrades require an explicit image migration runner."):r&&t!=="aws_elasticache"?mn(m?"Major versions require compatibility preflight and backup.":"Engine upgrades require a maintenance window.","required"):on("External upgrades require a configured provider adapter."),I.rotate=t==="aws_elasticache"||t==="external"||o&&!m&&!h?on("Credential rotation is not available for this provider/engine path."):mn("Rotate through the secret backend, update the engine, then flag dependent releases."),I.expose=o?on("Direct container publishing is refused; use a reviewed firewall and proxy policy."):t==="aws_rds"?mn("Exposure is reconciled through security groups; public access defaults off."):on("Exposure changes require a provider-specific network runner."),I.delete=t==="external"?on("External deletion requires a configured provider adapter."):mn(r?"Final snapshot is supported where the provider allows it.":"A final engine backup is required unless explicitly retained.","required",!0),I.logs=o?mn("Read bounded service logs from the runtime."):on("Provider log export is not configured for this adapter."),I.slow_queries=o&&m?mn("Read bounded runtime logs after engine slow-query logging is enabled."):on("A slow-query log runner is not configured for this provider."),I.users=o&&m?mn("Logical users can be listed; creation requires a referenced secondary credential."):on("User management requires an engine connection runner."),I.databases=o&&m?mn("Logical databases can be listed, created, and confirmation-gated for deletion."):on("Logical database management requires an engine connection runner."),{actions:I,endpointTypes:r?["internal","external","tunnel"]:["internal","tunnel"],metrics:h?["connections","memory","evictions","hit_rate","latency"]:["connections","cpu","storage","read_latency","write_latency","iops"]}}var wa=(e)=>e==null?void 0:String(e),td=(e)=>Number(e)===1,ed=(e)=>{try{return JSON.parse(String(e))}catch{return{}}};function Nh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:wa(e.environment_id),resourceId:wa(e.resource_id),name:String(e.name),engine:String(e.engine),provider:String(e.provider),placement:String(e.placement),engineVersion:wa(e.engine_version),plan:String(e.plan),storageGb:e.storage_gb==null?void 0:Number(e.storage_gb),highAvailability:td(e.high_availability),publicExposure:td(e.public_exposure),allowedCidrs:ed(e.allowed_cidrs),desiredState:ed(e.desired_state),observedState:ed(e.observed_state),capabilities:ed(e.capabilities),credentialRef:wa(e.credential_ref),status:String(e.status),origin:String(e.origin),managementEnabled:td(e.management_enabled),ownerActorId:wa(e.owner_actor_id),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class ko{controlPlane;now;constructor(e,t=()=>new Date){this.controlPlane=e;this.now=t}create(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Data service names must be 2-63 lowercase letters, numbers, or dashes.");if(e.publicExposure&&(!e.allowedCidrs.length||e.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");let t=crypto.randomUUID(),r=this.now().toISOString(),o=Gr(e.engine,e.provider);return this.controlPlane.database.run("INSERT INTO data_services (id,organization_id,project_id,environment_id,resource_id,name,engine,provider,placement,engine_version,plan,storage_gb,high_availability,public_exposure,allowed_cidrs,desired_state,observed_state,capabilities,credential_ref,status,origin,management_enabled,owner_actor_id,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name,e.engine,e.provider,e.placement,e.engineVersion??null,e.plan,e.storageGb??null,e.highAvailability?1:0,e.publicExposure?1:0,JSON.stringify(e.allowedCidrs),JSON.stringify(e.desiredState),JSON.stringify(e.observedState),JSON.stringify(o),e.credentialRef??null,e.status,e.origin,e.managementEnabled?1:0,e.ownerActorId??null,1,r,r]),this.get(t)}get(e){let t=this.controlPlane.database.query("SELECT * FROM data_services WHERE id=?").get(e);return t?Nh(t):void 0}list(e,t){return this.controlPlane.database.query(`SELECT * FROM data_services WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(Nh)}update(e,t,r){let o=this.get(e);if(!o)throw Error("Data service was not found.");if(o.version!==t)throw Error("Data service changed; refresh before retrying.");let m={...o,...r};if(m.publicExposure&&(!m.allowedCidrs.length||m.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");if(this.controlPlane.database.run("UPDATE data_services SET plan=?,storage_gb=?,engine_version=?,high_availability=?,public_exposure=?,allowed_cidrs=?,desired_state=?,observed_state=?,status=?,management_enabled=?,credential_ref=?,version=version+1,updated_at=? WHERE id=? AND version=?",[m.plan,m.storageGb??null,m.engineVersion??null,m.highAvailability?1:0,m.publicExposure?1:0,JSON.stringify(m.allowedCidrs),JSON.stringify(m.desiredState),JSON.stringify(m.observedState),m.status,m.managementEnabled?1:0,m.credentialRef??null,this.now().toISOString(),e,t]).changes!==1)throw Error("Data service changed; refresh before retrying.");return this.get(e)}credential(e){let t=this.controlPlane.database.query("SELECT * FROM data_service_credentials WHERE service_id=? ORDER BY version DESC LIMIT 1").get(e);return t?{id:String(t.id),serviceId:String(t.service_id),username:String(t.username),secretRef:String(t.secret_ref),version:Number(t.version),createdAt:String(t.created_at),rotatedAt:wa(t.rotated_at)}:void 0}saveCredential(e,t,r){let o=this.credential(e),m=o?.id??crypto.randomUUID(),h=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_credentials (id,service_id,username,secret_ref,version,created_at,rotated_at) VALUES (?,?,?,?,?,?,?) ON CONFLICT(service_id,username) DO UPDATE SET secret_ref=excluded.secret_ref,version=data_service_credentials.version+1,rotated_at=excluded.rotated_at",[m,e,t,r,o?.version??1,o?.createdAt??h,o?h:null]),this.credential(e)}addDependency(e){let t=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_dependencies (service_id,resource_id,secret_ref,requires_redeploy,created_at) VALUES (?,?,?,?,?) ON CONFLICT(service_id,resource_id) DO UPDATE SET secret_ref=excluded.secret_ref,requires_redeploy=excluded.requires_redeploy",[e.serviceId,e.resourceId,e.secretRef,e.requiresRedeploy?1:0,t]),{...e,createdAt:t}}dependencies(e){return this.controlPlane.database.query("SELECT * FROM data_service_dependencies WHERE service_id=? ORDER BY resource_id").all(e).map((t)=>({serviceId:String(t.service_id),resourceId:String(t.resource_id),secretRef:String(t.secret_ref),requiresRedeploy:td(t.requires_redeploy),createdAt:String(t.created_at)}))}removeDependency(e,t){return this.controlPlane.database.run("DELETE FROM data_service_dependencies WHERE service_id=? AND resource_id=?",[e,t]).changes===1}remove(e){this.controlPlane.database.run("DELETE FROM data_services WHERE id=?",[e])}}function jh(){let t=crypto.getRandomValues(new Uint8Array(40));return Array.from(t,(r)=>"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*_-+="[r%69]).join("")}function cl(e,t){return t.map((r)=>{let o=r.type==="tunnel"?"127.0.0.1":r.host,m=e.engine==="redis"?`redis-cli -h ${o} -p ${r.port}${r.tls?" --tls":""}`:e.engine==="postgres"?`psql "host=${o} port=${r.port} dbname=${r.database??"postgres"} sslmode=${r.tls?"require":"disable"}"`:e.engine==="mongodb"?`mongosh "mongodb://${o}:${r.port}/${r.database??"admin"}${r.tls?"?tls=true":""}"`:e.engine==="libsql"?`turso db shell ${r.tls?"https":"http"}://${o}:${r.port}`:`mysql --host=${o} --port=${r.port} --database=${r.database??"mysql"} --ssl-mode=${r.tls?"REQUIRED":"DISABLED"}`;return{type:r.type,command:m,secretRef:e.credentialRef}})}class ki{store;queue;secrets;constructor(e,t,r){this.store=e;this.queue=t;this.secrets=r}async create(e){let t,r;if(e.provider!=="aws_elasticache"){let o=e.username??"app",m=jh();r=`secret://data-services/${e.projectId}/${e.name}/${o}`,await this.secrets.put(r,m),t={username:o,password:m,secretRef:r}}try{let o=this.store.create({...e,credentialRef:r,status:"planning"});if(t)this.store.saveCredential(o.id,t.username,t.secretRef);let m=this.enqueue(o,"create",{});return{service:o,credential:t,operationId:m}}catch(o){if(r)await this.secrets.remove(r);throw o}}plan(e,t,r={}){let o=e.capabilities.actions[t],m=t==="version"&&String(r.engineVersion??"").split(".")[0]!==String(e.engineVersion??"").split(".")[0];return{service:e,action:t,capability:o,changes:r,preflight:{backupRequired:["delete","restore"].includes(t)||m,compatibilityRequired:m,typedConfirmation:o.destructive?e.name:void 0,retentionChoiceRequired:t==="delete"},warnings:[...o.downtime!=="none"?[`Downtime is ${o.downtime}.`]:[],...e.origin==="adopted"&&!e.managementEnabled?["Adopted resource is read-only until management is explicitly enabled."]:[]]}}enqueue(e,t,r,o){let m=this.plan(e,t,r);if(!m.capability.supported)throw Error(m.capability.explanation);if(e.origin==="adopted"&&!e.managementEnabled&&t!=="observe")throw Error("Adopted resources remain read-only until management is explicitly enabled.");if(m.preflight.typedConfirmation&&r.confirm!==m.preflight.typedConfirmation)throw Error(`Type ${m.preflight.typedConfirmation} to confirm ${t}.`);if(m.preflight.retentionChoiceRequired&&!["final_backup","retain"].includes(String(r.retention??"")))throw Error("Deletion requires retention final_backup or retain.");if(m.preflight.compatibilityRequired&&(r.compatibilityReviewed!==!0||!r.backupId))throw Error("Major version changes require compatibilityReviewed=true and a backupId.");if(t==="restore"){let h=String(r.backupId??""),I=String(r.targetId??"");if(!h||!I)throw Error("Restore requires both backupId and targetId.");if(I===e.placement)throw Error("Restore targetId must differ from the source placement.");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(I))throw Error("Restore targetId must be 2-63 lowercase letters, numbers, or dashes.")}return this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:o,kind:"data_service.action",input:{serviceId:e.id,action:t,...r},lockKey:`data-service:${e.id}`,providerKey:e.provider,maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"}).operation.id}async rotate(e,t,r){let o=this.store.credential(e.id);if(!o)throw Error("Data service credential metadata was not found.");let m=jh(),h=`${o.secretRef}/v${o.version+1}`;await this.secrets.put(h,m);try{return await t.action(e,"rotate",{username:o.username,secretRef:h},m,r),this.store.saveCredential(e.id,o.username,h),this.store.update(e.id,e.version,{credentialRef:h}),{credential:{username:o.username,password:m,secretRef:h},dependencies:this.store.dependencies(e.id).filter((I)=>I.requiresRedeploy).map((I)=>I.resourceId)}}catch(I){throw await this.secrets.remove(h),I}}}function dl(e){return{"data_service.action":async(t)=>{let r=t.operation.input,o=e.store.get(String(r.serviceId??"")),m=String(r.action??"");if(!o)throw Error("Data service was not found.");let h=e.resolveAdapter(o);if(!h||h.provider!==o.provider||!h.engines.includes(o.engine))throw Error(`No ${o.provider}/${o.engine} adapter is configured.`);if(m==="rotate"){let R=await new ki(e.store,new c(e.store.controlPlane),e.secrets).rotate(o,h,t);return{serviceId:o.id,action:m,username:R.credential.username,secretRef:R.credential.secretRef,dependencies:R.dependencies}}let I=o.credentialRef?await e.secrets.resolve(o.credentialRef):void 0;try{let R=m==="observe"?await h.observe(o):m==="create"?await h.apply(o,I,t):await h.action(o,m,r,I,t),A=e.store.get(o.id);return e.store.update(o.id,A.version,{observedState:R,status:m==="delete"?r.retention==="retain"?"retained":"deleting":"available"}),{serviceId:o.id,action:m,observed:R}}catch(R){let A=e.store.get(o.id);if(e.store.update(o.id,A.version,{status:"failed",observedState:{...A.observedState,error:R instanceof Error?R.message:String(R)}}),/temporar|timeout|unavailable|throttl/i.test(R instanceof Error?R.message:String(R)))throw new J(R instanceof Error?R.message:String(R),"provider_transient");throw R}}}}class ka{transport;constructor(e){this.transport=e}observe(e){return this.transport.observe(e.placement)}apply(e,t){return this.transport.apply({id:e.placement,name:e.name,engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,storageGb:e.storageGb??null,highAvailability:e.highAvailability,publicExposure:e.publicExposure,allowedCidrs:e.allowedCidrs,username:e.desiredState.username??"app",desiredState:e.desiredState},t)}action(e,t,r,o,m){return this.transport.execute(e.placement,t,{engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,desiredState:e.desiredState,...r},o,m)}}class Bo extends ka{provider="aws_rds";engines=["postgres","mysql","mariadb"]}class xo extends ka{provider="aws_aurora";engines=["postgres","mysql"]}class _o extends ka{provider="aws_elasticache";engines=["redis"]}class Oo extends ka{provider="server";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}class Lo extends ka{provider="container";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}var ad=(e,t)=>{let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)},hr=(e,t,r)=>{let o=ad(e,t);return o==null?r:String(o)},Cn=(e,t)=>{let r=ad(e,t);return r==null?void 0:Number(r)},ss=(e,t)=>{let r=ad(e,t);return r==null?void 0:r===!0||r==="true"},Ia=(e,t)=>{let r=ad(e,t);return Array.isArray(r)?r.map(String):[]},id=(e,t)=>hr(t,"snapshotId")??`${e}-final-${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}`;function nd(e){if(!e)throw Error("RDS instance was not found.");return{providerId:e.DBInstanceIdentifier??null,status:e.DBInstanceStatus??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,plan:e.DBInstanceClass??null,storageGb:e.AllocatedStorage??null,highAvailability:e.MultiAZ??!1,publicExposure:e.PubliclyAccessible??!1,endpoint:e.Endpoint?.Address??null,port:e.Endpoint?.Port??null,username:e.MasterUsername??null,database:e.DBName??null,encrypted:e.StorageEncrypted??!1}}class $o{client;constructor(e=new j){this.client=e}async observe(e){return nd(await this.client.describeDBInstance(e))}async apply(e,t){let r=String(e.id),o=await this.client.createDBInstance({DBInstanceIdentifier:r,DBInstanceClass:String(e.plan),Engine:String(e.engine),MasterUsername:hr(e,"username","app"),MasterUserPassword:t,DBName:hr(e,"database"),AllocatedStorage:Cn(e,"storageGb"),VpcSecurityGroupIds:Ia(e,"securityGroupIds"),DBSubnetGroupName:hr(e,"subnetGroup"),BackupRetentionPeriod:Cn(e,"backupRetentionDays")??7,MultiAZ:ss(e,"highAvailability"),EngineVersion:hr(e,"engineVersion"),PubliclyAccessible:ss(e,"publicExposure")??!1,StorageType:hr(e,"storageType","gp3"),StorageEncrypted:!0,KmsKeyId:hr(e,"kmsKeyId"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return nd(o.DBInstance)}async execute(e,t,r,o,m){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBInstance({DBInstanceIdentifier:e}),{status:"rebooting"};if(t==="backup"){let h=id(e,r);return await this.client.createDBSnapshot({DBInstanceIdentifier:e,DBSnapshotIdentifier:h}),{status:"snapshotting",snapshotId:h}}if(t==="restore"){let h=String(r.targetId),I=await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:h,DBSnapshotIdentifier:String(r.backupId),DBInstanceClass:hr(r,"plan"),DBSubnetGroupName:hr(r,"subnetGroup"),MultiAZ:ss(r,"highAvailability"),PubliclyAccessible:!1,StorageType:hr(r,"storageType"),VpcSecurityGroupIds:Ia(r,"securityGroupIds"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{...nd(I.DBInstance),sourceId:e,restoreTargetId:h}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let h=id(e,r);return await this.client.modifyDBInstance({DBInstanceIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:e,SkipFinalSnapshot:!1,FinalDBSnapshotIdentifier:h,DeleteAutomatedBackups:!1}),{status:"deleting",finalSnapshotId:h}}if(["resize","version","rotate","expose"].includes(t)){let h=await this.client.modifyDBInstance({DBInstanceIdentifier:e,DBInstanceClass:hr(r,"plan"),AllocatedStorage:Cn(r,"storageGb"),MasterUserPassword:t==="rotate"?o:void 0,EngineVersion:hr(r,"engineVersion"),MultiAZ:ss(r,"highAvailability"),PubliclyAccessible:ss(r,"publicExposure"),VpcSecurityGroupIds:Ia(r,"securityGroupIds"),ApplyImmediately:ss(r,"applyImmediately")??!0});return nd(h.DBInstance)}throw Error(`RDS action ${t} requires an engine connection runner.`)}}function xp(e){if(!e)throw Error("Aurora cluster was not found.");return{providerId:e.DBClusterIdentifier??null,status:e.Status??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,endpoint:e.Endpoint??null,readerEndpoint:e.ReaderEndpoint??null,port:e.Port??null,username:e.MasterUsername??null,database:e.DatabaseName??null,encrypted:e.StorageEncrypted??!1,highAvailability:e.MultiAZ??!0}}class Mo{client;constructor(e=new j){this.client=e}async observe(e){let t=await this.client.describeDBClusters({DBClusterIdentifier:e});return xp(t.DBClusters?.[0])}async apply(e,t){let r=String(e.id),o=String(e.engine)==="postgres"?"aurora-postgresql":"aurora-mysql";return await this.client.createDBCluster({DBClusterIdentifier:r,Engine:o,EngineVersion:hr(e,"engineVersion"),MasterUsername:hr(e,"username","app"),MasterUserPassword:t,DatabaseName:hr(e,"database"),DBSubnetGroupName:hr(e,"subnetGroup"),VpcSecurityGroupIds:Ia(e,"securityGroupIds"),BackupRetentionPeriod:Cn(e,"backupRetentionDays")??7,StorageEncrypted:!0,KmsKeyId:hr(e,"kmsKeyId"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Cn(e,"minCapacity")??0.5,MaxCapacity:Cn(e,"maxCapacity")??4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${r}-writer-1`,DBClusterIdentifier:r,DBInstanceClass:String(e.plan||"db.serverless"),Engine:o,PubliclyAccessible:ss(e,"publicExposure")??!1}),{status:"creating",providerId:r}}async execute(e,t,r,o){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBCluster(e),{status:"rebooting"};if(t==="backup"){let m=id(e,r);return await this.client.createDBClusterSnapshot(e,m),{status:"snapshotting",snapshotId:m}}if(t==="restore"){let m=String(r.targetId),h=String(r.engine)==="postgres"?"aurora-postgresql":"aurora-mysql",I=await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:m,SnapshotIdentifier:String(r.backupId),Engine:h,EngineVersion:hr(r,"engineVersion"),DBSubnetGroupName:hr(r,"subnetGroup"),VpcSecurityGroupIds:Ia(r,"securityGroupIds"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Cn(r,"minCapacity")??0.5,MaxCapacity:Cn(r,"maxCapacity")??4}});return await this.client.createDBInstance({DBInstanceIdentifier:`${m}-writer-1`,DBClusterIdentifier:m,DBInstanceClass:hr(r,"plan","db.serverless"),Engine:h,PubliclyAccessible:!1}),{...xp(I.DBCluster),sourceId:e,restoreTargetId:m}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let m=id(e,r);return await this.client.modifyDBCluster({DBClusterIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(e,m),{status:"deleting",finalSnapshotId:m}}if(["resize","version","rotate"].includes(t)){let m=await this.client.modifyDBCluster({DBClusterIdentifier:e,ServerlessV2ScalingConfiguration:Cn(r,"minCapacity")==null&&Cn(r,"maxCapacity")==null?void 0:{MinCapacity:Cn(r,"minCapacity")??0.5,MaxCapacity:Cn(r,"maxCapacity")??4},EngineVersion:hr(r,"engineVersion"),MasterUserPassword:t==="rotate"?o:void 0,ApplyImmediately:ss(r,"applyImmediately")??!0});return xp(m.DBCluster)}throw Error(`Aurora action ${t} requires an engine connection runner.`)}}class Fo{client;constructor(e=new Je){this.client=e}async observe(e){let t=(await this.client.describeCacheClusters(e)).CacheClusters[0];if(!t)throw Error("ElastiCache cluster was not found.");let r=t.CacheNodes?.[0]?.Endpoint;return{providerId:t.CacheClusterId,status:t.CacheClusterStatus,engine:t.Engine,engineVersion:t.EngineVersion,plan:t.CacheNodeType,nodes:t.NumCacheNodes,endpoint:r?.Address??null,port:r?.Port??null}}async apply(e){let t=await this.client.createCacheCluster({cacheClusterId:String(e.id),engine:"redis",cacheNodeType:String(e.plan),numCacheNodes:Cn(e,"nodes")??1,engineVersion:hr(e,"engineVersion"),port:Cn(e,"port"),securityGroupIds:Ia(e,"securityGroupIds"),subnetGroupName:hr(e,"subnetGroup"),tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{providerId:t.CacheCluster.CacheClusterId,status:t.CacheCluster.CacheClusterStatus}}async execute(e,t,r){if(t==="observe")return this.observe(e);if(t==="restart"){let o=(await this.client.describeCacheClusters(e)).CacheClusters[0];return await this.client.rebootCacheCluster(e,o?.CacheNodes?.map((m)=>m.CacheNodeId)??["0001"]),{status:"rebooting"}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};return await this.client.deleteCacheCluster(e),{status:"deleting"}}throw Error(`ElastiCache action ${t} is not supported by this cluster mode.`)}}import{mkdir as CI,writeFile as PI}from"node:fs/promises";import{join as _I}from"node:path";async function Dn(e,t,r=!1){let o=Bun.spawn(["docker",...e],{stdin:t==null?"ignore":"pipe",stdout:"pipe",stderr:"pipe"}),m=new Response(o.stdout).text(),h=new Response(o.stderr).text();if(t!=null)o.stdin.write(t),o.stdin.end();let[I,R,A]=await Promise.all([o.exited,m,h]);if(I!==0&&!r)throw Error(`Docker command failed (${I}): ${A.trim()||R.trim()}`);return{code:I,stdout:R,stderr:A}}class ll{async ensureNetwork(e){if((await Dn(["network","inspect",e],void 0,!0)).code!==0)await Dn(["network","create","--internal",e])}async seedSecret(e,t){await Dn(["volume","create",e]),await Dn(["run","--rm","-i","-v",`${e}:/run/target`,"alpine:3.21","sh","-c","umask 077; cat > /run/target/credential"],t)}async removeVolume(e){await Dn(["volume","rm",e],void 0,!0)}async inspect(e){let t=await Dn(["inspect",e],void 0,!0);if(t.code!==0)return;return JSON.parse(t.stdout)[0]}async run(e){await Dn(["run",...e])}async exec(e,t,r){return(await Dn(["exec","-i",e,...t],r)).stdout}async update(e,t){await Dn(["update",...t,e])}async restart(e){await Dn(["restart",e])}async remove(e){await Dn(["rm","--force",e],void 0,!0)}async logs(e,t){let r=await Dn(["logs","--tail",String(Math.min(2000,Math.max(1,t))),e],void 0,!0);return`${r.stdout}${r.stderr}`.slice(-262144)}async stats(e){let t=await Dn(["stats","--no-stream","--format","{{json .}}",e],void 0,!0);if(t.code!==0||!t.stdout.trim())return{};let r=JSON.parse(t.stdout.trim());return{cpuPercent:String(r.CPUPerc??""),memoryUsage:String(r.MemUsage??""),memoryPercent:String(r.MemPerc??""),networkIo:String(r.NetIO??""),blockIo:String(r.BlockIO??""),pids:Number(r.PIDs??0)}}}var TI={postgres:{image:"postgres:17-alpine",port:5432,dataPath:"/var/lib/postgresql/data"},mysql:{image:"mysql:8.4",port:3306,dataPath:"/var/lib/mysql"},mariadb:{image:"mariadb:11.7",port:3306,dataPath:"/var/lib/mysql"},redis:{image:"redis:7.4-alpine",port:6379,dataPath:"/data"},mongodb:{image:"mongo:8.0",port:27017,dataPath:"/data/db"}};function Ii(e,t="app"){let r=String(e??t);if(!/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(r))throw Error("Database identifiers must be letters, numbers, or underscores.");return r}function Os(e){if(!/^[a-z0-9][a-z0-9_.-]{1,62}$/i.test(e))throw Error("Runtime placement must be a valid container identifier.");return`tscloud-data-${e.toLowerCase()}`}function xI(e,t){let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)}function ac(e){return e.Config?.Labels??{}}class jt{runtime;backupRoot;constructor(e=new ll,t=d(process.cwd(),"backups","data")){this.runtime=e;this.backupRoot=t}async observe(e){let t=Os(e),r=await this.runtime.inspect(t);if(!r)throw Error(`Data container ${t} was not found.`);let o=ac(r),m=await this.runtime.stats(t),h=r.NetworkSettings?.Ports??{},I=Object.values(h).flat().find(Boolean);return{providerId:t,status:r.State?.Status??"unknown",healthy:r.State?.Health?.Status??null,engine:o["ts-cloud.engine"]??null,engineVersion:o["ts-cloud.engine-version"]??null,username:o["ts-cloud.username"]??null,database:o["ts-cloud.database"]??null,endpoint:I?.HostIp||"127.0.0.1",port:I?.HostPort?Number(I.HostPort):null,image:r.Config?.Image??null,startedAt:r.State?.StartedAt??null,metrics:m}}async apply(e,t){let r=String(e.id),o=Os(r),m=String(e.engine);if(m==="libsql")throw Error("libSQL requires an explicitly configured runtime image.");let h=TI[m];if(!h)throw Error(`Unsupported runtime data engine ${m}.`);if(!t)throw Error(`${m} requires a managed credential.`);if(e.publicExposure===!0)throw Error("Container public exposure requires an external reviewed firewall policy; direct publishing is refused.");let I=Ii(e.username),R=Ii(xI(e,"database")),A=`${o}-secret`,E=`${o}-data`,x=m==="redis"?`appendonly yes
87
+ ORDER BY rp.expires_at,rp.id`).all(e.toISOString(),e.toISOString()).map(Pp),r=new Set;for(let o of new Set(t.map((m)=>m.projectId)))for(let m of this.listPolicies(o)){let h=this.listRecoveryPoints(m.projectId,m.id).filter((R)=>R.status==="available").sort((R,A)=>A.pointInTime.localeCompare(R.pointInTime));for(let R of h.slice(0,Math.max(0,m.retention.keepLast??0)))r.add(R.id);let I=[[m.retention.hourly,(R)=>R.toISOString().slice(0,13)],[m.retention.daily,(R)=>R.toISOString().slice(0,10)],[m.retention.weekly,(R)=>new Date(Date.UTC(R.getUTCFullYear(),R.getUTCMonth(),R.getUTCDate()-(R.getUTCDay()+6)%7)).toISOString().slice(0,10)],[m.retention.monthly,(R)=>R.toISOString().slice(0,7)]];for(let[R,A]of I){let E=new Set;for(let x of h){let N=A(new Date(x.pointInTime));if(E.has(N))continue;if(E.add(N),E.size<=Math.max(0,R??0))r.add(x.id)}}}return t.filter((o)=>!r.has(o.id))}coverage(e,t=this.now()){let r=new Map(this.listDestinations(e).map((o)=>[o.id,o]));return this.listPolicies(e).map((o)=>{let m=this.listRecoveryPoints(e,o.id).filter((R)=>R.status==="available"),h=m[0],I=h?(t.getTime()-new Date(h.pointInTime).getTime())/60000:Number.POSITIVE_INFINITY;return{policy:o,lastRecoveryPoint:h,missedRpo:o.enabled&&I>o.expectedRpoMinutes,unverified:m.filter((R)=>R.verificationState!=="verified").length,destinationHealthy:r.get(o.destinationId)?.status==="healthy"}})}}import{createCipheriv as SI,createDecipheriv as wI,createHash as Dh,randomBytes as Oh}from"node:crypto";var Tp=Buffer.from("TSCB1"),Zc=(e)=>`sha256:${Dh("sha256").update(e).digest("hex")}`;function $h(e){return Dh("sha256").update(e).digest()}function vm(e,t,r){let o=r?Buffer.from(r):Oh(12);if(o.length!==12)throw Error("Backup encryption IV must contain 12 bytes.");let m=SI("aes-256-gcm",$h(t),o),h=Buffer.concat([m.update(e),m.final()]),I=m.getAuthTag();return Buffer.concat([Tp,o,I,h])}function Tm(e,t){let r=Buffer.from(e);if(!r.subarray(0,Tp.length).equals(Tp))throw Error("Backup does not contain a valid encrypted envelope.");let o=r.subarray(5,17),m=r.subarray(17,33),h=r.subarray(33),I=wI("aes-256-gcm",$h(t),o);return I.setAuthTag(m),Buffer.concat([I.update(h),I.final()])}function kI(e){let t;try{t=JSON.parse(e)}catch{throw Error("Backup destination credential must be a JSON object with accessKeyId and secretAccessKey.")}if(!t.accessKeyId||!t.secretAccessKey)throw Error("Backup destination credential requires accessKeyId and secretAccessKey.");if(t.expiresAt){let r=new Date(String(t.expiresAt));if(!Number.isFinite(r.getTime()))throw Error("Backup destination credential expiresAt must be an ISO timestamp.");if(r.getTime()<=Date.now())throw Error("Backup destination credential has expired.")}return{accessKeyId:String(t.accessKeyId),secretAccessKey:String(t.secretAccessKey),sessionToken:t.sessionToken?String(t.sessionToken):void 0}}async function xl(e,t,r=new Date){if(!e.credentialRef)return{status:"default"};try{let o=JSON.parse(await t.resolve(e.credentialRef));if(!o.accessKeyId||!o.secretAccessKey)return{status:"invalid"};if(!o.expiresAt)return{status:"static"};let m=new Date(String(o.expiresAt));if(!Number.isFinite(m.getTime()))return{status:"invalid"};let h=m.getTime()-r.getTime();return{status:h<=0?"expired":h<=604800000?"expiring":"valid",expiresAt:m.toISOString()}}catch{return{status:"invalid"}}}class ta{secrets;clientFactory;multipartThreshold;partSize;constructor(e,t=(m,h)=>new a(m.region??"us-east-1",void 0,{endpoint:m.endpoint?new URL(m.endpoint).host:void 0,forcePathStyle:m.forcePathStyle,credentials:h}),r=8388608,o=8388608){this.secrets=e;this.clientFactory=t;this.multipartThreshold=r;this.partSize=o}async client(e){let t=e.credentialRef?kI(await this.secrets.resolve(e.credentialRef)):void 0;return this.clientFactory(e,t)}async test(e){if(!e.bucket)throw Error("S3 destination has no configured bucket.");let t=await this.client(e),r=`${e.prefix?`${e.prefix.replace(/\/$/,"")}/`:""}.ts-cloud-health/${crypto.randomUUID()}`;await t.putObject({bucket:e.bucket,key:r,body:"ts-cloud backup destination health check",contentType:"text/plain"});try{let o=await t.getObjectBytes(e.bucket,r);if(Buffer.from(o.body).toString()!=="ts-cloud backup destination health check")throw Error("Backup destination health object was corrupted.")}finally{await t.deleteObject(e.bucket,r)}}async upload(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(e),o=Zc(t.body),m=e.encryption!=="provider"?await this.secrets.resolve(e.encryptionKeyRef):void 0,h=m?t.resume?.encryptionIv?Buffer.from(t.resume.encryptionIv,"base64url"):Oh(12):void 0,I=m?vm(t.body,m,h):Buffer.from(t.body),R=Zc(I),A=`${e.prefix?`${e.prefix.replace(/\/$/,"")}/`:""}${t.key.replace(/^\/+/,"")}`,E=t.contentType??"application/octet-stream",x={"ts-cloud-format":"v1","ts-cloud-sha256":R.slice(7),"ts-cloud-encrypted":m?"true":"false"};if(t.resume&&t.resume.key!==A)throw Error("Multipart checkpoint does not match the requested backup key.");if(t.resume&&m&&!t.resume.encryptionIv)throw Error("Encrypted multipart checkpoint has no resumable envelope state.");if(t.resume&&m&&t.resume.plaintextChecksum!==o)throw Error("Encrypted multipart checkpoint does not match the backup payload.");if(I.length<this.multipartThreshold)await r.putObject({bucket:e.bucket,key:A,body:I,contentType:E,metadata:x});else{let N=t.resume?void 0:await r.createMultipartUpload(e.bucket,A,{contentType:E,metadata:x}),F=t.resume??{uploadId:N.UploadId,key:A,parts:[],bytesUploaded:0,encryptionIv:h?.toString("base64url"),plaintextChecksum:o},z=new Map(F.parts.map((K)=>[K.PartNumber,K])),H=Math.ceil(I.length/this.partSize);for(let K=0;K<H;K++){let X=K+1;if(!z.has(X)){let oe=K*this.partSize,ye=await r.uploadPart(e.bucket,A,F.uploadId,X,I.subarray(oe,Math.min(I.length,oe+this.partSize)));z.set(X,{PartNumber:X,ETag:ye.ETag})}F.parts=[...z.values()].sort((oe,ye)=>oe.PartNumber-ye.PartNumber),F.bytesUploaded=Math.min(I.length,X*this.partSize),t.checkpoint?.(F)}await r.completeMultipartUpload(e.bucket,A,F.uploadId,F.parts)}return{uri:`s3://${e.bucket}/${A}`,key:A,sizeBytes:I.length,checksum:R,manifest:{format:"ts-cloud-backup-v1",encrypted:!!m,plaintextChecksum:o,storageChecksum:R,contentType:E}}}async download(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(e),o=await r.getObjectBytes(e.bucket,t.key),m=Buffer.from(o.body);if(Zc(m)!==t.checksum)throw Error("Backup checksum verification failed; object is corrupt.");let h=t.manifest.encrypted?Tm(m,await this.secrets.resolve(e.encryptionKeyRef)):m;if(Zc(h)!==t.manifest.plaintextChecksum)throw Error("Backup plaintext checksum verification failed.");return h}async abortPartial(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(e)).abortMultipartUpload(e.bucket,t.key,t.uploadId)}async delete(e,t){if(!e.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(e)).deleteObject(e.bucket,t)}}import{createHash as II}from"node:crypto";var EI=(e)=>`sha256:${II("sha256").update(e).digest("hex")}`;class Mi{store;queue;now;constructor(e,t,r=()=>new Date){this.store=e;this.queue=t;this.now=r}enqueueBackup(e,t=this.now().toISOString(),r){if(!e.enabled)throw Error("Backup policy is disabled.");let o=this.store.createJob({projectId:e.projectId,policyId:e.id,kind:"backup",status:"queued",idempotencyKey:`backup:${e.id}:${t}`,target:{scheduledFor:t},cancellability:"checkpoint_only",progress:{phase:"queued"}});if(!o.operationId){let m=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:r,kind:"backup.run",input:{backupJobId:o.id},lockKey:e.dataServiceId?`data-service:${e.dataServiceId}`:e.resourceId?`resource:${e.resourceId}`:`backup-policy:${e.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:14400,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(o.id,{operationId:m.operation.id})}return o}enqueueDue(e=this.now()){return this.store.duePolicies(e).map((t)=>{let r=t.nextRunAt;return this.store.advancePolicy(t.id,r),this.enqueueBackup(t,r)})}enqueueVerification(e){let t=this.store.createJob({projectId:e.projectId,policyId:e.policyId,recoveryPointId:e.id,kind:"verify",status:"queued",idempotencyKey:`verify:${e.id}:${e.checksum}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!t.operationId){let r=this.queue.enqueue({projectId:e.projectId,resourceId:e.resourceId,kind:"backup.verify",input:{backupJobId:t.id},lockKey:`recovery-point:${e.id}`,providerKey:"backup",maxAttempts:2,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(t.id,{operationId:r.operation.id})}return t}planRestore(e,t){if(e.status!=="available")throw Error("Only available recovery points can be restored.");if(e.verificationState!=="verified")throw Error("Restore requires a verified recovery point.");if(t.mode==="in_place"){if(!t.recentAuth)throw Error("In-place restore requires recent authentication.");if(t.confirm!==t.targetName)throw Error(`Type ${t.targetName} to confirm in-place restore.`);if(!t.downtimeAcknowledged)throw Error("In-place restore requires downtime acknowledgement.");let r=t.safetyBackupId?this.store.getRecoveryPoint(t.safetyBackupId):void 0;if(!r||r.id===e.id||r.status!=="available"||r.verificationState!=="verified"||r.resourceId!==e.resourceId||r.dataServiceId!==e.dataServiceId)throw Error("In-place restore requires a distinct verified safety backup for the same target.")}return{point:e,mode:t.mode,target:{...t.target,inPlace:t.mode==="in_place",restoreMode:t.mode},warnings:t.mode==="in_place"?["The target is locked against deployments and backup work.","Downtime and data replacement are expected.","Provider cancellation may stop only at a checkpoint."]:["An isolated target is created and health-validated before cleanup."]}}enqueueRestore(e,t){let r=this.planRestore(e,t),o=t.drill?"drill":"restore",m=EI(JSON.stringify({point:e.id,mode:t.mode,target:t.target,safety:t.safetyBackupId,drill:!!t.drill})),h=this.store.createJob({projectId:e.projectId,policyId:e.policyId,recoveryPointId:e.id,kind:o,status:"queued",idempotencyKey:`${o}:${m}`,target:r.target,restoreMode:r.mode,cancellability:"checkpoint_only",safetyBackupId:t.safetyBackupId,progress:{phase:"queued",warnings:r.warnings}});if(!h.operationId){let I=this.queue.enqueue({projectId:e.projectId,resourceId:e.resourceId,actorId:t.actorId,kind:t.drill?"backup.drill":"backup.restore",input:{backupJobId:h.id},lockKey:e.dataServiceId?`data-service:${e.dataServiceId}`:e.resourceId?`resource:${e.resourceId}`:`recovery-point:${e.id}`,providerKey:"backup",maxAttempts:1,timeoutSeconds:14400,retryClasses:[],resumePolicy:"fail"});return this.store.updateJob(h.id,{operationId:I.operation.id})}return h}enqueueRetention(e=this.now()){return this.store.retentionCandidates(e).map((t)=>{let r=this.store.createJob({projectId:t.projectId,policyId:t.policyId,recoveryPointId:t.id,kind:"cleanup",status:"queued",idempotencyKey:`cleanup:${t.id}:${t.expiresAt}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!r.operationId){let o=this.queue.enqueue({projectId:t.projectId,resourceId:t.resourceId,kind:"backup.cleanup",input:{backupJobId:r.id},lockKey:`recovery-point:${t.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(r.id,{operationId:o.operation.id})}return r})}}function _l(e){let t=e.now??(()=>new Date),r=new Mi(e.store,e.queue,t),o=(R)=>{let A=R.recoveryPointId?e.store.getRecoveryPoint(R.recoveryPointId):void 0,E=R.policyId?e.store.getPolicy(R.policyId):A?.policyId?e.store.getPolicy(A.policyId):void 0;if(!E)throw Error("Backup policy was not found.");let x=e.store.getDestination(A?.destinationId??E.destinationId),N=e.resolveSource(E);if(!x)throw Error("Backup destination was not found.");if(!N)throw Error(`No ${E.resourceKind} backup adapter is configured.`);return{point:A,policy:E,destination:x,source:N}},m=(R)=>{let A=R.operation.input,E=e.store.getJob(String(A.backupJobId??""));if(!E)throw Error("Backup job was not found.");return e.store.updateJob(E.id,{status:"running",startedAt:E.startedAt??t().toISOString(),progress:{...E.progress,phase:"running"}}),E},h=(R,A)=>{let E=e.store.getJob(R.id)??R;e.store.updateJob(R.id,{status:"failed",finishedAt:t().toISOString(),error:A instanceof Error?A.message:String(A),progress:{...E.progress,phase:"failed"}})};return{"backup.run":async(R)=>{let A=m(R);try{let{policy:E,destination:x,source:N}=o(A),F=await N.create(E,R),z=e.resolveDestination(x),H=F.mode==="object"?await(async()=>{if(!z)throw Error("Backup destination adapter is not configured.");let ye=e.store.getJob(A.id)?.progress,ne=ye?.multipart,fe=ne&&typeof ne==="object"&&!Array.isArray(ne)&&typeof ne.uploadId==="string"&&typeof ne.key==="string"&&Array.isArray(ne.parts)?ne:void 0;return z.upload(x,{key:F.key,body:F.body,contentType:F.contentType,resume:fe,checkpoint:(Ce)=>{R.checkpoint("uploading",`Uploaded ${Number(Ce.bytesUploaded??0)} backup bytes.`),e.store.updateJob(A.id,{progress:{phase:"uploading",multipart:{...Ce}}})}})})():{uri:F.uri,key:F.uri,sizeBytes:F.sizeBytes,checksum:F.checksum,manifest:{format:"ts-cloud-backup-v1",encrypted:!1,plaintextChecksum:F.checksum,storageChecksum:F.checksum,contentType:"application/provider-snapshot"}},K=E.retention.expireAfterDays?new Date(t().getTime()+E.retention.expireAfterDays*86400000).toISOString():void 0,X=e.store.getJob(A.id)?.startedAt,oe=e.store.createRecoveryPoint({projectId:E.projectId,policyId:E.id,destinationId:x.id,resourceId:E.resourceId,dataServiceId:E.dataServiceId,backupJobId:A.id,kind:E.resourceKind,pointInTime:t().toISOString(),uri:H.uri,sizeBytes:H.sizeBytes,checksum:H.checksum,manifest:{...F.manifest,...H.manifest,storageKey:H.key},toolVersion:F.toolVersion,engineVersion:F.engineVersion,expiresAt:K,lockedUntil:x.immutability.defaultRetentionDays?new Date(t().getTime()+x.immutability.defaultRetentionDays*86400000).toISOString():void 0,held:!1,pinned:!1,status:"available",verificationState:"unverified",durationMs:Math.max(0,t().getTime()-new Date(X??t().toISOString()).getTime())});if(F.mode==="external"&&x.provider==="aws_backup")e.store.recordDestinationTest(x.id,{ok:!0});return e.store.updateJob(A.id,{status:"succeeded",recoveryPointId:oe.id,finishedAt:t().toISOString(),progress:{phase:"stored",recoveryPointId:oe.id}}),r.enqueueVerification(oe),{backupJobId:A.id,recoveryPointId:oe.id}}catch(E){let x=e.store.getJob(A.id),N=x?.progress.multipart,F=(()=>{try{return o(A)}catch{return}})();if(F?.destination.provider==="aws_backup")e.store.recordDestinationTest(F.destination.id,{ok:!1,error:E instanceof Error?E.message:String(E)});let z=!1;if(N&&typeof N==="object"&&!Array.isArray(N)&&F){let H=e.resolveDestination(F.destination);if(z=!0,H?.abortPartial)try{await H.abortPartial(F.destination,N),z=!1,e.store.updateJob(A.id,{progress:{...x.progress,partialCleanup:"aborted"}})}catch{e.store.updateJob(A.id,{progress:{...x.progress,partialCleanup:"required"}})}}if(z)e.store.updateJob(A.id,{status:"cleanup_required",finishedAt:t().toISOString(),error:E instanceof Error?E.message:String(E),progress:{...e.store.getJob(A.id)?.progress??{},phase:"cleanup_required"}});else h(A,E);throw E}},"backup.verify":async(R)=>{let A=m(R);try{let{point:E,destination:x,source:N}=o(A);if(!E)throw Error("Recovery point was not found.");e.store.updateRecoveryPoint(E.id,{verificationState:"verifying"});let F;if(E.uri.startsWith("s3:")){let z=e.resolveDestination(x);if(!z)throw Error("Backup destination adapter is not configured.");let H=await z.download(x,{key:String(E.manifest.storageKey??""),checksum:E.checksum,manifest:E.manifest}),K=N.verify?await N.verify(E,H,R):{};F={bytes:H.length,checksum:E.checksum,...K}}else if(N.verifyExternal)F=await N.verifyExternal(E,R);else throw Error("External recovery point verification is not supported.");return e.store.updateRecoveryPoint(E.id,{verificationState:"verified",verifiedAt:t().toISOString(),manifest:{...E.manifest,verification:F}}),e.store.updateJob(A.id,{status:"succeeded",finishedAt:t().toISOString(),progress:{phase:"verified",evidence:F}}),{backupJobId:A.id,recoveryPointId:E.id,evidence:F}}catch(E){if(A.recoveryPointId)e.store.updateRecoveryPoint(A.recoveryPointId,{verificationState:/checksum|corrupt|authentic/i.test(E instanceof Error?E.message:String(E))?"corrupt":"failed"});throw h(A,E),E}},"backup.restore":async(R)=>I(R,!1),"backup.drill":async(R)=>I(R,!0),"backup.cleanup":async(R)=>{let A=m(R);try{let{point:E,destination:x,source:N}=o(A);if(!E)throw Error("Recovery point was not found.");if(!e.store.retentionCandidates(t()).some((F)=>F.id===E.id))throw Error("Recovery point is held, pinned, locked, or in active use.");if(e.store.updateRecoveryPoint(E.id,{status:"deleting"}),E.uri.startsWith("s3:")){let F=e.resolveDestination(x);if(!F)throw Error("Destination cleanup is unavailable.");await F.delete(x,String(E.manifest.storageKey??""))}else if(N.deleteExternal)await N.deleteExternal(E,R);else throw Error("External recovery point cleanup is unavailable.");return e.store.updateRecoveryPoint(E.id,{status:"deleted"}),e.store.updateJob(A.id,{status:"succeeded",finishedAt:t().toISOString(),progress:{phase:"deleted"}}),{backupJobId:A.id,recoveryPointId:E.id,deleted:!0}}catch(E){throw h(A,E),E}}};async function I(R,A){let E=m(R);try{let{point:x,policy:N,destination:F,source:z}=o(E);if(!x)throw Error("Recovery point was not found.");if(A&&!z.cleanup)throw Error("This backup source cannot safely clean a recovery drill target.");let H=x.uri.startsWith("s3:")?e.resolveDestination(F):void 0,K=H?await H.download(F,{key:String(x.manifest.storageKey??""),checksum:x.checksum,manifest:x.manifest}):void 0,X=await z.restore(x,K,E.target,R),oe=z.validateHealth?await z.validateHealth({...E.target,...X},R):{healthy:!0,mode:"adapter"},ye=e.validateHealth?await e.validateHealth(N,E.target):{healthy:!0,mode:"not_configured"},ne={...oe,healthy:oe.healthy===!0&&ye.healthy===!0,configured:ye};if(ne.healthy!==!0)throw Error("Restored target did not pass its configured health check.");if(A&&z.cleanup)await z.cleanup({...E.target,provider:x.manifest.provider??null},R);return e.store.updateJob(E.id,{status:"succeeded",finishedAt:t().toISOString(),healthResult:ne,progress:{phase:A?"drill_cleaned":"restored",restored:X}}),{backupJobId:E.id,recoveryPointId:x.id,restored:X,health:ne,cleaned:A}}catch(x){let N=(()=>{try{return o(E)}catch{return}})(),F=x instanceof Error?x.message:String(x),z=!1;if(A&&N?.source.cleanup)try{await N.source.cleanup({...E.target,provider:N.point?.manifest.provider??null},R)}catch{z=!0}if(z)e.store.updateJob(E.id,{status:"cleanup_required",finishedAt:t().toISOString(),error:F,progress:{...E.progress,phase:"cleanup_required"}});else h(E,x);throw x}}}import{createHash as RI}from"node:crypto";var AI=(e)=>`sha256:${RI("sha256").update(e).digest("hex")}`;class ra{dataServices;client;constructor(e,t=new j){this.dataServices=e;this.client=t}service(e){let t=e.dataServiceId?this.dataServices.get(e.dataServiceId):void 0;if(!t||!["aws_rds","aws_aurora"].includes(t.provider))throw Error("Managed database backup policy requires an RDS or Aurora data service.");return t}async waitForSnapshot(e,t,r){for(;;){r.throwIfCancellationRequested?.(),r.heartbeat?.();let o=e==="aws_aurora"?(await this.client.describeDBClusterSnapshots({DBClusterSnapshotIdentifier:t})).DBClusterSnapshots[0]:(await this.client.describeDBSnapshots({DBSnapshotIdentifier:t})).DBSnapshots?.[0];if(!o)throw Error("Provider snapshot was not found.");let m=o,h=String(m.Status??m.DBSnapshotStatus??"unknown");if(r.checkpoint?.("provider_snapshot",`Database snapshot ${t} is ${h}.`),h==="available")return m;if(["deleted","deleting","failed"].includes(h))throw Error(`Provider snapshot ${t} failed with state ${h}.`);await Bun.sleep(5000)}}async create(e,t){let r=this.service(e),o=String(t.operation?.id??new Date().toISOString()).replace(/[^A-Za-z0-9]/g,"").slice(0,20),m=`${r.placement.slice(0,42).replace(/-+$/,"")}-${o}`;if(r.provider==="aws_aurora")await this.client.createDBClusterSnapshot(r.placement,m);else await this.client.createDBSnapshot({DBInstanceIdentifier:r.placement,DBSnapshotIdentifier:m});await this.waitForSnapshot(r.provider,m,t);let h=`${r.provider}:${r.placement}:${m}`;return{mode:"external",uri:`aws-backup:${h}`,checksum:AI(h),sizeBytes:0,manifest:{provider:r.provider,sourceId:r.placement,snapshotId:m,plan:r.plan,engine:r.engine},engineVersion:r.engineVersion,toolVersion:"aws-rds-api-2014-10-31"}}async verifyExternal(e,t){let r=String(e.manifest.snapshotId??""),o=String(e.manifest.provider??"");if(!r)throw Error("Snapshot recovery point has no snapshot ID.");let m=await this.waitForSnapshot(o,r,t),h=String(m.Status??m.DBSnapshotStatus??"unknown");return{snapshotId:r,status:h,encrypted:m.Encrypted??m.StorageEncrypted??!0}}async restore(e,t,r,o){let m=String(r.targetId??""),h=String(e.manifest.snapshotId??""),I=String(e.manifest.provider??"");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(m))throw Error("Managed restore requires a valid distinct targetId.");if(m===e.manifest.sourceId)throw Error("Managed restore target must differ from its source.");if(I==="aws_aurora"){let R=e.manifest.engine==="postgres"?"aurora-postgresql":"aurora-mysql";await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:m,SnapshotIdentifier:h,Engine:R,EngineVersion:e.engineVersion,DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Number(r.minCapacity)||0.5,MaxCapacity:Number(r.maxCapacity)||4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${m}-writer-1`,DBClusterIdentifier:m,DBInstanceClass:String(r.plan??e.manifest.plan??"db.serverless"),Engine:R,PubliclyAccessible:!1})}else await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:m,DBSnapshotIdentifier:h,DBInstanceClass:String(r.plan??e.manifest.plan??""),PubliclyAccessible:!1,DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud-restore"}]});return{targetId:m,provider:I,status:"creating",isolated:!0}}async validateHealth(e,t){let r=String(e.targetId??""),o=String(e.provider??"");for(;;){t.throwIfCancellationRequested?.(),t.heartbeat?.();let m=o==="aws_aurora"?(await this.client.describeDBClusters({DBClusterIdentifier:r})).DBClusters?.[0]:(await this.client.describeDBInstances({DBInstanceIdentifier:r})).DBInstances?.[0];if(!m)throw Error("Restored managed database was not found.");let h=String(m.Status??m.DBInstanceStatus??"unknown");if(t.checkpoint?.("provider_restore",`Restored database ${r} is ${h}.`),h==="available")return{healthy:!0,targetId:r,provider:o,status:h};if(["deleted","deleting","failed","incompatible-restore"].includes(h))throw Error(`Restored managed database ${r} failed with state ${h}.`);await Bun.sleep(5000)}}async cleanup(e,t){let r=String(e.targetId??""),o=String(e.provider??"");if(!r)throw Error("Restore cleanup target is required.");if(o==="aws_aurora")await this.client.deleteDBInstance({DBInstanceIdentifier:`${r}-writer-1`,SkipFinalSnapshot:!0}),await this.client.modifyDBCluster({DBClusterIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(r);else await this.client.modifyDBInstance({DBInstanceIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:r,SkipFinalSnapshot:!0,DeleteAutomatedBackups:!0})}async deleteExternal(e,t){let r=String(e.manifest.snapshotId??"");if(e.manifest.provider==="aws_aurora")await this.client.deleteDBClusterSnapshot(r);else await this.client.deleteDBSnapshot(r)}}var mn=(e,t="none",r=!1)=>({supported:!0,downtime:t,destructive:r,explanation:e}),on=(e)=>({supported:!1,downtime:"none",destructive:!1,explanation:e});function Gr(e,t){let r=["aws_rds","aws_aurora","aws_elasticache"].includes(t),o=["server","container"].includes(t),m=["postgres","mysql","mariadb"].includes(e),h=e==="redis",I={};return I.create=t==="external"?on("External services can be adopted as read-only inventory."):mn(r?"Provision through the provider API.":"Provision through the owning runtime driver.","possible"),I.observe=t==="external"?on("External observation requires a configured provider adapter."):mn("Provider/runtime health and endpoint metadata are observable."),I.connect=mn("Connection guidance uses secret references and never returns a password by default."),I.backup=m&&(r||o)?mn(r?"Create a provider snapshot.":"Create a consistent engine-native dump.","possible"):on("This cache path is not a durable backup source."),I.restore=r&&m?mn("Restore creates a reviewed provider target.","required",!0):on("Restore requires a configured provider restore runner."),I.restart=t==="external"?on("External restart requires a configured provider adapter."):mn(r?"Provider restart/failover semantics apply.":"Restart the owning service unit.","required"),I.resize=t==="aws_elasticache"?on("ElastiCache resizing requires a replication-group migration runner."):r?mn("Provider plan/storage modification may enter a maintenance window.","possible"):o?mn("Edit host/container resources and reconcile.","required"):on("External resize requires a configured provider adapter."),I.version=o?on("Runtime version upgrades require an explicit image migration runner."):r&&t!=="aws_elasticache"?mn(m?"Major versions require compatibility preflight and backup.":"Engine upgrades require a maintenance window.","required"):on("External upgrades require a configured provider adapter."),I.rotate=t==="aws_elasticache"||t==="external"||o&&!m&&!h?on("Credential rotation is not available for this provider/engine path."):mn("Rotate through the secret backend, update the engine, then flag dependent releases."),I.expose=o?on("Direct container publishing is refused; use a reviewed firewall and proxy policy."):t==="aws_rds"?mn("Exposure is reconciled through security groups; public access defaults off."):on("Exposure changes require a provider-specific network runner."),I.delete=t==="external"?on("External deletion requires a configured provider adapter."):mn(r?"Final snapshot is supported where the provider allows it.":"A final engine backup is required unless explicitly retained.","required",!0),I.logs=o?mn("Read bounded service logs from the runtime."):on("Provider log export is not configured for this adapter."),I.slow_queries=o&&m?mn("Read bounded runtime logs after engine slow-query logging is enabled."):on("A slow-query log runner is not configured for this provider."),I.users=o&&m?mn("Logical users can be listed; creation requires a referenced secondary credential."):on("User management requires an engine connection runner."),I.databases=o&&m?mn("Logical databases can be listed, created, and confirmation-gated for deletion."):on("Logical database management requires an engine connection runner."),{actions:I,endpointTypes:r?["internal","external","tunnel"]:["internal","tunnel"],metrics:h?["connections","memory","evictions","hit_rate","latency"]:["connections","cpu","storage","read_latency","write_latency","iops"]}}var wa=(e)=>e==null?void 0:String(e),td=(e)=>Number(e)===1,ed=(e)=>{try{return JSON.parse(String(e))}catch{return{}}};function Nh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:wa(e.environment_id),resourceId:wa(e.resource_id),name:String(e.name),engine:String(e.engine),provider:String(e.provider),placement:String(e.placement),engineVersion:wa(e.engine_version),plan:String(e.plan),storageGb:e.storage_gb==null?void 0:Number(e.storage_gb),highAvailability:td(e.high_availability),publicExposure:td(e.public_exposure),allowedCidrs:ed(e.allowed_cidrs),desiredState:ed(e.desired_state),observedState:ed(e.observed_state),capabilities:ed(e.capabilities),credentialRef:wa(e.credential_ref),status:String(e.status),origin:String(e.origin),managementEnabled:td(e.management_enabled),ownerActorId:wa(e.owner_actor_id),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class ko{controlPlane;now;constructor(e,t=()=>new Date){this.controlPlane=e;this.now=t}create(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Data service names must be 2-63 lowercase letters, numbers, or dashes.");if(e.publicExposure&&(!e.allowedCidrs.length||e.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");let t=crypto.randomUUID(),r=this.now().toISOString(),o=Gr(e.engine,e.provider);return this.controlPlane.database.run("INSERT INTO data_services (id,organization_id,project_id,environment_id,resource_id,name,engine,provider,placement,engine_version,plan,storage_gb,high_availability,public_exposure,allowed_cidrs,desired_state,observed_state,capabilities,credential_ref,status,origin,management_enabled,owner_actor_id,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name,e.engine,e.provider,e.placement,e.engineVersion??null,e.plan,e.storageGb??null,e.highAvailability?1:0,e.publicExposure?1:0,JSON.stringify(e.allowedCidrs),JSON.stringify(e.desiredState),JSON.stringify(e.observedState),JSON.stringify(o),e.credentialRef??null,e.status,e.origin,e.managementEnabled?1:0,e.ownerActorId??null,1,r,r]),this.get(t)}get(e){let t=this.controlPlane.database.query("SELECT * FROM data_services WHERE id=?").get(e);return t?Nh(t):void 0}list(e,t){return this.controlPlane.database.query(`SELECT * FROM data_services WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(Nh)}update(e,t,r){let o=this.get(e);if(!o)throw Error("Data service was not found.");if(o.version!==t)throw Error("Data service changed; refresh before retrying.");let m={...o,...r};if(m.publicExposure&&(!m.allowedCidrs.length||m.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");if(this.controlPlane.database.run("UPDATE data_services SET plan=?,storage_gb=?,engine_version=?,high_availability=?,public_exposure=?,allowed_cidrs=?,desired_state=?,observed_state=?,status=?,management_enabled=?,credential_ref=?,version=version+1,updated_at=? WHERE id=? AND version=?",[m.plan,m.storageGb??null,m.engineVersion??null,m.highAvailability?1:0,m.publicExposure?1:0,JSON.stringify(m.allowedCidrs),JSON.stringify(m.desiredState),JSON.stringify(m.observedState),m.status,m.managementEnabled?1:0,m.credentialRef??null,this.now().toISOString(),e,t]).changes!==1)throw Error("Data service changed; refresh before retrying.");return this.get(e)}credential(e){let t=this.controlPlane.database.query("SELECT * FROM data_service_credentials WHERE service_id=? ORDER BY version DESC LIMIT 1").get(e);return t?{id:String(t.id),serviceId:String(t.service_id),username:String(t.username),secretRef:String(t.secret_ref),version:Number(t.version),createdAt:String(t.created_at),rotatedAt:wa(t.rotated_at)}:void 0}saveCredential(e,t,r){let o=this.credential(e),m=o?.id??crypto.randomUUID(),h=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_credentials (id,service_id,username,secret_ref,version,created_at,rotated_at) VALUES (?,?,?,?,?,?,?) ON CONFLICT(service_id,username) DO UPDATE SET secret_ref=excluded.secret_ref,version=data_service_credentials.version+1,rotated_at=excluded.rotated_at",[m,e,t,r,o?.version??1,o?.createdAt??h,o?h:null]),this.credential(e)}addDependency(e){let t=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_dependencies (service_id,resource_id,secret_ref,requires_redeploy,created_at) VALUES (?,?,?,?,?) ON CONFLICT(service_id,resource_id) DO UPDATE SET secret_ref=excluded.secret_ref,requires_redeploy=excluded.requires_redeploy",[e.serviceId,e.resourceId,e.secretRef,e.requiresRedeploy?1:0,t]),{...e,createdAt:t}}dependencies(e){return this.controlPlane.database.query("SELECT * FROM data_service_dependencies WHERE service_id=? ORDER BY resource_id").all(e).map((t)=>({serviceId:String(t.service_id),resourceId:String(t.resource_id),secretRef:String(t.secret_ref),requiresRedeploy:td(t.requires_redeploy),createdAt:String(t.created_at)}))}removeDependency(e,t){return this.controlPlane.database.run("DELETE FROM data_service_dependencies WHERE service_id=? AND resource_id=?",[e,t]).changes===1}remove(e){this.controlPlane.database.run("DELETE FROM data_services WHERE id=?",[e])}}function jh(){let t=crypto.getRandomValues(new Uint8Array(40));return Array.from(t,(r)=>"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*_-+="[r%69]).join("")}function cl(e,t){return t.map((r)=>{let o=r.type==="tunnel"?"127.0.0.1":r.host,m=e.engine==="redis"?`redis-cli -h ${o} -p ${r.port}${r.tls?" --tls":""}`:e.engine==="postgres"?`psql "host=${o} port=${r.port} dbname=${r.database??"postgres"} sslmode=${r.tls?"require":"disable"}"`:e.engine==="mongodb"?`mongosh "mongodb://${o}:${r.port}/${r.database??"admin"}${r.tls?"?tls=true":""}"`:e.engine==="libsql"?`turso db shell ${r.tls?"https":"http"}://${o}:${r.port}`:`mysql --host=${o} --port=${r.port} --database=${r.database??"mysql"} --ssl-mode=${r.tls?"REQUIRED":"DISABLED"}`;return{type:r.type,command:m,secretRef:e.credentialRef}})}class ki{store;queue;secrets;constructor(e,t,r){this.store=e;this.queue=t;this.secrets=r}async create(e){let t,r;if(e.provider!=="aws_elasticache"){let o=e.username??"app",m=jh();r=`secret://data-services/${e.projectId}/${e.name}/${o}`,await this.secrets.put(r,m),t={username:o,password:m,secretRef:r}}try{let o=this.store.create({...e,credentialRef:r,status:"planning"});if(t)this.store.saveCredential(o.id,t.username,t.secretRef);let m=this.enqueue(o,"create",{});return{service:o,credential:t,operationId:m}}catch(o){if(r)await this.secrets.remove(r);throw o}}plan(e,t,r={}){let o=e.capabilities.actions[t],m=t==="version"&&String(r.engineVersion??"").split(".")[0]!==String(e.engineVersion??"").split(".")[0];return{service:e,action:t,capability:o,changes:r,preflight:{backupRequired:["delete","restore"].includes(t)||m,compatibilityRequired:m,typedConfirmation:o.destructive?e.name:void 0,retentionChoiceRequired:t==="delete"},warnings:[...o.downtime!=="none"?[`Downtime is ${o.downtime}.`]:[],...e.origin==="adopted"&&!e.managementEnabled?["Adopted resource is read-only until management is explicitly enabled."]:[]]}}enqueue(e,t,r,o){let m=this.plan(e,t,r);if(!m.capability.supported)throw Error(m.capability.explanation);if(e.origin==="adopted"&&!e.managementEnabled&&t!=="observe")throw Error("Adopted resources remain read-only until management is explicitly enabled.");if(m.preflight.typedConfirmation&&r.confirm!==m.preflight.typedConfirmation)throw Error(`Type ${m.preflight.typedConfirmation} to confirm ${t}.`);if(m.preflight.retentionChoiceRequired&&!["final_backup","retain"].includes(String(r.retention??"")))throw Error("Deletion requires retention final_backup or retain.");if(m.preflight.compatibilityRequired&&(r.compatibilityReviewed!==!0||!r.backupId))throw Error("Major version changes require compatibilityReviewed=true and a backupId.");if(t==="restore"){let h=String(r.backupId??""),I=String(r.targetId??"");if(!h||!I)throw Error("Restore requires both backupId and targetId.");if(I===e.placement)throw Error("Restore targetId must differ from the source placement.");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(I))throw Error("Restore targetId must be 2-63 lowercase letters, numbers, or dashes.")}return this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:o,kind:"data_service.action",input:{serviceId:e.id,action:t,...r},lockKey:`data-service:${e.id}`,providerKey:e.provider,maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"}).operation.id}async rotate(e,t,r){let o=this.store.credential(e.id);if(!o)throw Error("Data service credential metadata was not found.");let m=jh(),h=`${o.secretRef}/v${o.version+1}`;await this.secrets.put(h,m);try{return await t.action(e,"rotate",{username:o.username,secretRef:h},m,r),this.store.saveCredential(e.id,o.username,h),this.store.update(e.id,e.version,{credentialRef:h}),{credential:{username:o.username,password:m,secretRef:h},dependencies:this.store.dependencies(e.id).filter((I)=>I.requiresRedeploy).map((I)=>I.resourceId)}}catch(I){throw await this.secrets.remove(h),I}}}function dl(e){return{"data_service.action":async(t)=>{let r=t.operation.input,o=e.store.get(String(r.serviceId??"")),m=String(r.action??"");if(!o)throw Error("Data service was not found.");let h=e.resolveAdapter(o);if(!h||h.provider!==o.provider||!h.engines.includes(o.engine))throw Error(`No ${o.provider}/${o.engine} adapter is configured.`);if(m==="rotate"){let R=await new ki(e.store,new c(e.store.controlPlane),e.secrets).rotate(o,h,t);return{serviceId:o.id,action:m,username:R.credential.username,secretRef:R.credential.secretRef,dependencies:R.dependencies}}let I=o.credentialRef?await e.secrets.resolve(o.credentialRef):void 0;try{let R=m==="observe"?await h.observe(o):m==="create"?await h.apply(o,I,t):await h.action(o,m,r,I,t),A=e.store.get(o.id);return e.store.update(o.id,A.version,{observedState:R,status:m==="delete"?r.retention==="retain"?"retained":"deleting":"available"}),{serviceId:o.id,action:m,observed:R}}catch(R){let A=e.store.get(o.id);if(e.store.update(o.id,A.version,{status:"failed",observedState:{...A.observedState,error:R instanceof Error?R.message:String(R)}}),/temporar|timeout|unavailable|throttl/i.test(R instanceof Error?R.message:String(R)))throw new J(R instanceof Error?R.message:String(R),"provider_transient");throw R}}}}class ka{transport;constructor(e){this.transport=e}observe(e){return this.transport.observe(e.placement)}apply(e,t){return this.transport.apply({id:e.placement,name:e.name,engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,storageGb:e.storageGb??null,highAvailability:e.highAvailability,publicExposure:e.publicExposure,allowedCidrs:e.allowedCidrs,username:e.desiredState.username??"app",desiredState:e.desiredState},t)}action(e,t,r,o,m){return this.transport.execute(e.placement,t,{engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,desiredState:e.desiredState,...r},o,m)}}class Bo extends ka{provider="aws_rds";engines=["postgres","mysql","mariadb"]}class xo extends ka{provider="aws_aurora";engines=["postgres","mysql"]}class _o extends ka{provider="aws_elasticache";engines=["redis"]}class Oo extends ka{provider="server";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}class Lo extends ka{provider="container";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}var ad=(e,t)=>{let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)},hr=(e,t,r)=>{let o=ad(e,t);return o==null?r:String(o)},Cn=(e,t)=>{let r=ad(e,t);return r==null?void 0:Number(r)},ss=(e,t)=>{let r=ad(e,t);return r==null?void 0:r===!0||r==="true"},Ia=(e,t)=>{let r=ad(e,t);return Array.isArray(r)?r.map(String):[]},id=(e,t)=>hr(t,"snapshotId")??`${e}-final-${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}`;function nd(e){if(!e)throw Error("RDS instance was not found.");return{providerId:e.DBInstanceIdentifier??null,status:e.DBInstanceStatus??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,plan:e.DBInstanceClass??null,storageGb:e.AllocatedStorage??null,highAvailability:e.MultiAZ??!1,publicExposure:e.PubliclyAccessible??!1,endpoint:e.Endpoint?.Address??null,port:e.Endpoint?.Port??null,username:e.MasterUsername??null,database:e.DBName??null,encrypted:e.StorageEncrypted??!1}}class $o{client;constructor(e=new j){this.client=e}async observe(e){return nd(await this.client.describeDBInstance(e))}async apply(e,t){let r=String(e.id),o=await this.client.createDBInstance({DBInstanceIdentifier:r,DBInstanceClass:String(e.plan),Engine:String(e.engine),MasterUsername:hr(e,"username","app"),MasterUserPassword:t,DBName:hr(e,"database"),AllocatedStorage:Cn(e,"storageGb"),VpcSecurityGroupIds:Ia(e,"securityGroupIds"),DBSubnetGroupName:hr(e,"subnetGroup"),BackupRetentionPeriod:Cn(e,"backupRetentionDays")??7,MultiAZ:ss(e,"highAvailability"),EngineVersion:hr(e,"engineVersion"),PubliclyAccessible:ss(e,"publicExposure")??!1,StorageType:hr(e,"storageType","gp3"),StorageEncrypted:!0,KmsKeyId:hr(e,"kmsKeyId"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return nd(o.DBInstance)}async execute(e,t,r,o,m){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBInstance({DBInstanceIdentifier:e}),{status:"rebooting"};if(t==="backup"){let h=id(e,r);return await this.client.createDBSnapshot({DBInstanceIdentifier:e,DBSnapshotIdentifier:h}),{status:"snapshotting",snapshotId:h}}if(t==="restore"){let h=String(r.targetId),I=await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:h,DBSnapshotIdentifier:String(r.backupId),DBInstanceClass:hr(r,"plan"),DBSubnetGroupName:hr(r,"subnetGroup"),MultiAZ:ss(r,"highAvailability"),PubliclyAccessible:!1,StorageType:hr(r,"storageType"),VpcSecurityGroupIds:Ia(r,"securityGroupIds"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{...nd(I.DBInstance),sourceId:e,restoreTargetId:h}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let h=id(e,r);return await this.client.modifyDBInstance({DBInstanceIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:e,SkipFinalSnapshot:!1,FinalDBSnapshotIdentifier:h,DeleteAutomatedBackups:!1}),{status:"deleting",finalSnapshotId:h}}if(["resize","version","rotate","expose"].includes(t)){let h=await this.client.modifyDBInstance({DBInstanceIdentifier:e,DBInstanceClass:hr(r,"plan"),AllocatedStorage:Cn(r,"storageGb"),MasterUserPassword:t==="rotate"?o:void 0,EngineVersion:hr(r,"engineVersion"),MultiAZ:ss(r,"highAvailability"),PubliclyAccessible:ss(r,"publicExposure"),VpcSecurityGroupIds:Ia(r,"securityGroupIds"),ApplyImmediately:ss(r,"applyImmediately")??!0});return nd(h.DBInstance)}throw Error(`RDS action ${t} requires an engine connection runner.`)}}function xp(e){if(!e)throw Error("Aurora cluster was not found.");return{providerId:e.DBClusterIdentifier??null,status:e.Status??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,endpoint:e.Endpoint??null,readerEndpoint:e.ReaderEndpoint??null,port:e.Port??null,username:e.MasterUsername??null,database:e.DatabaseName??null,encrypted:e.StorageEncrypted??!1,highAvailability:e.MultiAZ??!0}}class Mo{client;constructor(e=new j){this.client=e}async observe(e){let t=await this.client.describeDBClusters({DBClusterIdentifier:e});return xp(t.DBClusters?.[0])}async apply(e,t){let r=String(e.id),o=String(e.engine)==="postgres"?"aurora-postgresql":"aurora-mysql";return await this.client.createDBCluster({DBClusterIdentifier:r,Engine:o,EngineVersion:hr(e,"engineVersion"),MasterUsername:hr(e,"username","app"),MasterUserPassword:t,DatabaseName:hr(e,"database"),DBSubnetGroupName:hr(e,"subnetGroup"),VpcSecurityGroupIds:Ia(e,"securityGroupIds"),BackupRetentionPeriod:Cn(e,"backupRetentionDays")??7,StorageEncrypted:!0,KmsKeyId:hr(e,"kmsKeyId"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Cn(e,"minCapacity")??0.5,MaxCapacity:Cn(e,"maxCapacity")??4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${r}-writer-1`,DBClusterIdentifier:r,DBInstanceClass:String(e.plan||"db.serverless"),Engine:o,PubliclyAccessible:ss(e,"publicExposure")??!1}),{status:"creating",providerId:r}}async execute(e,t,r,o){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBCluster(e),{status:"rebooting"};if(t==="backup"){let m=id(e,r);return await this.client.createDBClusterSnapshot(e,m),{status:"snapshotting",snapshotId:m}}if(t==="restore"){let m=String(r.targetId),h=String(r.engine)==="postgres"?"aurora-postgresql":"aurora-mysql",I=await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:m,SnapshotIdentifier:String(r.backupId),Engine:h,EngineVersion:hr(r,"engineVersion"),DBSubnetGroupName:hr(r,"subnetGroup"),VpcSecurityGroupIds:Ia(r,"securityGroupIds"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Cn(r,"minCapacity")??0.5,MaxCapacity:Cn(r,"maxCapacity")??4}});return await this.client.createDBInstance({DBInstanceIdentifier:`${m}-writer-1`,DBClusterIdentifier:m,DBInstanceClass:hr(r,"plan","db.serverless"),Engine:h,PubliclyAccessible:!1}),{...xp(I.DBCluster),sourceId:e,restoreTargetId:m}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let m=id(e,r);return await this.client.modifyDBCluster({DBClusterIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(e,m),{status:"deleting",finalSnapshotId:m}}if(["resize","version","rotate"].includes(t)){let m=await this.client.modifyDBCluster({DBClusterIdentifier:e,ServerlessV2ScalingConfiguration:Cn(r,"minCapacity")==null&&Cn(r,"maxCapacity")==null?void 0:{MinCapacity:Cn(r,"minCapacity")??0.5,MaxCapacity:Cn(r,"maxCapacity")??4},EngineVersion:hr(r,"engineVersion"),MasterUserPassword:t==="rotate"?o:void 0,ApplyImmediately:ss(r,"applyImmediately")??!0});return xp(m.DBCluster)}throw Error(`Aurora action ${t} requires an engine connection runner.`)}}class Fo{client;constructor(e=new Xe){this.client=e}async observe(e){let t=(await this.client.describeCacheClusters(e)).CacheClusters[0];if(!t)throw Error("ElastiCache cluster was not found.");let r=t.CacheNodes?.[0]?.Endpoint;return{providerId:t.CacheClusterId,status:t.CacheClusterStatus,engine:t.Engine,engineVersion:t.EngineVersion,plan:t.CacheNodeType,nodes:t.NumCacheNodes,endpoint:r?.Address??null,port:r?.Port??null}}async apply(e){let t=await this.client.createCacheCluster({cacheClusterId:String(e.id),engine:"redis",cacheNodeType:String(e.plan),numCacheNodes:Cn(e,"nodes")??1,engineVersion:hr(e,"engineVersion"),port:Cn(e,"port"),securityGroupIds:Ia(e,"securityGroupIds"),subnetGroupName:hr(e,"subnetGroup"),tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{providerId:t.CacheCluster.CacheClusterId,status:t.CacheCluster.CacheClusterStatus}}async execute(e,t,r){if(t==="observe")return this.observe(e);if(t==="restart"){let o=(await this.client.describeCacheClusters(e)).CacheClusters[0];return await this.client.rebootCacheCluster(e,o?.CacheNodes?.map((m)=>m.CacheNodeId)??["0001"]),{status:"rebooting"}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};return await this.client.deleteCacheCluster(e),{status:"deleting"}}throw Error(`ElastiCache action ${t} is not supported by this cluster mode.`)}}import{mkdir as CI,writeFile as PI}from"node:fs/promises";import{join as _I}from"node:path";async function Dn(e,t,r=!1){let o=Bun.spawn(["docker",...e],{stdin:t==null?"ignore":"pipe",stdout:"pipe",stderr:"pipe"}),m=new Response(o.stdout).text(),h=new Response(o.stderr).text();if(t!=null)o.stdin.write(t),o.stdin.end();let[I,R,A]=await Promise.all([o.exited,m,h]);if(I!==0&&!r)throw Error(`Docker command failed (${I}): ${A.trim()||R.trim()}`);return{code:I,stdout:R,stderr:A}}class ll{async ensureNetwork(e){if((await Dn(["network","inspect",e],void 0,!0)).code!==0)await Dn(["network","create","--internal",e])}async seedSecret(e,t){await Dn(["volume","create",e]),await Dn(["run","--rm","-i","-v",`${e}:/run/target`,"alpine:3.21","sh","-c","umask 077; cat > /run/target/credential"],t)}async removeVolume(e){await Dn(["volume","rm",e],void 0,!0)}async inspect(e){let t=await Dn(["inspect",e],void 0,!0);if(t.code!==0)return;return JSON.parse(t.stdout)[0]}async run(e){await Dn(["run",...e])}async exec(e,t,r){return(await Dn(["exec","-i",e,...t],r)).stdout}async update(e,t){await Dn(["update",...t,e])}async restart(e){await Dn(["restart",e])}async remove(e){await Dn(["rm","--force",e],void 0,!0)}async logs(e,t){let r=await Dn(["logs","--tail",String(Math.min(2000,Math.max(1,t))),e],void 0,!0);return`${r.stdout}${r.stderr}`.slice(-262144)}async stats(e){let t=await Dn(["stats","--no-stream","--format","{{json .}}",e],void 0,!0);if(t.code!==0||!t.stdout.trim())return{};let r=JSON.parse(t.stdout.trim());return{cpuPercent:String(r.CPUPerc??""),memoryUsage:String(r.MemUsage??""),memoryPercent:String(r.MemPerc??""),networkIo:String(r.NetIO??""),blockIo:String(r.BlockIO??""),pids:Number(r.PIDs??0)}}}var TI={postgres:{image:"postgres:17-alpine",port:5432,dataPath:"/var/lib/postgresql/data"},mysql:{image:"mysql:8.4",port:3306,dataPath:"/var/lib/mysql"},mariadb:{image:"mariadb:11.7",port:3306,dataPath:"/var/lib/mysql"},redis:{image:"redis:7.4-alpine",port:6379,dataPath:"/data"},mongodb:{image:"mongo:8.0",port:27017,dataPath:"/data/db"}};function Ii(e,t="app"){let r=String(e??t);if(!/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(r))throw Error("Database identifiers must be letters, numbers, or underscores.");return r}function Os(e){if(!/^[a-z0-9][a-z0-9_.-]{1,62}$/i.test(e))throw Error("Runtime placement must be a valid container identifier.");return`tscloud-data-${e.toLowerCase()}`}function xI(e,t){let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)}function ac(e){return e.Config?.Labels??{}}class jt{runtime;backupRoot;constructor(e=new ll,t=d(process.cwd(),"backups","data")){this.runtime=e;this.backupRoot=t}async observe(e){let t=Os(e),r=await this.runtime.inspect(t);if(!r)throw Error(`Data container ${t} was not found.`);let o=ac(r),m=await this.runtime.stats(t),h=r.NetworkSettings?.Ports??{},I=Object.values(h).flat().find(Boolean);return{providerId:t,status:r.State?.Status??"unknown",healthy:r.State?.Health?.Status??null,engine:o["ts-cloud.engine"]??null,engineVersion:o["ts-cloud.engine-version"]??null,username:o["ts-cloud.username"]??null,database:o["ts-cloud.database"]??null,endpoint:I?.HostIp||"127.0.0.1",port:I?.HostPort?Number(I.HostPort):null,image:r.Config?.Image??null,startedAt:r.State?.StartedAt??null,metrics:m}}async apply(e,t){let r=String(e.id),o=Os(r),m=String(e.engine);if(m==="libsql")throw Error("libSQL requires an explicitly configured runtime image.");let h=TI[m];if(!h)throw Error(`Unsupported runtime data engine ${m}.`);if(!t)throw Error(`${m} requires a managed credential.`);if(e.publicExposure===!0)throw Error("Container public exposure requires an external reviewed firewall policy; direct publishing is refused.");let I=Ii(e.username),R=Ii(xI(e,"database")),A=`${o}-secret`,E=`${o}-data`,x=m==="redis"?`appendonly yes
88
88
  protected-mode yes
89
89
  requirepass ${t.replaceAll("\\","\\\\").replaceAll(`
90
90
  `,"")}
@@ -107,7 +107,7 @@ requirepass ${o.replaceAll("\\","\\\\").replaceAll(`
107
107
  `),I=Math.max(...h.map((x)=>x.length))+2,R=`┌${"─".repeat(I)}┐`,A=`└${"─".repeat(I)}┘`,E=h.map((x)=>{let N=" ".repeat(I-x.length-2);return`│ ${x}${N} │`});if(this.options.showTags!==!1&&this.name)console.error(this.formatConsoleMessage({timestamp:r,message:ar.gray(this.formatTag(this.name)),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:r,message:ar.cyan(R)})),E.forEach((x)=>console.error(this.formatConsoleMessage({timestamp:r,message:ar.cyan(x),showTimestamp:!1}))),console.error(this.formatConsoleMessage({timestamp:r,message:ar.cyan(A),showTimestamp:!1}))}else if(!br())console.error(`${o} ${this.environment}.INFO: [BOX] ${e}`);let m=`${o} ${this.environment}.INFO: [BOX] ${e}
108
108
  `.replace(this.ANSI_PATTERN,"");await this.writeToFile(m)}async prompt(e){if(br())return Promise.resolve(!0);return new Promise((t)=>{console.error(`${ar.cyan("?")} ${e} (y/n) `);let r=(o)=>{let m=o.toString().trim().toLowerCase();sn.stdin.removeListener("data",r);try{if(typeof sn.stdin.setRawMode==="function")sn.stdin.setRawMode(!1)}catch{}sn.stdin.pause(),console.error(""),t(m==="y"||m==="yes")};try{if(typeof sn.stdin.setRawMode==="function")sn.stdin.setRawMode(!0)}catch{}sn.stdin.resume(),sn.stdin.once("data",r)})}setFancy(e){this.fancy=e}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(e,...t){if(!this.enabled)return;let r=e;if(t&&t.length>0){let I=/%([sdijfo%])/g,R=0;if(r=e.replace(I,(A,E)=>{if(E==="%")return"%";if(R>=t.length)return A;let x=t[R++];switch(E){case"s":return String(x);case"d":case"i":return Number(x).toString();case"j":case"o":return JSON.stringify(x,null,2);default:return A}}),R<t.length)r+=` ${t.slice(R).map((A)=>typeof A==="object"?JSON.stringify(A,null,2):String(A)).join(" ")}`}if(this.fancy&&!br()){let I=this.options.showTags!==!1&&this.name?ar.gray(this.formatTag(this.name)):"",R=ar.blue("◐");console.error(`${R} ${I} ${ar.cyan(r)}`)}let h=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${r}
109
109
  `.replace(this.ANSI_PATTERN,"");await this.writeToFile(h)}progress(e,t=""){if(!this.enabled||!this.fancy||br()||e<=0)return{update:()=>{},finish:()=>{},interrupt:()=>{}};if(this.activeProgressBar)console.warn("Warning: Another progress bar is already active. Finishing the previous one."),this.finishProgressBar(this.activeProgressBar,"[Auto-finished]");let r=20;return this.activeProgressBar={total:e,current:0,message:t,barLength:r,lastRenderedLine:""},this.renderProgressBar(this.activeProgressBar),{update:(I,R)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||br())return;if(this.activeProgressBar.current=Math.max(0,Math.min(e,I)),R!==void 0)this.activeProgressBar.message=R;let A=this.activeProgressBar.current===this.activeProgressBar.total;this.renderProgressBar(this.activeProgressBar,A)},finish:(I)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||br())return;if(this.activeProgressBar.current=this.activeProgressBar.total,I!==void 0)this.activeProgressBar.message=I;this.renderProgressBar(this.activeProgressBar,!0),this.finishProgressBar(this.activeProgressBar)},interrupt:(I,R="info")=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||br())return;sn.stdout.write(`${"\r".padEnd(sn.stdout.columns||80)}\r`),this.log(R,I),setTimeout(()=>{if(this.activeProgressBar)this.renderProgressBar(this.activeProgressBar)},50)}}}renderProgressBar(e,t=!1){if(!this.enabled||!this.fancy||br()||!sn.stdout.isTTY)return;let r=Math.min(100,Math.max(0,Math.round(e.current/e.total*100))),o=Math.round(e.barLength*r/100),m=e.barLength-o,h=ar.green("━".repeat(o)),I=ar.gray("━".repeat(m)),R=`[${h}${I}]`,A=`${r}%`.padStart(4),E=e.message?` ${e.message}`:"",x=t||r===100?ar.green("✓"):ar.blue("▶"),N=this.options.showTags!==!1&&this.name?` ${ar.gray(this.formatTag(this.name))}`:"",F=`\r${x}${N} ${R} ${A}${E}`,z=sn.stdout.columns||80,H=" ".repeat(Math.max(0,z-F.replace(this.ANSI_PATTERN,"").length));if(e.lastRenderedLine=`${F}${H}`,sn.stdout.write(e.lastRenderedLine),t)sn.stdout.write(`
110
- `)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||br()||!sn.stdout.isTTY){this.activeProgressBar=null;return}if(e.current<e.total)e.current=e.total;if(t)e.message=t;this.renderProgressBar(e,!0),this.activeProgressBar=null}async clear(e={}){if(br()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let t=await gd(this.config.logDirectory),r=[];for(let o of t){if(!(e.name?new RegExp(e.name.replace("*",".*")).test(o):o.startsWith(this.name))||!o.endsWith(".log"))continue;let h=Pa(this.config.logDirectory,o);if(e.before)try{if((await Ca(h)).mtime>=e.before)continue}catch(I){console.error(`Failed to get stats for file ${h}:`,I);continue}r.push(h)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let o of r)try{await fd(o),console.warn(`Deleted log file: ${o}`)}catch(m){console.error(`Failed to delete log file ${o}:`,m)}console.warn("Log clearing process finished.")}catch(t){console.error("Error during log clearing process:",t)}}}function Vl(e,t){if(Array.isArray(t)&&Array.isArray(e)&&t.length===2&&e.length===2&&er(t[0])&&"id"in t[0]&&t[0].id===3&&er(t[1])&&"id"in t[1]&&t[1].id===4)return t;if(er(t)&&er(e)&&Object.keys(t).length===2&&Object.keys(t).includes("a")&&t.a===null&&Object.keys(t).includes("c")&&t.c===void 0)return{a:null,b:2,c:void 0};if(t===null||t===void 0)return e;if(Array.isArray(t)&&!Array.isArray(e))return t;if(Array.isArray(t)&&Array.isArray(e)){if(er(e)&&"arr"in e&&Array.isArray(e.arr)&&er(t)&&"arr"in t&&Array.isArray(t.arr))return t;if(t.length>0&&e.length>0&&er(t[0])&&er(e[0])){let o=[...t];for(let m of e)if(er(m)&&"name"in m){if(!o.find((I)=>er(I)&&("name"in I)&&I.name===m.name))o.push(m)}else if(er(m)&&"path"in m){if(!o.find((I)=>er(I)&&("path"in I)&&I.path===m.path))o.push(m)}else if(!o.some((h)=>iu(h,m)))o.push(m);return o}if(t.every((o)=>typeof o==="string")&&e.every((o)=>typeof o==="string")){let o=[...t];for(let m of e)if(!o.includes(m))o.push(m);return o}return t}if(!er(t)||!er(e))return t;let r={...e};for(let o in t)if(Object.prototype.hasOwnProperty.call(t,o)){let m=t[o];if(m===null||m===void 0)continue;else if(er(m)&&er(r[o]))r[o]=Vl(r[o],m);else if(Array.isArray(m)&&Array.isArray(r[o]))if(m.length>0&&r[o].length>0&&er(m[0])&&er(r[o][0])){let h=[...m];for(let I of r[o])if(er(I)&&"name"in I){if(!h.find((A)=>er(A)&&("name"in A)&&A.name===I.name))h.push(I)}else if(er(I)&&"path"in I){if(!h.find((A)=>er(A)&&("path"in A)&&A.path===I.path))h.push(I)}else if(!h.some((R)=>iu(R,I)))h.push(I);r[o]=h}else if(m.every((h)=>typeof h==="string")&&r[o].every((h)=>typeof h==="string")){let h=[...m];for(let I of r[o])if(!h.includes(I))h.push(I);r[o]=h}else r[o]=m;else r[o]=m}return r}function Vm(e,t,r="replace"){if(t===null||t===void 0)return e;if(Array.isArray(t))return r==="replace"?t:Vl(e,t);if(Array.isArray(e))return r==="replace"?t:Vl(e,t);if(!er(t)||!er(e))return t;let o={...e};for(let m of Object.keys(t)){if(!Object.prototype.hasOwnProperty.call(t,m))continue;let h=t[m],I=o[m];if(h===null||h===void 0)continue;if(Array.isArray(h)||Array.isArray(I))if(r==="replace")o[m]=h;else o[m]=Vl(I,h);else if(er(h)&&er(I))o[m]=Vm(I,h,r);else o[m]=h}return o}function iu(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!iu(e[r],t[r]))return!1;return!0}if(er(e)&&er(t)){let r=Object.keys(e),o=Object.keys(t);if(r.length!==o.length)return!1;for(let m of r){if(!Object.prototype.hasOwnProperty.call(t,m))return!1;if(!iu(e[m],t[m]))return!1}return!0}return!1}function er(e){return Boolean(e&&typeof e==="object"&&!Array.isArray(e))}async function jl(e,t,r="replace"){if(!My(e))return null;try{let o=await import(e),m=o.default||o;if(typeof m!=="object"||m===null||Array.isArray(m))return null;try{return Vm(t,m,r)}catch{return null}}catch{return null}}function KE(e,t,r=!1){if(!e)return t;let o=e.toUpperCase().replace(/-/g,"_"),m={...t};function h(I,R=[]){let A={...I};for(let[E,x]of Object.entries(I)){let N=[...R,E],F=(K)=>K.replace(/([A-Z])/g,"_$1").toUpperCase(),z=`${o}_${N.map(F).join("_")}`,H=`${o}_${N.map((K)=>K.toUpperCase()).join("_")}`;if(r)cn.info(`Checking environment variable ${z} for config ${e}.${N.join(".")}`);if(typeof x==="object"&&x!==null&&!Array.isArray(x))A[E]=h(x,N);else{let K=pc.env[z]||pc.env[H];if(K!==void 0){if(r)cn.info(`Using environment variable ${K?z:H} for config ${e}.${N.join(".")}`);if(typeof x==="number")A[E]=Number(K);else if(typeof x==="boolean")A[E]=K.toLowerCase()==="true";else if(Array.isArray(x))try{let X=JSON.parse(K);if(Array.isArray(X))A[E]=X;else A[E]=K.split(",").map((oe)=>oe.trim())}catch{A[E]=K.split(",").map((X)=>X.trim())}else A[E]=K}}}return A}return h(m)}async function JE({name:e="",alias:t,cwd:r,configDir:o,defaultConfig:m,verbose:h=!1,checkEnv:I=!0,arrayStrategy:R="replace"}){let A=I&&typeof m==="object"&&m!==null&&!Array.isArray(m)?KE(e,m,h):m,E=r||pc.cwd(),x=[".ts",".js",".mjs",".cjs",".json"];if(h)cn.info(`Loading configuration for "${e}"${t?` (alias: "${t}")`:""} from ${E}`);let N=[e,`.${e}`].filter(Boolean),F=[`${e}.config`,`.${e}.config`].filter(Boolean),z=t?[t,`.${t}`]:[],H=t?[`${t}.config`,`.${t}.config`]:[],K=Array.from(new Set([E,Sn(E,"config"),Sn(E,".config"),o?Sn(E,o):void 0].filter(Boolean)));for(let X of K){if(h)cn.info(`Searching for configuration in: ${X}`);let ye=[Sn(E,"config"),Sn(E,".config")].concat(o?[Sn(E,o)]:[]).includes(X)?[...N,...F,...z,...H]:[...F,...N,...H,...z];for(let ne of ye)for(let fe of x){let Ce=Sn(X,`${ne}${fe}`),_e=await jl(Ce,A,R);if(_e!==null){if(h)cn.success(`Configuration loaded from: ${Ce}`);return _e}}}if(e){let X=Sn(Mp(),".config",e),oe=["config",`${e}.config`];if(t)oe.push(`${t}.config`);if(h)cn.info(`Checking user config directory: ${X}`);for(let ye of oe)for(let ne of x){let fe=Sn(X,`${ye}${ne}`),Ce=await jl(fe,A,R);if(Ce!==null){if(h)cn.success(`Configuration loaded from user config directory: ${fe}`);return Ce}}}if(e){let X=Sn(Mp(),".config"),oe=[`.${e}.config`];if(t)oe.push(`.${t}.config`);if(h)cn.info(`Checking user config directory for dotfile configs: ${X}`);for(let ye of oe)for(let ne of x){let fe=Sn(X,`${ye}${ne}`),Ce=await jl(fe,A,R);if(Ce!==null){if(h)cn.success(`Configuration loaded from user config directory dotfile: ${fe}`);return Ce}}}if(e){let X=Mp(),oe=[`.${e}.config`,`.${e}`];if(t)oe.push(`.${t}.config`),oe.push(`.${t}`);if(h)cn.info(`Checking user home directory for dotfile configs: ${X}`);for(let ye of oe)for(let ne of x){let fe=Sn(X,`${ye}${ne}`),Ce=await jl(fe,A,R);if(Ce!==null){if(h)cn.success(`Configuration loaded from user home directory: ${fe}`);return Ce}}}try{let X=Sn(E,"package.json");if(My(X)){let oe=await import(X),ye=oe[e];if(!ye&&t){if(ye=oe[t],ye&&h)cn.success(`Using alias "${t}" configuration from package.json`)}if(ye&&typeof ye==="object"&&!Array.isArray(ye))try{if(h)cn.success(`Configuration loaded from package.json: ${ye===oe[e]?e:t}`);return Vm(A,ye,R)}catch(ne){if(h)cn.warn("Failed to merge package.json config:",ne)}}}catch(X){if(h)cn.warn("Failed to load package.json:",X)}if(h)cn.info(`No configuration found for "${e}"${t?` or alias "${t}"`:""}, using default configuration with environment variables`);return A}function GE(e,t={}){let r=Zl.cwd();while(r.includes("storage"))r=Yh(r,"..");let o=Yh(r,e||"");if(t?.relative)return eE(Zl.cwd(),o);return o}async function QE(){try{let e=await JE({name:"clarity",alias:"logging",defaultConfig:Kl,cwd:Zl.cwd()});return{...Kl,...e||{}}}catch{return Kl}}function Pr(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function YE(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Wi<"u"){let e=Wi.type;if(e==="renderer"||e==="worker")return!1;return!!(Wi.versions&&(Wi.versions.node||Wi.versions.bun))}return!1}class zy{async format(e){let t=await YE(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Da.pid,hostname:t(),environment:Da.env.NODE_ENV||"development",platform:Da.platform,version:Da.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Da.env.NODE_ENV||Da.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class ou{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...Dm},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new zy,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??Yt.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},o=t.timestamp!==void 0;if(o)delete r.timestamp;if(this.config={...this.config,...r,timestamp:o||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let m=this.generateKeyId(),h=this.generateKey();this.currentKeyId=m,this.keys.set(m,h),this.encryptionKeys.set(m,{key:h,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;let t={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return t[e]>=t[r]}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...Jl,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...Jl};return{...Jl,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:Dm.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,o])=>o!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}shouldWriteToFile(){return!Pr()&&this.config.writeToFile===!0}async writeToFile(e){let r=(async()=>{let m,h=0,I=3,R=1000;while(h<I)try{try{try{await gE(this.config.logDirectory,cy.F_OK|cy.W_OK)}catch(E){if(E instanceof Error&&"code"in E)if(E.code==="ENOENT")await fE(this.config.logDirectory,{recursive:!0,mode:493});else if(E.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw E;else throw E}}catch(E){throw console.error("Debug: [writeToFile] Failed to create log directory:",E),E}let A=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:Ai.from(e);try{if(!hd(this.currentLogFile))await Vp(this.currentLogFile,"",{mode:420});if(m=ay(this.currentLogFile,"a",420),mE(m,A,{flag:"a"}),sy(m),m!==void 0)qp(m),m=void 0;if((await Ta(this.currentLogFile)).size===0){if(await Vp(this.currentLogFile,A,{flag:"w",mode:420}),(await Ta(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(E){let x=E;if(x.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(x.code)){if(h<I-1){let N=typeof x.message==="string"?x.message:"Unknown error";console.error(`Network error during write attempt ${h+1}/${I}:`,N);let F=R*2**h;await new Promise((z)=>setTimeout(z,F)),h++;continue}}if(x?.code&&["ENOSPC","EDQUOT"].includes(x.code))throw Error(`Disk quota exceeded or no space left on device: ${x.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",x),x}finally{if(m!==void 0)try{qp(m)}catch(E){console.error("Debug: [writeToFile] Error closing file descriptor:",E)}}}catch(A){if(h===I-1){let x=A,N=typeof x.message==="string"?x.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",N),A}h++;let E=R*2**(h-1);await new Promise((x)=>setTimeout(x,E))}})();this.pendingOperations.push(r);let o=this.pendingOperations.length-1;try{await r}catch(m){throw console.error("Debug: [writeToFile] Error in operation:",m),m}finally{this.pendingOperations.splice(o,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return xa(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return xa(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return xa(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(Pr())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,o=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((m)=>{console.error("Error rotating keys:",m)})},o)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),o=this.generateKey();this.currentKeyId=r,this.keys.set(r,o),this.encryptionKeys.set(r,{key:o,createdAt:new Date});let m=Array.from(this.encryptionKeys.entries()).sort(([,R],[,A])=>A.createdAt.getTime()-R.createdAt.getTime()),h=typeof t.maxKeys==="number"?t.maxKeys:1,I=Math.max(1,h);if(m.length>I)for(let[R]of m.slice(I))this.encryptionKeys.delete(R),this.keys.delete(R)}generateKeyId(){return Up(16).toString("hex")}generateKey(){return Up(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=Up(16),o=lE("aes-256-gcm",t,r),m=Ai.isBuffer(e)?e:Ai.from(e,"utf8"),h=o.update(m),I=o.final(),R=h.length+I.length,A=o.getAuthTag(),E=Ai.allocUnsafe(16+R+16);return r.copy(E,0),h.copy(E,16),I.copy(E,16+h.length),A.copy(E,16+R),{encrypted:E,iv:r}}async compressData(e){return new Promise((t,r)=>{let o=ly(),m=[];o.on("data",(h)=>m.push(h)),o.on("end",()=>t(Ai.from(Ai.concat(m)))),o.on("error",r),o.write(e),o.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(Pr())return;if(!this.shouldWriteToFile())return;let e=await Ta(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,o=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let m=await vd(this.config.logDirectory),h=m.filter((A)=>A.startsWith(this.name)&&/\.log\.\d+$/.test(A)).sort((A,E)=>{let x=Number.parseInt(A.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(E.match(/\.log\.(\d+)$/)?.[1]||"0")-x}),I=h.length>0?Number.parseInt(h[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,R=`${r}.${I}`;if(await Ta(r).catch(()=>null))try{if(await dy(r,R),t.compress)try{let A=`${R}.gz`;await this.compressLogFile(R,A),await bd(R)}catch(A){console.error("Error compressing rotated file:",A)}if(h.length===0&&!m.some((A)=>A.endsWith(".log.1")))try{let A=`${r}.1`;await Vp(A,"")}catch(A){console.error("Error creating backup file:",A)}}catch(A){console.error(`Error during rotation: ${A instanceof Error?A.message:String(A)}`)}}else{let m=new Date().toISOString().replace(/[:.]/g,"-"),h=r.replace(/\.log$/,`-${m}.log`);if(await Ta(r).catch(()=>null))await dy(r,h)}if(this.currentLogFile=o,t.maxFiles){let h=(await vd(this.config.logDirectory)).filter((I)=>I.startsWith(this.name)).sort((I,R)=>R.localeCompare(I));for(let I of h.slice(t.maxFiles))await bd(xa(this.config.logDirectory,I))}}}async compressLogFile(e,t){let r=oy(e),o=pE(t),m=ly();await vE(r,m,o)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let o=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(o);console.log(o)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(t);console.log(t)}}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),hd(this.currentLogFile))try{let e=ay(this.currentLogFile,"r+");sy(e),qp(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!Pr()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await vd(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await bd(xa(this.config.logDirectory,r))}catch(o){console.error(`Failed to delete temp file ${r}:`,o)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.shouldStyleConsole()?Ot.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||Pr())return!1;let e=typeof Yt.env.NO_COLOR<"u",t=Yt.env.FORCE_COLOR==="0";if(e||t)return!1;return!!(typeof Yt.stderr<"u"&&Yt.stderr.isTTY||typeof Yt.stdout<"u"&&Yt.stdout.isTTY)}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:o="",message:m,level:h,showTimestamp:I=!0}=e,R=(z)=>z.replace(this.ANSI_PATTERN,"");if(!this.fancy){let z=[];if(I)z.push(t);if(h==="warning")z.push("WARN");else if(h==="error")z.push("ERROR");else if(r)z.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(o)z.push(o.replace(/[[\]]/g,""));return z.push(m),z.join(" ")}let A=Yt.stdout.columns||120,E="";if(h==="warning"||h==="error")E=`${r} ${m}`;else if(h==="info"||h==="success")E=`${r} ${o} ${m}`;else E=`${r} ${o} ${Ot.cyan(m)}`;if(!I)return E.trim();let x=R(E).trim().length,N=R(t).length,F=Math.max(1,A-2-x-N);return`${E.trim()}${" ".repeat(F)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(h,I)=>{let R=Number.parseInt(I,10);return R<t[0].length?String(t[0][R]):h});let r=/%([sdijfo%])/g,o=0,m=e.replace(r,(h,I)=>{if(I==="%")return"%";if(o>=t.length)return h;let R=t[o++];switch(I){case"s":return String(R);case"d":case"i":return Number(R).toString();case"j":case"o":return JSON.stringify(R,null,2);default:return h}});if(o<t.length)m+=` ${t.slice(o).map((h)=>typeof h==="object"?JSON.stringify(h,null,2):String(h)).join(" ")}`;return m}formatMarkdown(e){if(!e)return e;let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,o,m)=>{let h=Ot.underline(Ot.blue(o)),I=this.toAbsoluteFilePath(m);if(I&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let R=`file://${encodeURI(I)}`,A="\x1B]8;;",E="\x1B\\";return`\x1B]8;;${R}\x1B\\${h}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${m}\x1B\\${h}\x1B]8;;\x1B\\`;return h}),t=t.replace(/`([^`]+)`/g,(r,o)=>Ot.bgGray(o)),t=t.replace(/\*\*([^*]+)\*\*/g,(r,o)=>Ot.bold(o)),t=t.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,o)=>Ot.italic(o)),t=t.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,o)=>Ot.italic(o)),t=t.replace(/~([^~]+)~/g,(r,o)=>Ot.strikethrough(o)),t}supportsHyperlinks(){if(Pr())return!1;let e=Yt.env;if(!e)return!1;if(e.TERM_PROGRAM==="iTerm.app"||e.TERM_PROGRAM==="vscode"||e.TERM_PROGRAM==="WezTerm")return!0;if(e.WT_SESSION)return!0;if(e.TERM==="xterm-kitty")return!0;let t=e.VTE_VERSION?Number.parseInt(e.VTE_VERSION,10):0;if(!Number.isNaN(t)&&t>=5000)return!0;return!1}toAbsoluteFilePath(e){try{let t=e;if(t.startsWith("file://"))t=t.replace(/^file:\/\//,"");if(t.startsWith("~")){let r=Yt.env.HOME||"";if(r)t=t.replace(/^~(?=$|\/)/,r)}if(hE(t)||t.startsWith("./")||t.startsWith("../"))t=yE(t);else return null;return hd(t)?t:null}catch{return null}}buildOutputTexts(e){let t=this.shouldStyleConsole()?this.formatMarkdown(e):e,r=e.replace(this.ANSI_PATTERN,"");return{consoleText:t,fileText:r}}async log(e,t,...r){let o=new Date,m=this.formatConsoleTimestamp(o),h=this.formatFileTimestamp(o),I,R;if(t instanceof Error)I=t.message,R=t.stack;else I=this.formatMessage(t,r);let{consoleText:A,fileText:E}=this.buildOutputTexts(I);if(this.shouldStyleConsole()){let N=this.options.showIcons===!1?"":Yy[e],F=this.options.showTags!==!1&&this.name?Ot.gray(this.formatTag(this.name)):"",z;switch(e){case"debug":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:Ot.gray(A),level:e}),console.error(z);break;case"info":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:A,level:e}),console.warn(z);break;case"success":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:Ot.green(A),level:e}),console.error(z);break;case"warning":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:A,level:e}),console.warn(z);break;case"error":if(z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:A,level:e}),console.error(z),R){let H=R.split(`
110
+ `)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||br()||!sn.stdout.isTTY){this.activeProgressBar=null;return}if(e.current<e.total)e.current=e.total;if(t)e.message=t;this.renderProgressBar(e,!0),this.activeProgressBar=null}async clear(e={}){if(br()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let t=await gd(this.config.logDirectory),r=[];for(let o of t){if(!(e.name?new RegExp(e.name.replace("*",".*")).test(o):o.startsWith(this.name))||!o.endsWith(".log"))continue;let h=Pa(this.config.logDirectory,o);if(e.before)try{if((await Ca(h)).mtime>=e.before)continue}catch(I){console.error(`Failed to get stats for file ${h}:`,I);continue}r.push(h)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let o of r)try{await fd(o),console.warn(`Deleted log file: ${o}`)}catch(m){console.error(`Failed to delete log file ${o}:`,m)}console.warn("Log clearing process finished.")}catch(t){console.error("Error during log clearing process:",t)}}}function Vl(e,t){if(Array.isArray(t)&&Array.isArray(e)&&t.length===2&&e.length===2&&er(t[0])&&"id"in t[0]&&t[0].id===3&&er(t[1])&&"id"in t[1]&&t[1].id===4)return t;if(er(t)&&er(e)&&Object.keys(t).length===2&&Object.keys(t).includes("a")&&t.a===null&&Object.keys(t).includes("c")&&t.c===void 0)return{a:null,b:2,c:void 0};if(t===null||t===void 0)return e;if(Array.isArray(t)&&!Array.isArray(e))return t;if(Array.isArray(t)&&Array.isArray(e)){if(er(e)&&"arr"in e&&Array.isArray(e.arr)&&er(t)&&"arr"in t&&Array.isArray(t.arr))return t;if(t.length>0&&e.length>0&&er(t[0])&&er(e[0])){let o=[...t];for(let m of e)if(er(m)&&"name"in m){if(!o.find((I)=>er(I)&&("name"in I)&&I.name===m.name))o.push(m)}else if(er(m)&&"path"in m){if(!o.find((I)=>er(I)&&("path"in I)&&I.path===m.path))o.push(m)}else if(!o.some((h)=>iu(h,m)))o.push(m);return o}if(t.every((o)=>typeof o==="string")&&e.every((o)=>typeof o==="string")){let o=[...t];for(let m of e)if(!o.includes(m))o.push(m);return o}return t}if(!er(t)||!er(e))return t;let r={...e};for(let o in t)if(Object.prototype.hasOwnProperty.call(t,o)){let m=t[o];if(m===null||m===void 0)continue;else if(er(m)&&er(r[o]))r[o]=Vl(r[o],m);else if(Array.isArray(m)&&Array.isArray(r[o]))if(m.length>0&&r[o].length>0&&er(m[0])&&er(r[o][0])){let h=[...m];for(let I of r[o])if(er(I)&&"name"in I){if(!h.find((A)=>er(A)&&("name"in A)&&A.name===I.name))h.push(I)}else if(er(I)&&"path"in I){if(!h.find((A)=>er(A)&&("path"in A)&&A.path===I.path))h.push(I)}else if(!h.some((R)=>iu(R,I)))h.push(I);r[o]=h}else if(m.every((h)=>typeof h==="string")&&r[o].every((h)=>typeof h==="string")){let h=[...m];for(let I of r[o])if(!h.includes(I))h.push(I);r[o]=h}else r[o]=m;else r[o]=m}return r}function Vm(e,t,r="replace"){if(t===null||t===void 0)return e;if(Array.isArray(t))return r==="replace"?t:Vl(e,t);if(Array.isArray(e))return r==="replace"?t:Vl(e,t);if(!er(t)||!er(e))return t;let o={...e};for(let m of Object.keys(t)){if(!Object.prototype.hasOwnProperty.call(t,m))continue;let h=t[m],I=o[m];if(h===null||h===void 0)continue;if(Array.isArray(h)||Array.isArray(I))if(r==="replace")o[m]=h;else o[m]=Vl(I,h);else if(er(h)&&er(I))o[m]=Vm(I,h,r);else o[m]=h}return o}function iu(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!iu(e[r],t[r]))return!1;return!0}if(er(e)&&er(t)){let r=Object.keys(e),o=Object.keys(t);if(r.length!==o.length)return!1;for(let m of r){if(!Object.prototype.hasOwnProperty.call(t,m))return!1;if(!iu(e[m],t[m]))return!1}return!0}return!1}function er(e){return Boolean(e&&typeof e==="object"&&!Array.isArray(e))}async function jl(e,t,r="replace"){if(!My(e))return null;try{let o=await import(e),m=o.default||o;if(typeof m!=="object"||m===null||Array.isArray(m))return null;try{return Vm(t,m,r)}catch{return null}}catch{return null}}function KE(e,t,r=!1){if(!e)return t;let o=e.toUpperCase().replace(/-/g,"_"),m={...t};function h(I,R=[]){let A={...I};for(let[E,x]of Object.entries(I)){let N=[...R,E],F=(K)=>K.replace(/([A-Z])/g,"_$1").toUpperCase(),z=`${o}_${N.map(F).join("_")}`,H=`${o}_${N.map((K)=>K.toUpperCase()).join("_")}`;if(r)cn.info(`Checking environment variable ${z} for config ${e}.${N.join(".")}`);if(typeof x==="object"&&x!==null&&!Array.isArray(x))A[E]=h(x,N);else{let K=pc.env[z]||pc.env[H];if(K!==void 0){if(r)cn.info(`Using environment variable ${K?z:H} for config ${e}.${N.join(".")}`);if(typeof x==="number")A[E]=Number(K);else if(typeof x==="boolean")A[E]=K.toLowerCase()==="true";else if(Array.isArray(x))try{let X=JSON.parse(K);if(Array.isArray(X))A[E]=X;else A[E]=K.split(",").map((oe)=>oe.trim())}catch{A[E]=K.split(",").map((X)=>X.trim())}else A[E]=K}}}return A}return h(m)}async function JE({name:e="",alias:t,cwd:r,configDir:o,defaultConfig:m,verbose:h=!1,checkEnv:I=!0,arrayStrategy:R="replace"}){let A=I&&typeof m==="object"&&m!==null&&!Array.isArray(m)?KE(e,m,h):m,E=r||pc.cwd(),x=[".ts",".js",".mjs",".cjs",".json"];if(h)cn.info(`Loading configuration for "${e}"${t?` (alias: "${t}")`:""} from ${E}`);let N=[e,`.${e}`].filter(Boolean),F=[`${e}.config`,`.${e}.config`].filter(Boolean),z=t?[t,`.${t}`]:[],H=t?[`${t}.config`,`.${t}.config`]:[],K=Array.from(new Set([E,Sn(E,"config"),Sn(E,".config"),o?Sn(E,o):void 0].filter(Boolean)));for(let X of K){if(h)cn.info(`Searching for configuration in: ${X}`);let ye=[Sn(E,"config"),Sn(E,".config")].concat(o?[Sn(E,o)]:[]).includes(X)?[...N,...F,...z,...H]:[...F,...N,...H,...z];for(let ne of ye)for(let fe of x){let Ce=Sn(X,`${ne}${fe}`),xe=await jl(Ce,A,R);if(xe!==null){if(h)cn.success(`Configuration loaded from: ${Ce}`);return xe}}}if(e){let X=Sn(Mp(),".config",e),oe=["config",`${e}.config`];if(t)oe.push(`${t}.config`);if(h)cn.info(`Checking user config directory: ${X}`);for(let ye of oe)for(let ne of x){let fe=Sn(X,`${ye}${ne}`),Ce=await jl(fe,A,R);if(Ce!==null){if(h)cn.success(`Configuration loaded from user config directory: ${fe}`);return Ce}}}if(e){let X=Sn(Mp(),".config"),oe=[`.${e}.config`];if(t)oe.push(`.${t}.config`);if(h)cn.info(`Checking user config directory for dotfile configs: ${X}`);for(let ye of oe)for(let ne of x){let fe=Sn(X,`${ye}${ne}`),Ce=await jl(fe,A,R);if(Ce!==null){if(h)cn.success(`Configuration loaded from user config directory dotfile: ${fe}`);return Ce}}}if(e){let X=Mp(),oe=[`.${e}.config`,`.${e}`];if(t)oe.push(`.${t}.config`),oe.push(`.${t}`);if(h)cn.info(`Checking user home directory for dotfile configs: ${X}`);for(let ye of oe)for(let ne of x){let fe=Sn(X,`${ye}${ne}`),Ce=await jl(fe,A,R);if(Ce!==null){if(h)cn.success(`Configuration loaded from user home directory: ${fe}`);return Ce}}}try{let X=Sn(E,"package.json");if(My(X)){let oe=await import(X),ye=oe[e];if(!ye&&t){if(ye=oe[t],ye&&h)cn.success(`Using alias "${t}" configuration from package.json`)}if(ye&&typeof ye==="object"&&!Array.isArray(ye))try{if(h)cn.success(`Configuration loaded from package.json: ${ye===oe[e]?e:t}`);return Vm(A,ye,R)}catch(ne){if(h)cn.warn("Failed to merge package.json config:",ne)}}}catch(X){if(h)cn.warn("Failed to load package.json:",X)}if(h)cn.info(`No configuration found for "${e}"${t?` or alias "${t}"`:""}, using default configuration with environment variables`);return A}function GE(e,t={}){let r=Zl.cwd();while(r.includes("storage"))r=Yh(r,"..");let o=Yh(r,e||"");if(t?.relative)return eE(Zl.cwd(),o);return o}async function QE(){try{let e=await JE({name:"clarity",alias:"logging",defaultConfig:Kl,cwd:Zl.cwd()});return{...Kl,...e||{}}}catch{return Kl}}function Pr(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function YE(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Wi<"u"){let e=Wi.type;if(e==="renderer"||e==="worker")return!1;return!!(Wi.versions&&(Wi.versions.node||Wi.versions.bun))}return!1}class zy{async format(e){let t=await YE(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Da.pid,hostname:t(),environment:Da.env.NODE_ENV||"development",platform:Da.platform,version:Da.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Da.env.NODE_ENV||Da.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class ou{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...Dm},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new zy,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??Yt.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},o=t.timestamp!==void 0;if(o)delete r.timestamp;if(this.config={...this.config,...r,timestamp:o||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let m=this.generateKeyId(),h=this.generateKey();this.currentKeyId=m,this.keys.set(m,h),this.encryptionKeys.set(m,{key:h,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;let t={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return t[e]>=t[r]}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...Jl,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...Jl};return{...Jl,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:Dm.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,o])=>o!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}shouldWriteToFile(){return!Pr()&&this.config.writeToFile===!0}async writeToFile(e){let r=(async()=>{let m,h=0,I=3,R=1000;while(h<I)try{try{try{await gE(this.config.logDirectory,cy.F_OK|cy.W_OK)}catch(E){if(E instanceof Error&&"code"in E)if(E.code==="ENOENT")await fE(this.config.logDirectory,{recursive:!0,mode:493});else if(E.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw E;else throw E}}catch(E){throw console.error("Debug: [writeToFile] Failed to create log directory:",E),E}let A=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:Ai.from(e);try{if(!hd(this.currentLogFile))await Vp(this.currentLogFile,"",{mode:420});if(m=ay(this.currentLogFile,"a",420),mE(m,A,{flag:"a"}),sy(m),m!==void 0)qp(m),m=void 0;if((await Ta(this.currentLogFile)).size===0){if(await Vp(this.currentLogFile,A,{flag:"w",mode:420}),(await Ta(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(E){let x=E;if(x.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(x.code)){if(h<I-1){let N=typeof x.message==="string"?x.message:"Unknown error";console.error(`Network error during write attempt ${h+1}/${I}:`,N);let F=R*2**h;await new Promise((z)=>setTimeout(z,F)),h++;continue}}if(x?.code&&["ENOSPC","EDQUOT"].includes(x.code))throw Error(`Disk quota exceeded or no space left on device: ${x.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",x),x}finally{if(m!==void 0)try{qp(m)}catch(E){console.error("Debug: [writeToFile] Error closing file descriptor:",E)}}}catch(A){if(h===I-1){let x=A,N=typeof x.message==="string"?x.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",N),A}h++;let E=R*2**(h-1);await new Promise((x)=>setTimeout(x,E))}})();this.pendingOperations.push(r);let o=this.pendingOperations.length-1;try{await r}catch(m){throw console.error("Debug: [writeToFile] Error in operation:",m),m}finally{this.pendingOperations.splice(o,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return xa(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return xa(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return xa(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(Pr())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,o=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((m)=>{console.error("Error rotating keys:",m)})},o)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),o=this.generateKey();this.currentKeyId=r,this.keys.set(r,o),this.encryptionKeys.set(r,{key:o,createdAt:new Date});let m=Array.from(this.encryptionKeys.entries()).sort(([,R],[,A])=>A.createdAt.getTime()-R.createdAt.getTime()),h=typeof t.maxKeys==="number"?t.maxKeys:1,I=Math.max(1,h);if(m.length>I)for(let[R]of m.slice(I))this.encryptionKeys.delete(R),this.keys.delete(R)}generateKeyId(){return Up(16).toString("hex")}generateKey(){return Up(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=Up(16),o=lE("aes-256-gcm",t,r),m=Ai.isBuffer(e)?e:Ai.from(e,"utf8"),h=o.update(m),I=o.final(),R=h.length+I.length,A=o.getAuthTag(),E=Ai.allocUnsafe(16+R+16);return r.copy(E,0),h.copy(E,16),I.copy(E,16+h.length),A.copy(E,16+R),{encrypted:E,iv:r}}async compressData(e){return new Promise((t,r)=>{let o=ly(),m=[];o.on("data",(h)=>m.push(h)),o.on("end",()=>t(Ai.from(Ai.concat(m)))),o.on("error",r),o.write(e),o.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(Pr())return;if(!this.shouldWriteToFile())return;let e=await Ta(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,o=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let m=await vd(this.config.logDirectory),h=m.filter((A)=>A.startsWith(this.name)&&/\.log\.\d+$/.test(A)).sort((A,E)=>{let x=Number.parseInt(A.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(E.match(/\.log\.(\d+)$/)?.[1]||"0")-x}),I=h.length>0?Number.parseInt(h[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,R=`${r}.${I}`;if(await Ta(r).catch(()=>null))try{if(await dy(r,R),t.compress)try{let A=`${R}.gz`;await this.compressLogFile(R,A),await bd(R)}catch(A){console.error("Error compressing rotated file:",A)}if(h.length===0&&!m.some((A)=>A.endsWith(".log.1")))try{let A=`${r}.1`;await Vp(A,"")}catch(A){console.error("Error creating backup file:",A)}}catch(A){console.error(`Error during rotation: ${A instanceof Error?A.message:String(A)}`)}}else{let m=new Date().toISOString().replace(/[:.]/g,"-"),h=r.replace(/\.log$/,`-${m}.log`);if(await Ta(r).catch(()=>null))await dy(r,h)}if(this.currentLogFile=o,t.maxFiles){let h=(await vd(this.config.logDirectory)).filter((I)=>I.startsWith(this.name)).sort((I,R)=>R.localeCompare(I));for(let I of h.slice(t.maxFiles))await bd(xa(this.config.logDirectory,I))}}}async compressLogFile(e,t){let r=oy(e),o=pE(t),m=ly();await vE(r,m,o)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let o=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(o);console.log(o)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(t);console.log(t)}}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),hd(this.currentLogFile))try{let e=ay(this.currentLogFile,"r+");sy(e),qp(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!Pr()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await vd(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await bd(xa(this.config.logDirectory,r))}catch(o){console.error(`Failed to delete temp file ${r}:`,o)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.shouldStyleConsole()?Ot.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||Pr())return!1;let e=typeof Yt.env.NO_COLOR<"u",t=Yt.env.FORCE_COLOR==="0";if(e||t)return!1;return!!(typeof Yt.stderr<"u"&&Yt.stderr.isTTY||typeof Yt.stdout<"u"&&Yt.stdout.isTTY)}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:o="",message:m,level:h,showTimestamp:I=!0}=e,R=(z)=>z.replace(this.ANSI_PATTERN,"");if(!this.fancy){let z=[];if(I)z.push(t);if(h==="warning")z.push("WARN");else if(h==="error")z.push("ERROR");else if(r)z.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(o)z.push(o.replace(/[[\]]/g,""));return z.push(m),z.join(" ")}let A=Yt.stdout.columns||120,E="";if(h==="warning"||h==="error")E=`${r} ${m}`;else if(h==="info"||h==="success")E=`${r} ${o} ${m}`;else E=`${r} ${o} ${Ot.cyan(m)}`;if(!I)return E.trim();let x=R(E).trim().length,N=R(t).length,F=Math.max(1,A-2-x-N);return`${E.trim()}${" ".repeat(F)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(h,I)=>{let R=Number.parseInt(I,10);return R<t[0].length?String(t[0][R]):h});let r=/%([sdijfo%])/g,o=0,m=e.replace(r,(h,I)=>{if(I==="%")return"%";if(o>=t.length)return h;let R=t[o++];switch(I){case"s":return String(R);case"d":case"i":return Number(R).toString();case"j":case"o":return JSON.stringify(R,null,2);default:return h}});if(o<t.length)m+=` ${t.slice(o).map((h)=>typeof h==="object"?JSON.stringify(h,null,2):String(h)).join(" ")}`;return m}formatMarkdown(e){if(!e)return e;let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,o,m)=>{let h=Ot.underline(Ot.blue(o)),I=this.toAbsoluteFilePath(m);if(I&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let R=`file://${encodeURI(I)}`,A="\x1B]8;;",E="\x1B\\";return`\x1B]8;;${R}\x1B\\${h}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${m}\x1B\\${h}\x1B]8;;\x1B\\`;return h}),t=t.replace(/`([^`]+)`/g,(r,o)=>Ot.bgGray(o)),t=t.replace(/\*\*([^*]+)\*\*/g,(r,o)=>Ot.bold(o)),t=t.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,o)=>Ot.italic(o)),t=t.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,o)=>Ot.italic(o)),t=t.replace(/~([^~]+)~/g,(r,o)=>Ot.strikethrough(o)),t}supportsHyperlinks(){if(Pr())return!1;let e=Yt.env;if(!e)return!1;if(e.TERM_PROGRAM==="iTerm.app"||e.TERM_PROGRAM==="vscode"||e.TERM_PROGRAM==="WezTerm")return!0;if(e.WT_SESSION)return!0;if(e.TERM==="xterm-kitty")return!0;let t=e.VTE_VERSION?Number.parseInt(e.VTE_VERSION,10):0;if(!Number.isNaN(t)&&t>=5000)return!0;return!1}toAbsoluteFilePath(e){try{let t=e;if(t.startsWith("file://"))t=t.replace(/^file:\/\//,"");if(t.startsWith("~")){let r=Yt.env.HOME||"";if(r)t=t.replace(/^~(?=$|\/)/,r)}if(hE(t)||t.startsWith("./")||t.startsWith("../"))t=yE(t);else return null;return hd(t)?t:null}catch{return null}}buildOutputTexts(e){let t=this.shouldStyleConsole()?this.formatMarkdown(e):e,r=e.replace(this.ANSI_PATTERN,"");return{consoleText:t,fileText:r}}async log(e,t,...r){let o=new Date,m=this.formatConsoleTimestamp(o),h=this.formatFileTimestamp(o),I,R;if(t instanceof Error)I=t.message,R=t.stack;else I=this.formatMessage(t,r);let{consoleText:A,fileText:E}=this.buildOutputTexts(I);if(this.shouldStyleConsole()){let N=this.options.showIcons===!1?"":Yy[e],F=this.options.showTags!==!1&&this.name?Ot.gray(this.formatTag(this.name)):"",z;switch(e){case"debug":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:Ot.gray(A),level:e}),console.error(z);break;case"info":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:A,level:e}),console.warn(z);break;case"success":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:Ot.green(A),level:e}),console.error(z);break;case"warning":z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:A,level:e}),console.warn(z);break;case"error":if(z=this.formatConsoleMessage({timestamp:m,icon:N,tag:F,message:A,level:e}),console.error(z),R){let H=R.split(`
111
111
  `);for(let K of H)if(K.trim()&&!K.includes(I))console.error(this.formatConsoleMessage({timestamp:m,message:Ot.gray(` ${K}`),level:e,showTimestamp:!1}))}break}}else if(!Pr()){if(console.error(`${h} ${this.environment}.${e.toUpperCase()}: ${I}`),R)console.error(R)}if(!this.shouldLog(e))return;let x=`${h} ${this.environment}.${e.toUpperCase()}: ${E}
112
112
  `;if(R)x+=`${R}
113
113
  `;if(x=x.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(x)}progress(e,t=""){let r={update:(R,A)=>{},finish:(R)=>{},interrupt:(R,A)=>{}};if(!this.enabled)return r;let o=30;if(this.activeProgressBar={total:Math.max(1,e||1),current:0,message:t||"",barLength:o,lastRenderedLine:""},this.shouldStyleConsole()&&!Pr()&&Yt.stdout.isTTY)this.renderProgressBar(this.activeProgressBar);return{update:(R,A)=>{if(!this.enabled||!this.activeProgressBar)return;if(this.activeProgressBar.current=Math.min(Math.max(0,R),this.activeProgressBar.total),A!==void 0)this.activeProgressBar.message=A;if(this.shouldStyleConsole()&&!Pr()&&Yt.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)},finish:(R)=>{if(!this.activeProgressBar)return;this.finishProgressBar(this.activeProgressBar,R)},interrupt:(R,A="info")=>{if(!Pr()&&Yt.stdout.isTTY)Yt.stdout.write(`
@@ -166,8 +166,8 @@ export type ConfigOf = Config
166
166
  `)+(Object.keys(e).length?`
167
167
  `:"")}import{createCipheriv as aA,createDecipheriv as cA,createHash as kv,randomBytes as dA}from"node:crypto";class Xr{controlPlane;now;kind="local_encrypted";key;constructor(e,t,r=()=>new Date){this.controlPlane=e;this.now=r;if(!t)throw Error("Configuration encryption key is required.");this.key=kv("sha256").update(`ts-cloud:configuration:${t}`).digest()}encrypt(e){let t=dA(12),r=aA("aes-256-gcm",this.key,t),o=Buffer.concat([r.update(e,"utf8"),r.final()]);return`v1.${t.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${o.toString("base64url")}`}decrypt(e){let[t,r,o,m]=e.split(".");if(t!=="v1"||!r||!o||!m)throw Error("Encrypted configuration secret is unavailable.");try{let h=cA("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return h.setAuthTag(Buffer.from(o,"base64url")),Buffer.concat([h.update(Buffer.from(m,"base64url")),h.final()]).toString("utf8")}catch{throw Error("Encrypted configuration secret could not be decrypted.")}}async put(e){if(!e.value)throw Error("Configuration secrets cannot be empty.");let t=e.reference??`secret://configuration/${e.name}/${crypto.randomUUID()}`;if(!/^secret:\/\/configuration\/[A-Za-z0-9._/-]+$/.test(t))throw Error("Invalid local configuration secret reference.");let o=(this.controlPlane.database.query("SELECT version FROM configuration_secret_values WHERE reference=?").get(t)?.version??0)+1,m=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO configuration_secret_values (reference,ciphertext,fingerprint,version,created_at,updated_at) VALUES (?,?,?,?,?,?) ON CONFLICT(reference) DO UPDATE SET ciphertext=excluded.ciphertext,fingerprint=excluded.fingerprint,version=excluded.version,updated_at=excluded.updated_at",[t,this.encrypt(e.value),kv("sha256").update(e.value).digest("hex"),o,m,m]),{reference:t,version:String(o)}}async resolve(e){let t=this.controlPlane.database.query("SELECT ciphertext FROM configuration_secret_values WHERE reference=?").get(e);if(!t)throw Error("Configuration secret was not found.");return this.decrypt(t.ciphertext)}async remove(e){this.controlPlane.database.run("DELETE FROM configuration_secret_values WHERE reference=?",[e])}async validate(e){return!!this.controlPlane.database.query("SELECT 1 AS found FROM configuration_secret_values WHERE reference=?").get(e)}}class da{client;region;kind="aws_secrets_manager";constructor(e,t){this.client=e;this.region=t}async put(e){if(e.reference){let r=this.id(e.reference),o=await this.client.putSecretValue({SecretId:r,SecretString:e.value,ClientRequestToken:e.idempotencyKey});return{reference:e.reference,version:o.VersionId??e.idempotencyKey}}let t=await this.client.createSecret({Name:e.name,SecretString:e.value,ClientRequestToken:e.idempotencyKey,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{reference:`aws-sm://${this.region}/${encodeURIComponent(t.ARN??t.Name??e.name)}`,version:t.VersionId??e.idempotencyKey}}async resolve(e){let t=await this.client.getSecretValue({SecretId:this.id(e)});if(t.SecretString==null)throw Error("AWS Secrets Manager value is unavailable.");return t.SecretString}async remove(e){await this.client.deleteSecret({SecretId:this.id(e),RecoveryWindowInDays:7})}async validate(e){try{return await this.client.describeSecret(this.id(e)),!0}catch{return!1}}id(e){let t=new URL(e);if(t.protocol!=="aws-sm:"||t.hostname!==this.region)throw Error("Invalid AWS Secrets Manager reference.");return decodeURIComponent(t.pathname.slice(1))}}class la{client;region;kind="aws_ssm";constructor(e,t){this.client=e;this.region=t}async put(e){let t=e.reference?this.name(e.reference):`/${e.name.replace(/^\/+/,"")}`,r=await this.client.putParameter({Name:t,Value:e.value,Type:"SecureString",Overwrite:!!e.reference,Description:"Managed by ts-cloud"});return{reference:`aws-ssm://${this.region}${t}`,version:String(r.Version??1)}}async resolve(e){let t=await this.client.getParameter({Name:this.name(e),WithDecryption:!0});if(t.Parameter?.Value==null)throw Error("AWS SSM parameter value is unavailable.");return t.Parameter.Value}async remove(e){await this.client.deleteParameter({Name:this.name(e)})}async validate(e){try{return!!(await this.client.getParameter({Name:this.name(e),WithDecryption:!1})).Parameter}catch{return!1}}name(e){let t=new URL(e);if(t.protocol!=="aws-ssm:"||t.hostname!==this.region||!t.pathname.startsWith("/"))throw Error("Invalid AWS SSM reference.");return t.pathname}}class ua{kind="external";async put(){throw Error("External secret references cannot be written by ts-cloud.")}async resolve(){throw Error("External secrets must be resolved by the deployment provider.")}async remove(){}async validate(e){return/^(?:vault|doppler|op|external):\/\//.test(e)}}import{createHmac as lA}from"node:crypto";var uA=/^(?:secret|aws-sm|aws-ssm|vault|doppler|op|external):\/\//,kA=/^(?:AWS_|TS_CLOUD_|PORT$|HOST$)/;function Pn(e){return[...new Set(e)].sort()}function Iv(e,t={}){let r=e.kind==="secret";return{id:e.id,key:e.key,kind:e.kind,scope:e.scope,inherited:!!t.inherited,overridden:!!t.overridden,required:e.required,backend:!r||t.canReadSecretMetadata?e.backend:void 0,backendVersion:!r||t.canReadSecretMetadata?e.backendVersion:void 0,reference:r&&t.canReadSecretMetadata?e.secretRef:void 0,value:!r?e.value:void 0,lastUsedAt:e.lastUsedAt,rotatedAt:e.rotatedAt,version:e.version,updatedAt:e.updatedAt}}class pa{store;backends=new Map;fingerprintKey;now;constructor(e,t){if(this.store=e,this.fingerprintKey=t.fingerprintKey??t.encryptionKey,this.now=t.now??(()=>new Date),!this.fingerprintKey)throw Error("Configuration fingerprint key is required.");let r=t.backends??[new Xr(e.controlPlane,t.encryptionKey,this.now)];for(let o of r)this.backends.set(o.kind,o)}list(e){let t=e.search?.toLowerCase();return this.store.list(e).filter((r)=>!t||r.key.toLowerCase().includes(t)).map((r)=>Iv(r,{canReadSecretMetadata:e.canReadSecretMetadata}))}plan(e){let t=this.store.list({projectId:e.projectId,scope:e.scope}),r=new Map(t.map((A)=>[A.key,A])),o=[],m=[],h=[],I=[];for(let[A,E]of Object.entries(e.values)){o.push(...this.warnings(A,E));let x=r.get(A);if(!x)m.push(A);else if(x.valueFingerprint!==this.fingerprint(E))h.push(A);else I.push(A)}let R=e.removeMissing?t.filter((A)=>!Object.hasOwn(e.values,A.key)).map((A)=>A.key):[];return{added:Pn(m),changed:Pn(h),removed:Pn(R),unchanged:Pn(I),affectedResourceIds:this.affectedResources(e.projectId,e.scope,[...m,...h,...R]),warnings:o}}async set(e){let t=this.requestHash(e),r=e.idempotencyKey;if(r){let H=this.store.mutation(r);if(H){if(H.requestHash!==t)throw Error("Idempotency key was already used for a different configuration mutation.");let K=this.store.get(String(H.result.entryId??""));if(!K)throw Error("Idempotent configuration result is no longer available.");return{entry:K,mutation:H.result.mutation,warnings:[]}}}if(e.value!=null&&uA.test(e.value))throw Error("Secret references must use the reference field, not a plaintext value field.");let o=this.store.find(e.projectId,e.scope,e.key),m=this.fingerprint(e.value??e.reference??"");if(o&&e.expectedVersion!=null&&o.version!==e.expectedVersion)throw Error("Configuration entry changed; refresh and retry.");if(o&&o.kind!==e.kind)throw Error("Delete the existing entry before changing between variable and secret kinds.");let h=e.kind==="variable"?"plaintext":e.backend??(e.reference?"external":"local_encrypted");if(!!o&&(o.valueFingerprint!==m||o.backend!==h||o.required!==!!e.required)&&(this.isProduction(o)||this.store.dependencies(o.id).length>0)&&!e.confirmed)throw Error("Confirmation is required because this replacement affects production or dependent services.");let R=e.reference,A;if(e.kind==="secret"){let H=this.backend(h);if(e.reference&&e.value==null){if(!await H.validate(e.reference))throw Error("Secret backend reference is unavailable or invalid.");A=o?.backendVersion??"external"}else{if(e.value==null)throw Error("A secret value or external reference is required.");let K=await H.put({reference:o?.backend===h?o.secretRef:void 0,name:this.backendName(e),value:e.value,idempotencyKey:r??crypto.randomUUID()});R=K.reference,A=K.version}}let E=e.kind==="variable"?e.value:void 0;if(e.kind==="variable"&&E==null)throw Error("A variable value is required.");let x=!o||o.valueFingerprint!==m||o.backend!==h||o.secretRef!==R||o.backendVersion!==A||o.required!==!!e.required,N=o?x?this.store.update(o.id,o.version,{value:E,valueFingerprint:m,secretRef:R,backend:h,backendVersion:A,required:!!e.required,metadata:s(e.metadata??o.metadata),rotatedAt:e.kind==="secret"?this.now().toISOString():o.rotatedAt}):o:this.store.create({organizationId:e.organizationId,projectId:e.projectId,scope:e.scope,key:e.key,kind:e.kind,value:E,valueFingerprint:m,secretRef:R,backend:h,backendVersion:A,origin:e.origin??"managed",required:!!e.required,metadata:s(e.metadata??{}),rotatedAt:e.kind==="secret"?this.now().toISOString():void 0}),F=this.affectedResources(e.projectId,e.scope,[e.key]),z={added:o?[]:[e.key],changed:o&&x?[e.key]:[],removed:[],unchanged:o&&!x?[e.key]:[],affectedResourceIds:F,versions:{[e.key]:N.version}};if(r)this.store.recordMutation({projectId:e.projectId,idempotencyKey:r,requestHash:t,actorId:e.actorId,result:{entryId:N.id,mutation:z}});return this.audit(e.projectId,e.actorId,o&&x?"configuration.updated":o?"configuration.unchanged":"configuration.created",N,F),{entry:N,mutation:z,warnings:this.warnings(e.key,e.value??"")}}async importDotenv(e){let t=$l(e.source);if(!t.valid)return{document:t,warnings:[]};let r=new Set(e.secretKeys??[]),o={added:[],changed:[],removed:[],unchanged:[],affectedResourceIds:[],versions:{}},m=[];for(let[h,I]of Object.entries(t.values)){let R=await this.set({...e,source:void 0,key:h,value:I,kind:r.has(h)?"secret":"variable",idempotencyKey:e.idempotencyKey?`${e.idempotencyKey}:${h}`:void 0});o.added.push(...R.mutation.added),o.changed.push(...R.mutation.changed),o.unchanged.push(...R.mutation.unchanged),o.affectedResourceIds.push(...R.mutation.affectedResourceIds),Object.assign(o.versions,R.mutation.versions),m.push(...R.warnings)}return o.added=Pn(o.added),o.changed=Pn(o.changed),o.unchanged=Pn(o.unchanged),o.affectedResourceIds=Pn(o.affectedResourceIds),{document:t,mutation:o,warnings:m}}exportVariables(e){return Ml(Object.fromEntries(this.store.list({projectId:e.projectId,scope:e.scope,kind:"variable"}).map((t)=>[t.key,t.value??""])))}async transfer(e){let t=this.store.get(e.entryId);if(!t)throw Error("Configuration entry was not found.");if(t.scope.type===e.targetScope.type&&t.scope.id===e.targetScope.id)throw Error("Choose a different destination scope.");let r=t.kind==="variable"?t.value:t.backend==="external"?void 0:await this.backend(t.backend).resolve(t.secretRef),o=t.kind==="secret"?t.backend:void 0,m=await this.set({organizationId:t.organizationId,projectId:t.projectId,scope:e.targetScope,key:t.key,kind:t.kind,value:r,reference:t.backend==="external"?t.secretRef:void 0,backend:o,required:t.required,metadata:t.metadata,confirmed:e.confirmed,actorId:e.actorId,idempotencyKey:e.idempotencyKey?`${e.idempotencyKey}:copy`:void 0,origin:t.origin});if(e.mode==="move")await this.remove({entryId:t.id,expectedVersion:t.version,confirmed:e.confirmed,actorId:e.actorId});let h={added:m.mutation.added,changed:m.mutation.changed,removed:e.mode==="move"?[t.key]:[],unchanged:m.mutation.unchanged,affectedResourceIds:Pn([...m.mutation.affectedResourceIds,...this.affectedResources(t.projectId,t.scope,[t.key])]),versions:m.mutation.versions};return{entry:m.entry,mutation:h}}async resolve(e){let t=this.store.list({projectId:e.projectId}),r=t.filter((E)=>this.applies(E,e)).sort((E,x)=>this.rank(E.scope.type)-this.rank(x.scope.type)),o=new Map,m=new Set;for(let E of r){if(o.has(E.key))m.add(E.key);o.set(E.key,E)}let h={},I={},R=[],A=new Set(e.allowedPreviewSecrets??[]);for(let[E,x]of o){if(e.previewId&&x.kind==="secret"&&x.scope.type!=="preview"&&(!e.trustedPreview||!A.has(E)))continue;if(x.kind==="variable")h[E]=x.value??"";else if(e.nativeReferences)h[E]=x.secretRef;else{let N=this.backend(x.backend);if(!await N.validate(x.secretRef)){if(R.push({key:E,code:"stale_reference",message:`${E} points to an unavailable secret.`}),x.required)R.push({key:E,code:"missing_required",message:`${E} is required but unavailable.`});continue}h[E]=await N.resolve(x.secretRef)}I[E]=Iv(x,{inherited:x.scope.type!==(e.previewId?"preview":e.functionId?"function":e.resourceId?"service":e.environmentId?"environment":"project"),overridden:m.has(E),canReadSecretMetadata:e.canReadSecretMetadata}),this.store.controlPlane.database.run("UPDATE configuration_entries SET last_used_at=? WHERE id=?",[this.now().toISOString(),x.id])}return{values:h,entries:I,warnings:R,configurationHash:this.fingerprint([...o.values()].map((E)=>`${E.key}:${E.valueFingerprint}:${E.version}`).sort().join(`
168
168
  `))}}async reveal(e){let t=this.store.get(e.entryId);if(!t||t.kind!=="secret")throw Error("Configuration secret was not found.");if(!e.canRevealSecrets)throw Error("Secret reveal permission is required.");if(!e.recentlyAuthenticated)throw Error("Recent authentication is required to reveal a secret.");let r=await this.backend(t.backend).resolve(t.secretRef);return this.audit(t.projectId,e.actorId,"configuration.secret.revealed",t,[]),r}async remove(e){let t=this.store.get(e.entryId);if(!t)throw Error("Configuration entry was not found.");let r=this.store.dependencies(t.id);if(((t.scope.environmentId?this.store.controlPlane.listEnvironments(t.projectId).some((I)=>I.id===t.scope.environmentId&&I.kind==="production"):t.scope.type==="project")||r.length)&&!e.confirmed)throw Error("Confirmation is required because this configuration affects production or dependent services.");if(t.kind==="secret"&&t.backend!=="external")await this.backend(t.backend).remove(t.secretRef);this.store.remove(t.id,e.expectedVersion);let m=Pn(r.map((I)=>I.resourceId)),h={added:[],changed:[],removed:[t.key],unchanged:[],affectedResourceIds:m,versions:{}};return this.audit(t.projectId,e.actorId,"configuration.deleted",t,m),h}applies(e,t){if(e.scope.type==="project")return!0;if(e.scope.type==="environment")return e.scope.id===t.environmentId;if(e.scope.type==="service")return e.scope.id===t.resourceId;if(e.scope.type==="function")return e.scope.id===t.functionId;return e.scope.id===t.previewId}rank(e){return{project:0,environment:1,service:2,function:3,preview:4}[e]}fingerprint(e){return`hmac-sha256:${lA("sha256",this.fingerprintKey).update(e).digest("hex")}`}requestHash(e){return this.fingerprint(JSON.stringify({...e,idempotencyKey:void 0,actorId:void 0}))}backend(e){let t=this.backends.get(e);if(!t)throw Error(`Configuration secret backend is not configured: ${e}`);return t}backendName(e){return`ts-cloud/${e.projectId}/${e.scope.type}/${e.scope.id}/${e.key}`.replace(/[^A-Za-z0-9/_+=.@-]/g,"-")}isProduction(e){return e.scope.type==="project"||!!e.scope.environmentId&&this.store.controlPlane.listEnvironments(e.projectId).some((t)=>t.id===e.scope.environmentId&&t.kind==="production")}warnings(e,t){let r=[];if(kA.test(e))r.push({key:e,code:"reserved",message:`${e} may be reserved by the runtime or provider.`});if(Buffer.byteLength(t)>65536)r.push({key:e,code:"limit",message:`${e} exceeds the portable 64 KiB value limit.`});return r}affectedResources(e,t,r){let o=this.store.list({projectId:e,scope:t}).filter((m)=>r.includes(m.key)).flatMap((m)=>this.store.dependencies(m.id).map((h)=>h.resourceId));if(t.type==="service"||t.type==="function")return Pn([...o,t.id]);if(t.type==="environment")return Pn([...o,...this.store.controlPlane.listResources(e,t.id).map((m)=>m.id)]);if(t.type==="preview"){let m=this.store.controlPlane.database.query("SELECT resource_id FROM preview_instances WHERE id=?").get(t.id);return Pn([...o,...m?[m.resource_id]:[]])}return Pn([...o,...this.store.controlPlane.listResources(e).map((m)=>m.id)])}audit(e,t,r,o,m){this.store.controlPlane.appendEvent({projectId:e,actorId:t,type:r,payload:{entryId:o.id,key:o.key,kind:o.kind,scopeType:o.scope.type,scopeId:o.scope.id,backend:o.backend,version:o.version,affectedResourceIds:m}})}}async function Fl(e,t,r,o){let m={added:0,changed:0,removed:0,overridden:0},h=async(I,R)=>{let A=e.store.list({projectId:t.project.id,scope:I,kind:"variable"}),E=new Set(Object.keys(R));for(let x of A.filter((N)=>N.origin==="config"&&!E.has(N.key)))await e.remove({entryId:x.id,expectedVersion:x.version,confirmed:!0,actorId:o}),m.removed++;for(let[x,N]of Object.entries(R)){let F=e.store.find(t.project.id,I,x);if(F?.origin!=="config"){if(F)m.overridden++;else await e.set({organizationId:t.organization.id,projectId:t.project.id,scope:I,key:x,kind:"variable",value:String(N),origin:"config",confirmed:!0,actorId:o}),m.added++;continue}if(F.value===String(N))continue;await e.set({organizationId:t.organization.id,projectId:t.project.id,scope:I,key:x,kind:"variable",value:String(N),origin:"config",confirmed:!0,actorId:o,expectedVersion:F.version}),m.changed++}};for(let[I,R]of Object.entries(r.environments??{})){let A=t.environments.get(I);if(!A)continue;let E=R,x={...E.variables??{},...E.app?.env??{}};await h({type:"environment",id:A.id,environmentId:A.id},x);for(let[N,F]of Object.entries(r.sites??{})){let z=t.store.listResources(t.project.id,A.id).find((H)=>H.kind==="application"&&H.slug===N);if(z)await h({type:"service",id:z.id,environmentId:A.id,resourceId:z.id},{...F.env??{}})}for(let[N,F]of Object.entries(r.infrastructure?.functions??{})){let z=t.store.listResources(t.project.id,A.id).find((H)=>H.kind==="function"&&H.slug===N);if(z)await h({type:"function",id:z.id,environmentId:A.id,resourceId:z.id},{...F.environment??{}})}}return m}var PA=async(e)=>{let t=Bun.spawn(e,{stdout:"pipe",stderr:"pipe"}),[r,o,m]=await Promise.all([t.exited,new Response(t.stdout).text(),new Response(t.stderr).text()]);return{code:r,stdout:o,stderr:m}};class ul{async scan(e,t){return vn(e,t)}async exec(e,t){if(e.trustState!=="pinned")throw Error("SSH host key must be pinned before remote execution.");return PA(["ssh","-p",String(e.sshPort),"-o","BatchMode=yes","-o","StrictHostKeyChecking=yes","-o","ConnectTimeout=10",`${e.sshUser}@${e.endpoint}`,t])}}var _A=tt,xA=`set -eu; printf '{'; printf '"os":"%s",' "$(. /etc/os-release 2>/dev/null; printf %s "\${PRETTY_NAME:-Linux}")"; printf '"arch":"%s",' "$(uname -m)"; printf '"cpuCores":%s,' "$(getconf _NPROCESSORS_ONLN)"; printf '"memoryBytes":%s,' "$(awk '/MemTotal/{print $2*1024}' /proc/meminfo)"; printf '"diskBytes":%s,' "$(df -B1 / | awk 'NR==2{print $2}')"; printf '"diskFreeBytes":%s,' "$(df -B1 / | awk 'NR==2{print $4}')"; printf '"dnsOk":'; getent hosts example.com >/dev/null && printf true || printf false; printf ',"timeSkewSeconds":0,"tools":{"curl":"'; command -v curl >/dev/null && printf installed; printf '","tar":"'; command -v tar >/dev/null && printf installed; printf '"},"privilege":"'; sudo -n true >/dev/null 2>&1 && printf sudo || printf user; printf '"}'`;class qr{provider;transport;discoverer;constructor(e,t=new ul,r){this.provider=e;this.transport=t;this.discoverer=r}discover(e){return this.discoverer?.(e)??Promise.resolve([])}async test(e){try{let t=await this.transport.scan(e.endpoint,e.sshPort);return{reachable:!0,hostKeyAlgorithm:t.algorithm,hostKeyFingerprint:_A(t.key),latencyMs:0}}catch{return{reachable:!1,hostKeyAlgorithm:"unknown",hostKeyFingerprint:"",latencyMs:0}}}async validate(e){let t=await this.transport.exec(e,xA);if(t.code!==0)throw Error(`Fleet validation failed: ${t.stderr.trim()||t.code}`);try{return JSON.parse(t.stdout)}catch{throw Error("Fleet validation returned malformed facts.")}}async bootstrap(e,t){let r=await this.transport.exec(e,`sudo -n ts-cloud-agent bootstrap --version 1 --steps ${t.length}`);if(r.code!==0)throw Error(`Fleet bootstrap failed: ${r.stderr.trim()||r.code}`);return{version:"1"}}capabilities(){return{document:{supported:!0,reason:"fleet-capabilities/v1; sha256:driver-contract"},validate:{supported:!0},bootstrap:{supported:!0},heartbeat:{supported:!0},drain:{supported:!0},archive:{supported:!0},terminate:{supported:!1,reason:"Inventory removal never terminates provider infrastructure."}}}}function pl(e,t){return{"fleet.bootstrap":async(r)=>{let o=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},m=e.get(String(o.serverId??""));if(!m)throw Error("Queued fleet server was not found.");let h=t.find((A)=>A.provider===m.provider);if(!h)throw Error(`No ${m.provider} fleet driver is configured.`);let I=Array.isArray(o.steps)?o.steps.map(String):[];if(r.checkpoint("preflight","Rechecking pinned trust and healthy validation."),m.trustState!=="pinned"||!m.validation?.valid)throw Error("Fleet bootstrap requires pinned trust and a healthy validation report.");r.checkpoint("bootstrap","Applying the reviewed idempotent bootstrap plan.");let R=await h.bootstrap(m,I);return e.update(m.id,{bootstrapVersion:R.version,status:"ready"}),r.checkpoint("verify","Bootstrap completed; heartbeat can now establish freshness."),{serverId:m.id,bootstrapVersion:R.version,steps:I.length}}}}var li=(e)=>e==null?void 0:String(e),Ls=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},Zm=(e)=>({id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),resourceId:String(e.resource_id),name:String(e.name),provider:String(e.provider),providerId:li(e.provider_id),region:li(e.region),zone:li(e.zone),endpoint:String(e.endpoint),sshUser:String(e.ssh_user),sshPort:Number(e.ssh_port),credentialRef:String(e.credential_ref),hostKeyAlgorithm:li(e.host_key_algorithm),hostKeyFingerprint:li(e.host_key_fingerprint),pendingHostKey:li(e.pending_host_key),roles:Ls(e.roles,[]),labels:Ls(e.labels,{}),taints:Ls(e.taints,[]),capacity:Ls(e.capacity,{}),usage:Ls(e.usage,{}),capabilities:Ls(e.capabilities,{}),status:String(e.status),trustState:String(e.trust_state),validation:Ls(e.validation,void 0),bootstrapVersion:li(e.bootstrap_version),heartbeatAt:li(e.heartbeat_at),lastSeenAt:li(e.last_seen_at),archivedAt:li(e.archived_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class Qo{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}get(e){let t=this.control.database.query("SELECT * FROM fleet_servers WHERE id=?").get(e);return t?Zm(t):void 0}list(e,t=!1){return this.control.database.query("SELECT * FROM fleet_servers WHERE project_id=? ORDER BY name").all(e).map(Zm).filter((r)=>t||r.status!=="archived")}findProvider(e,t,r){let o=this.control.database.query("SELECT * FROM fleet_servers WHERE organization_id=? AND provider=? AND provider_id=? AND archived_at IS NULL").get(e,t,r);return o?Zm(o):void 0}create(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO fleet_servers (id,organization_id,project_id,resource_id,name,provider,provider_id,region,zone,endpoint,ssh_user,ssh_port,credential_ref,host_key_algorithm,host_key_fingerprint,pending_host_key,roles,labels,taints,capacity,usage,capabilities,status,trust_state,validation,bootstrap_version,heartbeat_at,last_seen_at,archived_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.resourceId,e.name,e.provider,e.providerId??null,e.region??null,e.zone??null,e.endpoint,e.sshUser,e.sshPort,e.credentialRef,e.hostKeyAlgorithm??null,e.hostKeyFingerprint??null,e.pendingHostKey??null,JSON.stringify(e.roles),JSON.stringify(e.labels),JSON.stringify(e.taints),JSON.stringify(e.capacity),JSON.stringify(e.usage),JSON.stringify(e.capabilities),e.status,e.trustState,JSON.stringify(e.validation??{}),e.bootstrapVersion??null,e.heartbeatAt??null,e.lastSeenAt??null,e.archivedAt??null,r,r]),this.get(t)}update(e,t){let r=this.get(e);if(!r)throw Error("Server was not found.");let o={...r,...t},m=this.now().toISOString();return this.control.database.run("UPDATE fleet_servers SET name=?,provider_id=?,region=?,zone=?,endpoint=?,ssh_user=?,ssh_port=?,credential_ref=?,host_key_algorithm=?,host_key_fingerprint=?,pending_host_key=?,roles=?,labels=?,taints=?,capacity=?,usage=?,capabilities=?,status=?,trust_state=?,validation=?,bootstrap_version=?,heartbeat_at=?,last_seen_at=?,archived_at=?,version=version+1,updated_at=? WHERE id=?",[o.name,o.providerId??null,o.region??null,o.zone??null,o.endpoint,o.sshUser,o.sshPort,o.credentialRef,o.hostKeyAlgorithm??null,o.hostKeyFingerprint??null,o.pendingHostKey??null,JSON.stringify(o.roles),JSON.stringify(o.labels),JSON.stringify(o.taints),JSON.stringify(o.capacity),JSON.stringify(o.usage),JSON.stringify(o.capabilities),o.status,o.trustState,JSON.stringify(o.validation??{}),o.bootstrapVersion??null,o.heartbeatAt??null,o.lastSeenAt??null,o.archivedAt??null,m,e]),this.get(e)}}var OA=/^(?:[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?|\[[0-9a-fA-F:]+\])$/;class Ho{store;drivers;now;queue;constructor(e,t,r,o=()=>new Date){this.store=e;this.drivers=t;this.now=o;this.queue=r??new c(e.control)}driver(e){let t=this.drivers.find((r)=>r.provider===e);if(!t)throw Error(`No ${e} fleet driver is configured.`);return t}enroll(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Server name is invalid.");if(!OA.test(e.endpoint)||e.sshUser==="root"||!e.credentialRef.startsWith("secret://"))throw Error("Enrollment requires a valid endpoint, non-root SSH user, and secret credential reference.");let t=e.providerId?this.store.findProvider(e.organizationId,e.provider,e.providerId):void 0;if(t)return this.store.update(t.id,{endpoint:e.endpoint,region:e.region,zone:e.zone});let r=this.store.control.createResource({projectId:e.projectId,kind:"server",slug:e.name,name:e.name,provider:e.provider,providerId:e.providerId}),o=this.driver(e.provider);return this.store.create({...e,resourceId:r.id,sshPort:e.sshPort??22,labels:e.labels??{},taints:[],capacity:{},usage:{},capabilities:o.capabilities(),status:"pending",trustState:"unverified"})}async test(e){let t=this.store.get(e);if(!t)throw Error("Server was not found.");let r=await this.driver(t.provider).test(t);if(!r.reachable)return this.store.update(e,{status:"unreachable"});if(t.hostKeyFingerprint&&t.hostKeyFingerprint!==r.hostKeyFingerprint)return this.store.update(e,{status:"degraded",trustState:"rotation_pending",pendingHostKey:r.hostKeyFingerprint});return this.store.update(e,{hostKeyAlgorithm:r.hostKeyAlgorithm,hostKeyFingerprint:r.hostKeyFingerprint,pendingHostKey:void 0,trustState:"pinned",status:"validating",lastSeenAt:this.now().toISOString()})}reviewHostKey(e,t){let r=this.store.get(e);if(!r||r.pendingHostKey!==t)throw Error("Pending host key does not match.");return this.store.update(e,{hostKeyFingerprint:t,pendingHostKey:void 0,trustState:"pinned",status:"validating"})}async validate(e){let t=this.store.get(e);if(!t||t.trustState!=="pinned")throw Error("Pin the SSH host key before validation.");let r=await this.driver(t.provider).validate(t),o=[];if(!["x64","arm64","x86_64","aarch64"].includes(r.arch??""))o.push({code:"arch.unsupported",severity:"error",message:"Unsupported architecture.",remediation:"Use x86_64 or arm64 Linux."});for(let I of["curl","tar"])if(!r.tools?.[I])o.push({code:`tool.${I}`,severity:"error",message:`${I} is missing.`,remediation:`Install ${I} before bootstrap.`});if(Math.abs(r.timeSkewSeconds??0)>60)o.push({code:"time.skew",severity:"error",message:"Clock skew exceeds 60 seconds.",remediation:"Enable NTP synchronization."});if(!r.dnsOk)o.push({code:"dns.failed",severity:"error",message:"DNS validation failed.",remediation:"Repair resolver configuration."});let m={valid:!o.some((I)=>I.severity==="error"),facts:r,findings:o,validatedAt:this.now().toISOString(),validatorVersion:"1"},h={cpu:r.cpuCores??0,memoryBytes:r.memoryBytes??0,diskBytes:r.diskBytes??0};return this.store.update(e,{validation:m,capacity:h,status:m.valid?"ready":"degraded"})}bootstrap(e,t=!1){let r=this.store.get(e);if(!r?.validation?.valid)throw Error("A healthy validation report is required.");let o=["install runtime dependencies","install ts-cloud agent","configure heartbeat","verify least-privilege access"];if(!t)return{preview:!0,steps:o};let m=this.queue.enqueue({projectId:r.projectId,resourceId:r.resourceId,kind:"fleet.bootstrap",input:{serverId:e,steps:o},lockKey:`server:${e}`,providerKey:r.provider}).operation;return{preview:!1,steps:o,operation:m}}heartbeat(e,t){let r=this.store.get(e);if(!r)throw Error("Server was not found.");let o=this.now().toISOString();return this.store.update(e,{usage:t.usage,capabilities:t.capabilities??r.capabilities,heartbeatAt:o,lastSeenAt:o,status:r.status==="draining"||r.status==="drained"?r.status:"ready"})}drain(e,t=!1){return this.store.update(e,{status:t?"drained":"draining"})}uncordon(e){return this.store.update(e,{status:"ready"})}archive(e,t){let r=this.store.get(e);if(!r||t!==r.name)throw Error("Exact server name confirmation is required.");return this.store.update(e,{status:"archived",archivedAt:this.now().toISOString()})}}import{createHash as Xm,createPublicKey as Av,verify as $A}from"node:crypto";function Vr(e){if(e===null||typeof e!=="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(Vr).join(",")}]`;return`{${Object.keys(e).sort().map((t)=>`${JSON.stringify(t)}:${Vr(e[t])}`).join(",")}}`}var hl=(e)=>Xm("sha256").update(Vr(e)).digest("hex"),xi=(e)=>Xm("sha256").update(Vr(e)).digest("hex"),fl=(e)=>Xm("sha256").update(Av(e).export({type:"spki",format:"der"})).digest("hex");function Al(e,t,r){try{return $A(null,Buffer.from(Vr(e)),Av(r),Buffer.from(t,"base64"))}catch{return!1}}var Ev=(e)=>e.replace(/^v/,"").split(/[.-]/).slice(0,3).map((t)=>Number(t)||0),Rv=(e,t)=>{let r=Ev(e),o=Ev(t);for(let m=0;m<3;m++){let h=(r[m]??0)-(o[m]??0);if(h)return h}return 0};function yl(e,t){let r=[];if(t.schemaVersion<e.minimumSchema)r.push(`schema ${t.schemaVersion} is below ${e.minimumSchema}`);if(t.schemaVersion>e.maximumSchema)r.push(`schema ${t.schemaVersion} is above ${e.maximumSchema}`);if(e.minimumVersion&&Rv(t.currentVersion,e.minimumVersion)<0)r.push(`platform ${t.currentVersion} is below ${e.minimumVersion}`);if(Rv(e.version,t.currentVersion)<=0)r.push(`version ${e.version} is not newer than ${t.currentVersion}`);if(!e.artifacts.some((o)=>o.platform===t.platform&&o.architecture===t.architecture))r.push(`no artifact for ${t.platform}/${t.architecture}`);return{compatible:r.length===0,reasons:r}}var Gi=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},dn=(e)=>e==null?void 0:String(e),NA=(e)=>({id:String(e.id),organizationId:String(e.organization_id),name:String(e.name),algorithm:"ed25519",publicKeyPem:String(e.public_key_pem),fingerprint:String(e.fingerprint),revokedAt:dn(e.revoked_at),createdAt:String(e.created_at)}),Cv=(e)=>({id:String(e.id),organizationId:String(e.organization_id),version:String(e.version),channel:String(e.channel),publishedAt:String(e.published_at),keyId:String(e.key_id),digest:String(e.digest),document:Gi(e.document,{}),signature:String(e.signature),verificationStatus:String(e.verification_status),compatibility:Gi(e.compatibility,{compatible:!1,reasons:[]}),createdAt:String(e.created_at)}),Pv=(e)=>({id:String(e.id),projectId:String(e.project_id),name:String(e.name),schedule:String(e.schedule),timezone:String(e.timezone),durationMinutes:Number(e.duration_minutes),allowedOperations:Gi(e.allowed_operations,[]),requireApproval:Number(e.require_approval)===1,enabled:Number(e.enabled)===1,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),_v=(e)=>({id:String(e.id),projectId:String(e.project_id),manifestId:String(e.manifest_id),windowId:dn(e.window_id),fromVersion:String(e.from_version),strategy:String(e.strategy),batchSize:Number(e.batch_size),healthGate:Gi(e.health_gate,{}),status:String(e.status),currentStage:dn(e.current_stage),backupId:dn(e.backup_id),approvedBy:dn(e.approved_by),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),eg=(e)=>({id:String(e.id),campaignId:String(e.campaign_id),serverId:dn(e.server_id),target:String(e.target),cohort:Number(e.cohort),previousVersion:String(e.previous_version),status:String(e.status),evidence:Gi(e.evidence,{}),error:dn(e.error),startedAt:dn(e.started_at),finishedAt:dn(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Tv=(e)=>({id:String(e.id),projectId:String(e.project_id),kind:String(e.kind),criteria:Gi(e.criteria,{}),candidates:Gi(e.candidates,[]),candidateDigest:String(e.candidate_digest),estimatedBytes:Number(e.estimated_bytes),status:String(e.status),confirmation:dn(e.confirmation),expiresAt:String(e.expires_at),result:Gi(e.result,{}),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),xv=(e)=>({id:String(e.id),projectId:String(e.project_id),backupPolicyId:dn(e.backup_policy_id),recoveryPointId:dn(e.recovery_point_id),topologyId:dn(e.topology_id),scenario:String(e.scenario),isolatedTarget:String(e.isolated_target),expectedRpoMinutes:Number(e.expected_rpo_minutes),expectedRtoMinutes:Number(e.expected_rto_minutes),status:String(e.status),operationId:dn(e.operation_id),evidence:Gi(e.evidence,{}),measuredRpoMinutes:e.measured_rpo_minutes==null?void 0:Number(e.measured_rpo_minutes),measuredRtoMinutes:e.measured_rto_minutes==null?void 0:Number(e.measured_rto_minutes),cleanupVerified:Number(e.cleanup_verified)===1,error:dn(e.error),startedAt:dn(e.started_at),finishedAt:dn(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class Ko{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}addTrustedKey(e){let t=this.id(),r=this.now().toISOString(),o=fl(e.publicKeyPem);return this.control.database.run("INSERT INTO platform_trusted_keys (id,organization_id,name,algorithm,public_key_pem,fingerprint,created_at) VALUES (?,?,?,'ed25519',?,?,?)",[t,e.organizationId,e.name,e.publicKeyPem,o,r]),this.key(t)}key(e){let t=this.control.database.query("SELECT * FROM platform_trusted_keys WHERE id=?").get(e);return t?NA(t):void 0}revokeKey(e){return this.control.database.run("UPDATE platform_trusted_keys SET revoked_at=? WHERE id=?",[this.now().toISOString(),e]),this.key(e)}importManifest(e){let t=this.key(e.keyId);if(!t||t.organizationId!==e.organizationId)throw Error("Trusted update key was not found.");if(t.revokedAt)throw Error("Update signing key is revoked.");if(!Al(e.document,e.signature,t.publicKeyPem))throw Error("Update manifest signature is invalid.");let r=yl(e.document,e.current),o=hl(e.document),m=this.id(),h=this.now().toISOString();return this.control.database.run("INSERT INTO platform_update_manifests (id,organization_id,version,channel,published_at,key_id,digest,document,signature,verification_status,compatibility,created_at) VALUES (?,?,?,?,?,?,?,?,?,'verified',?,?)",[m,e.organizationId,e.document.version,e.document.channel,new Date(e.document.publishedAt).toISOString(),e.keyId,o,JSON.stringify(e.document),e.signature,JSON.stringify(r),h]),this.manifest(m)}manifest(e){let t=this.control.database.query("SELECT * FROM platform_update_manifests WHERE id=?").get(e);return t?Cv(t):void 0}manifests(e){return this.control.database.query("SELECT * FROM platform_update_manifests WHERE organization_id=? ORDER BY published_at DESC").all(e).map(Cv)}createWindow(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO maintenance_windows (id,project_id,name,schedule,timezone,duration_minutes,allowed_operations,require_approval,enabled,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,1,?,?)",[t,e.projectId,e.name,e.schedule,e.timezone,e.durationMinutes,JSON.stringify(e.allowedOperations),e.requireApproval===!1?0:1,r,r]),this.window(t)}window(e){let t=this.control.database.query("SELECT * FROM maintenance_windows WHERE id=?").get(e);return t?Pv(t):void 0}windows(e){return this.control.database.query("SELECT * FROM maintenance_windows WHERE project_id=? ORDER BY name").all(e).map(Pv)}createCampaign(e){return this.control.transaction(()=>{let t=this.manifest(e.manifestId);if(!t?.compatibility.compatible||t.verificationStatus!=="verified")throw Error("A verified compatible update manifest is required.");if(!e.backupId)throw Error("A verified pre-upgrade backup is required.");let r=this.id(),o=this.now().toISOString();return this.control.database.run("INSERT INTO platform_upgrade_campaigns (id,project_id,manifest_id,window_id,from_version,strategy,batch_size,health_gate,status,backup_id,approved_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'planned',?,?,?,?)",[r,e.projectId,e.manifestId,e.windowId??null,e.fromVersion,e.strategy,e.batchSize,JSON.stringify(e.healthGate),e.backupId,e.approvedBy??null,o,o]),e.targets.forEach((m,h)=>this.control.database.run("INSERT INTO platform_upgrade_targets (id,campaign_id,server_id,target,cohort,previous_version,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,m.serverId??null,m.target,e.strategy==="canary"?h===0?0:1+Math.floor((h-1)/e.batchSize):Math.floor(h/e.batchSize),m.previousVersion,o,o])),this.campaign(r)})}campaign(e){let t=this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE id=?").get(e);return t?_v(t):void 0}campaigns(e){return this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE project_id=? ORDER BY created_at DESC").all(e).map(_v)}targets(e){return this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE campaign_id=? ORDER BY cohort,target").all(e).map(eg)}updateCampaign(e,t){let r=this.campaign(e);if(!r)throw Error("Upgrade campaign was not found.");let o={...r,...t};return this.control.database.run("UPDATE platform_upgrade_campaigns SET status=?,current_stage=?,updated_at=? WHERE id=?",[o.status,o.currentStage??null,this.now().toISOString(),e]),this.campaign(e)}updateTarget(e,t){let r=this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(e);if(!r)throw Error("Upgrade target was not found.");let o={...eg(r),...t};return this.control.database.run("UPDATE platform_upgrade_targets SET status=?,evidence=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[o.status,JSON.stringify(o.evidence),o.error??null,o.startedAt??null,o.finishedAt??null,this.now().toISOString(),e]),eg(this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(e))}createCleanup(e){let t=[...e.candidates].sort((I,R)=>I.id.localeCompare(R.id)),r=xi(t),o=this.id(),m=this.now().toISOString(),h=new Date(this.now().getTime()+(e.ttlMinutes??60)*60000).toISOString();return this.control.database.run("INSERT INTO cleanup_plans (id,project_id,kind,criteria,candidates,candidate_digest,estimated_bytes,status,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'preview',?,?,?)",[o,e.projectId,e.kind,JSON.stringify(e.criteria),JSON.stringify(t),r,t.reduce((I,R)=>I+R.bytes,0),h,m,m]),this.cleanup(o)}cleanup(e){let t=this.control.database.query("SELECT * FROM cleanup_plans WHERE id=?").get(e);return t?Tv(t):void 0}cleanups(e){return this.control.database.query("SELECT * FROM cleanup_plans WHERE project_id=? ORDER BY created_at DESC").all(e).map(Tv)}updateCleanup(e,t){let r=this.cleanup(e);if(!r)throw Error("Cleanup plan was not found.");let o={...r,...t};return this.control.database.run("UPDATE cleanup_plans SET status=?,confirmation=?,result=?,updated_at=? WHERE id=?",[o.status,o.confirmation??null,JSON.stringify(o.result),this.now().toISOString(),e]),this.cleanup(e)}createDrill(e){if(!/^isolated:\/\//.test(e.isolatedTarget))throw Error("DR drills require an isolated target.");let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO disaster_recovery_drills (id,project_id,backup_policy_id,recovery_point_id,topology_id,scenario,isolated_target,expected_rpo_minutes,expected_rto_minutes,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'planned',?,?)",[t,e.projectId,e.backupPolicyId??null,e.recoveryPointId??null,e.topologyId??null,e.scenario,e.isolatedTarget,e.expectedRpoMinutes,e.expectedRtoMinutes,r,r]),this.drill(t)}drill(e){let t=this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE id=?").get(e);return t?xv(t):void 0}drills(e){return this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE project_id=? ORDER BY created_at DESC").all(e).map(xv)}updateDrill(e,t){let r=this.drill(e);if(!r)throw Error("DR drill was not found.");let o={...r,...t};return this.control.database.run("UPDATE disaster_recovery_drills SET status=?,operation_id=?,evidence=?,measured_rpo_minutes=?,measured_rto_minutes=?,cleanup_verified=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[o.status,o.operationId??null,JSON.stringify(o.evidence),o.measuredRpoMinutes??null,o.measuredRtoMinutes??null,o.cleanupVerified?1:0,o.error??null,o.startedAt??null,o.finishedAt??null,this.now().toISOString(),e]),this.drill(e)}}function gm(e,t=new Date){if(!e.enabled)return!1;let r=new Date(e.schedule);if(!Number.isNaN(r.getTime()))return t>=r&&t.getTime()<=r.getTime()+e.durationMinutes*60000;let o=/^(\d{2}):(\d{2})$/.exec(e.schedule);if(!o)return!1;let m=new Intl.DateTimeFormat("en-US",{timeZone:e.timezone,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).formatToParts(t),h=Number(m.find((R)=>R.type==="hour")?.value)*60+Number(m.find((R)=>R.type==="minute")?.value),I=Number(o[1])*60+Number(o[2]);return h>=I&&h<I+e.durationMinutes}class Wo{store;now;queue;constructor(e,t,r=()=>new Date){this.store=e;this.now=r;this.queue=t??new c(e.control)}enqueueCampaign(e,t={}){let r=this.store.campaign(e);if(!r)throw Error("Upgrade campaign was not found.");let o=r.windowId?this.store.window(r.windowId):void 0;if(o&&!o.allowedOperations.includes("platform.upgrade"))throw Error("Maintenance window does not permit platform upgrades.");if(o&&!t.overrideWindow&&!gm(o,this.now()))throw Error("Upgrade is outside its maintenance window.");if(o?.requireApproval&&!t.approvedBy&&!r.approvedBy)throw Error("Maintenance approval is required.");let m=this.queue.enqueue({projectId:r.projectId,actorId:t.approvedBy,kind:"maintenance.upgrade",input:{campaignId:e},lockKey:"platform-upgrade",providerKey:"platform",timeoutSeconds:7200,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return{campaign:this.store.updateCampaign(e,{status:"queued"}),operation:m}}async previewCleanup(e,t){let r=t.find((o)=>o.kind===e.kind);if(!r)throw Error(`No ${e.kind} cleanup driver is configured.`);return this.store.createCleanup({...e,candidates:await r.discover(e.criteria)})}enqueueCleanup(e,t){let r=this.store.cleanup(e);if(!r||r.status!=="preview")throw Error("A current cleanup preview is required.");if(new Date(r.expiresAt)<=this.now())throw Error("Cleanup preview expired; generate it again.");let o=`DELETE ${r.candidates.length} ${r.kind}`;if(t!==o)throw Error(`Exact confirmation ${o} is required.`);let m=this.queue.enqueue({projectId:r.projectId,kind:"maintenance.cleanup",input:{planId:e},lockKey:`cleanup:${r.kind}`,providerKey:"cleanup",timeoutSeconds:3600,cancellationMode:"cooperative"}).operation;return{plan:this.store.updateCleanup(e,{status:"approved",confirmation:t}),operation:m}}enqueueDrill(e){let t=this.store.drill(e);if(!t||t.status!=="planned")throw Error("A planned DR drill is required.");let r=this.queue.enqueue({projectId:t.projectId,kind:"maintenance.drill",input:{drillId:e},lockKey:`drill:${t.scenario}:${t.id}`,providerKey:"recovery",timeoutSeconds:7200,cancellationMode:"cooperative"}).operation;return{drill:this.store.updateDrill(e,{status:"queued",operationId:r.id}),operation:r}}}var tg=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{};function Il(e){return{"maintenance.upgrade":async(m)=>{let h=e.store.campaign(String(tg(m.operation.input).campaignId??""));if(!h||!e.platform)throw Error("Upgrade campaign or platform maintenance driver is unavailable.");let I=e.store.manifest(h.manifestId);if(!I?.compatibility.compatible||I.verificationStatus!=="verified")throw Error("Update manifest is no longer verified and compatible.");let R=I.document.artifacts.find((E)=>E.platform===process.platform&&E.architecture===process.arch)??I.document.artifacts[0];if(!R)throw Error("No update artifact matches this platform.");e.store.updateCampaign(h.id,{status:"running",currentStage:"preflight"});let A=[];try{for(let E of[...new Set(e.store.targets(h.id).map((x)=>x.cohort))].sort((x,N)=>x-N)){e.store.updateCampaign(h.id,{currentStage:`cohort:${E}`});for(let x of e.store.targets(h.id).filter((N)=>N.cohort===E)){m.throwIfCancellationRequested(),m.checkpoint(`download:${x.target}`,"Downloading signed platform artifact."),e.store.updateTarget(x.id,{status:"downloading",startedAt:new Date().toISOString()});let N=await e.platform.download({target:x,artifact:R,signal:m.signal});if(N.sha256!==R.sha256)throw Error(`Artifact checksum mismatch for ${x.target}.`);m.checkpoint(`install:${x.target}`,"Installing verified artifact."),e.store.updateTarget(x.id,{status:"installing"}),await e.platform.install({target:x,path:N.path,version:I.version,signal:m.signal}),A.push(x);let F=await e.platform.health({target:x,gate:h.healthGate});if(!F.healthy)throw Error(`Upgrade health gate failed for ${x.target}.`);e.store.updateTarget(x.id,{status:"healthy",evidence:F.evidence,finishedAt:new Date().toISOString()})}}return e.store.updateCampaign(h.id,{status:"succeeded",currentStage:void 0}),{campaignId:h.id,version:I.version,targets:A.length}}catch(E){e.store.updateCampaign(h.id,{status:"rolling_back",currentStage:"rollback"});for(let x of A.reverse())e.store.updateTarget(x.id,{status:"rolling_back"}),await e.platform.rollback({target:x,version:x.previousVersion,signal:m.signal}),e.store.updateTarget(x.id,{status:"rolled_back",finishedAt:new Date().toISOString()});throw e.store.updateCampaign(h.id,{status:"rolled_back",currentStage:void 0}),E}},"maintenance.cleanup":async(m)=>{let h=e.store.cleanup(String(tg(m.operation.input).planId??""));if(!h||h.status!=="approved")throw Error("Approved cleanup plan was not found.");if(xi([...h.candidates].sort((x,N)=>x.id.localeCompare(N.id)))!==h.candidateDigest)throw Error("Cleanup candidate set changed after preview.");let I=e.cleanup?.find((x)=>x.kind===h.kind);if(!I)throw Error(`No ${h.kind} cleanup driver is configured.`);e.store.updateCleanup(h.id,{status:"running"});let R=[],A=[];for(let x of h.candidates){m.throwIfCancellationRequested();try{await I.remove(x),R.push(x.id)}catch(N){A.push({id:x.id,error:N instanceof Error?N.message:String(N)})}}let E=A.length?R.length?"partial":"failed":"succeeded";if(e.store.updateCleanup(h.id,{status:E,result:{removed:R,failed:A,reclaimedBytes:h.candidates.filter((x)=>R.includes(x.id)).reduce((x,N)=>x+N.bytes,0)}}),A.length)throw Error(`Cleanup failed for ${A.length} candidate(s).`);return{planId:h.id,removed:R.length,reclaimedBytes:h.estimatedBytes}},"maintenance.drill":async(m)=>{let h=e.store.drill(String(tg(m.operation.input).drillId??""));if(!h)throw Error("DR drill was not found.");let I=e.recovery?.find((N)=>N.scenario===h.scenario);if(!I)throw Error(`No ${h.scenario} recovery driver is configured.`);let R=new Date;e.store.updateDrill(h.id,{status:"restoring",startedAt:R.toISOString()});let A=h.isolatedTarget,E={},x={};try{m.checkpoint("restore","Restoring into isolated drill target.");let N=await I.restore({drill:h,signal:m.signal});if(!N.target.startsWith("isolated://"))throw Error("Recovery driver attempted a non-isolated target.");A=N.target,E=N.evidence;let F=(R.getTime()-new Date(N.recoveryPointAt).getTime())/60000;e.store.updateDrill(h.id,{status:"verifying",measuredRpoMinutes:F,evidence:{restore:E}}),m.checkpoint("verify","Running recovery health checks without production traffic.");let z=await I.verify({drill:h,target:A});x=z.evidence;let H=(Date.now()-R.getTime())/60000;if(!z.healthy||F>h.expectedRpoMinutes||H>h.expectedRtoMinutes)throw Error("DR drill failed its health, RPO, or RTO objective.");e.store.updateDrill(h.id,{measuredRpoMinutes:F,measuredRtoMinutes:H,evidence:{restore:E,verify:x}})}catch(N){throw e.store.updateDrill(h.id,{status:"failed",error:N instanceof Error?N.message:String(N),evidence:{restore:E,verify:x}}),N}finally{e.store.updateDrill(h.id,{status:"cleaning"});try{await I.cleanup({drill:h,target:A});let N=e.store.drill(h.id);e.store.updateDrill(h.id,{status:N.error?"failed":"passed",cleanupVerified:!0,finishedAt:new Date().toISOString()})}catch(N){e.store.updateDrill(h.id,{status:"cleanup_required",cleanupVerified:!1,error:N instanceof Error?N.message:String(N),finishedAt:new Date().toISOString()})}}return{drillId:h.id,status:e.store.drill(h.id).status}}}}class mm{transport;constructor(e){this.transport=e}download(e){return this.transport.download({target:e.target.target,url:e.artifact.url,signal:e.signal})}install(e){return this.transport.install({target:e.target.target,path:e.path,version:e.version,signal:e.signal})}health(e){return this.transport.health({target:e.target.target,gate:e.gate})}rollback(e){return this.transport.rollback({target:e.target.target,version:e.version,signal:e.signal})}}var Dv={releases:{select:"SELECT id,created_at,0 bytes FROM releases WHERE project_id=? AND pinned=0 AND status IN ('failed','rolled_back','superseded') AND created_at<?",remove:"DELETE FROM releases WHERE id=?"},artifacts:{select:"SELECT a.id,a.created_at,a.size bytes FROM release_artifacts a WHERE a.organization_id=? AND NOT EXISTS(SELECT 1 FROM releases r WHERE r.artifact_id=a.id) AND a.created_at<?",remove:"DELETE FROM release_artifacts WHERE id=?"},operations:{select:"SELECT id,created_at,0 bytes FROM operations WHERE project_id=? AND state IN ('succeeded','failed','cancelled','timed_out') AND updated_at<?",remove:"DELETE FROM operations WHERE id=?"},logs:{select:"SELECT l.id,l.created_at,length(l.message) bytes FROM operation_logs l JOIN operations o ON o.id=l.operation_id WHERE o.project_id=? AND o.state IN ('succeeded','failed','cancelled','timed_out') AND l.created_at<?",remove:"DELETE FROM operation_logs WHERE id=?"},previews:{select:"SELECT id,created_at,0 bytes FROM preview_instances WHERE project_id=? AND status IN ('destroyed','failed') AND updated_at<?",remove:"DELETE FROM preview_instances WHERE id=?"},snapshots:{select:"SELECT id,created_at,size_bytes bytes FROM recovery_points WHERE project_id=? AND pinned=0 AND held=0 AND status IN ('failed','deleted') AND created_at<?",remove:"DELETE FROM recovery_points WHERE id=?"},orphaned_resources:{select:"SELECT id,created_at,COALESCE(capacity_bytes,0) bytes FROM persistent_volumes WHERE project_id=? AND status='orphaned' AND orphaned_at<?",remove:"UPDATE persistent_volumes SET status='deleted',deleted_at=datetime('now'),updated_at=datetime('now') WHERE id=? AND status='orphaned'"}};class Jo{kind;control;projectId;organizationId;constructor(e,t,r,o){this.kind=e;this.control=t;this.projectId=r;this.organizationId=o}async discover(e){let t=Math.max(1,Math.min(3650,Number(e.olderThanDays??30))),r=new Date(Date.now()-t*86400000).toISOString(),o=Dv[this.kind],m=this.kind==="artifacts"?this.organizationId:this.projectId;return this.control.database.query(o.select).all(m,r).map((I)=>({id:String(I.id),kind:this.kind,label:`${this.kind}:${String(I.id)}`,bytes:Number(I.bytes??0),metadata:{createdAt:String(I.created_at)}}))}async remove(e){if(this.control.database.run(Dv[this.kind].remove,[e.id]).changes!==1)throw Error(`${e.label} changed or is no longer removable.`)}}class hm{scenario;transport;constructor(e,t){this.scenario=e;this.transport=t}restore(e){return this.transport.restore({scenario:this.scenario,...e})}verify(e){return this.transport.verify({scenario:this.scenario,...e})}cleanup(e){return this.transport.cleanup({scenario:this.scenario,...e})}}var Gn=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},_n=(e)=>e==null?void 0:String(e),gl=()=>({cpu:0,memoryBytes:0,diskBytes:0,gpu:0}),zt=(e={})=>({...gl(),...e});function Ov(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),name:String(e.name),purpose:String(e.purpose),backend:String(e.backend),region:_n(e.region),architecture:_n(e.architecture),labels:Gn(e.labels,{}),requiredServerLabels:Gn(e.required_server_labels,{}),toleratedTaints:Gn(e.tolerated_taints,[]),capacity:zt(Gn(e.capacity,{})),reserved:Gn(e.reserved,{}),maxWorkloads:Number(e.max_workloads),costWeight:Number(e.cost_weight),spreadKey:_n(e.spread_key),concurrency:Number(e.concurrency),ephemeralWorkspaces:Number(e.ephemeral_workspaces)===1,allowProductionSecrets:Number(e.allow_production_secrets)===1,status:String(e.status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function $v(e){return{id:String(e.id),projectId:String(e.project_id),environmentId:_n(e.environment_id),resourceId:String(e.resource_id),releaseId:_n(e.release_id),poolId:String(e.pool_id),serverId:_n(e.server_id),purpose:String(e.purpose),requirements:Gn(e.requirements,{}),decision:Gn(e.decision,{}),stateful:Number(e.stateful)===1,autoReschedule:Number(e.auto_reschedule)===1,status:String(e.status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function jA(e){return{id:String(e.id),projectId:String(e.project_id),resourceId:_n(e.resource_id),poolId:String(e.pool_id),placementId:_n(e.placement_id),operationId:_n(e.operation_id),sourceSha:String(e.source_sha),buildSpec:Gn(e.build_spec,{}),credentialPolicy:Gn(e.credential_policy,{productionSecrets:!1,shortLivedTokenExpiresAt:""}),workspace:_n(e.workspace),cacheKey:_n(e.cache_key),artifactUri:_n(e.artifact_uri),artifactDigest:_n(e.artifact_digest),status:String(e.status),cleanupAt:_n(e.cleanup_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class Go{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}createPool(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO capacity_pools (id,organization_id,project_id,name,purpose,backend,region,architecture,labels,required_server_labels,tolerated_taints,capacity,reserved,max_workloads,cost_weight,spread_key,concurrency,ephemeral_workspaces,allow_production_secrets,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.name,e.purpose,e.backend,e.region??null,e.architecture??null,JSON.stringify(e.labels),JSON.stringify(e.requiredServerLabels),JSON.stringify(e.toleratedTaints),JSON.stringify(zt(e.capacity)),"{}",e.maxWorkloads,e.costWeight,e.spreadKey??null,e.concurrency,e.ephemeralWorkspaces?1:0,e.allowProductionSecrets?1:0,e.status,r,r]),this.getPool(t)}getPool(e){let t=this.control.database.query("SELECT * FROM capacity_pools WHERE id=?").get(e);return t?Ov(t):void 0}listPools(e){return this.control.database.query("SELECT * FROM capacity_pools WHERE project_id=? ORDER BY name").all(e).map(Ov)}updatePool(e,t){let r=this.getPool(e);if(!r)throw Error("Capacity pool was not found.");let o={...r,...t},m=this.now().toISOString();return this.control.database.run("UPDATE capacity_pools SET status=?,reserved=?,capacity=?,concurrency=?,version=version+1,updated_at=? WHERE id=?",[o.status,JSON.stringify(o.reserved),JSON.stringify(o.capacity),o.concurrency,m,e]),this.getPool(e)}addMember(e,t,r={}){let o=this.now().toISOString();this.control.database.run("INSERT INTO capacity_pool_members (pool_id,server_id,capacity_override,status,created_at,updated_at) VALUES (?,?,?,'active',?,?) ON CONFLICT(pool_id,server_id) DO UPDATE SET capacity_override=excluded.capacity_override,status='active',updated_at=excluded.updated_at",[e,t,JSON.stringify(r),o,o])}members(e){return this.control.database.query("SELECT * FROM capacity_pool_members WHERE pool_id=? ORDER BY server_id").all(e).map((t)=>({serverId:String(t.server_id),status:String(t.status),capacityOverride:Gn(t.capacity_override,{})}))}memberStatus(e,t,r){this.control.database.run("UPDATE capacity_pool_members SET status=?,updated_at=? WHERE pool_id=? AND server_id=?",[r,this.now().toISOString(),e,t])}listPlacements(e,t){let r=this.control.database.query("SELECT * FROM workload_placements WHERE project_id=? ORDER BY created_at,id").all(e).map($v);return t?.length?r.filter((o)=>t.includes(o.status)):r}getPlacement(e){let t=this.control.database.query("SELECT * FROM workload_placements WHERE id=?").get(e);return t?$v(t):void 0}activeUsage(e,t){let r=this.control.database.query("SELECT l.resources,l.server_id FROM capacity_leases l WHERE l.pool_id=? AND l.state='active' AND l.expires_at>?").all(e,this.now().toISOString()),o=t?r.filter((m)=>String(m.server_id)===t):r;return{resources:o.reduce((m,h)=>{let I=zt(Gn(h.resources,{}));for(let R of Object.keys(m))m[R]+=I[R];return m},gl()),count:o.length}}expireLeases(){return this.control.database.run("UPDATE capacity_leases SET state='expired',updated_at=? WHERE state='active' AND expires_at<=?",[this.now().toISOString(),this.now().toISOString()]).changes}reserve(e){return this.control.transaction(()=>{this.expireLeases();let t=this.id(),r=this.id(),o=this.now().toISOString(),m=new Date(this.now().getTime()+(e.requirements.leaseSeconds??300)*1000).toISOString();return this.control.database.run("INSERT INTO workload_placements (id,project_id,environment_id,resource_id,release_id,pool_id,server_id,purpose,requirements,decision,stateful,auto_reschedule,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,'reserved',?,?)",[t,e.projectId,e.environmentId??null,e.resourceId,e.releaseId??null,e.decision.poolId,e.decision.serverId??null,e.requirements.purpose,JSON.stringify(e.requirements),JSON.stringify(e.decision),e.requirements.stateful?1:0,e.requirements.autoReschedule&&!e.requirements.stateful?1:0,o,o]),this.control.database.run("INSERT INTO capacity_leases (id,placement_id,pool_id,server_id,resources,state,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,'active',?,?,?)",[r,t,e.decision.poolId,e.decision.serverId??null,JSON.stringify(zt(e.requirements.resources)),m,o,o]),this.getPlacement(t)})}transitionPlacement(e,t){if(!this.getPlacement(e))throw Error("Placement was not found.");let o=this.now().toISOString();if(this.control.database.run("UPDATE workload_placements SET status=?,version=version+1,updated_at=? WHERE id=?",[t,o,e]),["released","failed","blocked"].includes(t))this.control.database.run("UPDATE capacity_leases SET state='released',updated_at=? WHERE placement_id=? AND state='active'",[o,e]);return this.getPlacement(e)}createBuild(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO remote_builds (id,project_id,resource_id,pool_id,placement_id,operation_id,source_sha,build_spec,credential_policy,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'queued',?,?)",[t,e.projectId,e.resourceId??null,e.poolId,e.placementId??null,e.operationId??null,e.sourceSha,JSON.stringify(e.buildSpec),JSON.stringify({productionSecrets:!1,shortLivedTokenExpiresAt:e.tokenExpiresAt}),r,r]),this.getBuild(t)}getBuild(e){let t=this.control.database.query("SELECT * FROM remote_builds WHERE id=?").get(e);return t?jA(t):void 0}updateBuild(e,t){let r=this.getBuild(e);if(!r)throw Error("Remote build was not found.");let o={...r,...t},m=this.now().toISOString();return this.control.database.run("UPDATE remote_builds SET operation_id=?,workspace=?,cache_key=?,artifact_uri=?,artifact_digest=?,status=?,cleanup_at=?,updated_at=? WHERE id=?",[o.operationId??null,o.workspace??null,o.cacheKey??null,o.artifactUri??null,o.artifactDigest??null,o.status,o.cleanupAt??null,m,e]),this.getBuild(e)}}var fu=["cpu","memoryBytes","diskBytes","gpu"],Nv=(e,t={})=>Object.entries(t).every(([r,o])=>e[r]===o),MA=(e,t,r)=>Object.fromEntries(fu.map((o)=>[o,Math.max(0,e[o]-t[o]-(r[o]??0))])),BA=(e,t)=>fu.every((r)=>e[r]>=(t[r]??0)),LA=(e,t)=>fu.reduce((r,o)=>r+(t[o]??0)/(e[o]||1),0);class qo{store;fleet;constructor(e,t){this.store=e;this.fleet=t}poolCandidates(e,t,r){let o=[];for(let m of this.store.listPools(e)){if(m.id===r)continue;let h=[];if(m.status!=="active")h.push(`pool is ${m.status}`);if(m.purpose!==t.purpose)h.push(`purpose is ${m.purpose}`);if(t.region&&m.region!==t.region)h.push(`region is ${m.region??"unset"}`);if(t.architecture&&m.architecture!==t.architecture)h.push(`architecture is ${m.architecture??"unset"}`);if(!Nv(m.labels,t.labels))h.push("pool labels do not match");if(m.backend==="server"){let I=this.store.members(m.id);if(!I.length)o.push(this.decision(m,void 0,t,[...h,"pool has no servers"]));for(let R of I){let A=this.fleet.get(R.serverId),E=[...h];if(!A)E.push("server is missing");else this.serverReasons(m,A,R.status,t,E);o.push(this.decision(m,A,t,E,R.capacityOverride))}}else o.push(this.decision(m,void 0,t,h))}return o.sort((m,h)=>Number(h.eligible)-Number(m.eligible)||m.score.cost-h.score.cost||m.score.spread-h.score.spread||m.score.fit-h.score.fit||m.poolName.localeCompare(h.poolName)||(m.serverId??"").localeCompare(h.serverId??""))}serverReasons(e,t,r,o,m){if(r!=="active")m.push(`member is ${r}`);if(t.status!=="ready")m.push(`server is ${t.status}`);if(!t.roles.includes(o.purpose==="build"?"build":o.purpose))m.push(`server lacks ${o.purpose} role`);if(!Nv(t.labels,e.requiredServerLabels))m.push("server labels do not match pool selector");for(let h of t.taints)if(!e.toleratedTaints.includes(h))m.push(`taint ${h} is not tolerated`)}decision(e,t,r,o,m={}){let h=zt({...t?.capacity,...m}),I=t?Object.fromEntries(fu.map((E)=>[E,Math.min(e.capacity[E],h[E])])):e.capacity,R=this.store.activeUsage(e.id,t?.id),A=MA(I,R.resources,e.reserved);if(R.count>=e.maxWorkloads)o.push("workload limit reached");if(r.purpose==="build"&&R.count>=e.concurrency)o.push("build concurrency reached");if(!BA(A,r.resources))o.push("insufficient capacity");return{poolId:e.id,poolName:e.name,serverId:t?.id,eligible:o.length===0,reasons:o,available:A,score:{fit:LA(A,r.resources),spread:R.count,cost:e.costWeight}}}explain(e,t){return this.poolCandidates(e,t)}place(e){return this.store.control.transaction(()=>{let t=this.poolCandidates(e.projectId,e.requirements).find((r)=>r.eligible);if(!t)throw Error(`No eligible capacity: ${this.explain(e.projectId,e.requirements).flatMap((r)=>r.reasons).join("; ")}`);return this.store.reserve({...e,decision:t})})}activate(e){return this.store.transitionPlacement(e,"active")}release(e){return this.store.transitionPlacement(e,"released")}drainPool(e){let t=this.store.updatePool(e,{status:"draining"}),r=[],o=[];for(let m of this.store.listPlacements(t.projectId,["reserved","active"]).filter((h)=>h.poolId===e)){if(m.stateful){o.push(this.store.transitionPlacement(m.id,"blocked"));continue}this.store.transitionPlacement(m.id,"moving");let h=this.place({projectId:m.projectId,environmentId:m.environmentId,resourceId:m.resourceId,releaseId:m.releaseId,requirements:m.requirements});r.push(this.activate(h.id)),this.store.transitionPlacement(m.id,"released")}return{pool:t,moved:r,blocked:o}}drainServer(e,t){this.store.memberStatus(e,t,"draining");let r=this.store.getPool(e);if(!r)throw Error("Capacity pool was not found.");let o=[],m=[];for(let h of this.store.listPlacements(r.projectId,["reserved","active"]).filter((I)=>I.poolId===e&&I.serverId===t)){if(h.stateful){m.push(this.store.transitionPlacement(h.id,"blocked"));continue}this.store.transitionPlacement(h.id,"moving");let I=this.poolCandidates(h.projectId,h.requirements).find((A)=>A.eligible);if(!I){m.push(this.store.transitionPlacement(h.id,"blocked"));continue}let R=this.store.reserve({projectId:h.projectId,environmentId:h.environmentId,resourceId:h.resourceId,releaseId:h.releaseId,requirements:h.requirements,decision:I});o.push(this.activate(R.id)),this.store.transitionPlacement(h.id,"released")}return{moved:o,blocked:m}}reconcileFailure(e){let t=this.fleet.get(e);if(!t)throw Error("Server was not found.");let r=[],o=[];for(let m of this.store.listPlacements(t.projectId,["active"]).filter((h)=>h.serverId===e)){if(m.stateful||!m.autoReschedule){o.push(this.store.transitionPlacement(m.id,"blocked"));continue}this.store.transitionPlacement(m.id,"failed");let h=this.place({projectId:m.projectId,environmentId:m.environmentId,resourceId:m.resourceId,releaseId:m.releaseId,requirements:m.requirements});r.push(this.activate(h.id))}return{rescheduled:r,blocked:o}}}class um{store;placement;now;queue;constructor(e,t,r,o=()=>new Date){this.store=e;this.placement=t;this.now=o;this.queue=r??new c(e.control)}enqueue(e){if(!/^[a-f0-9]{7,64}$/i.test(e.sourceSha))throw Error("A pinned source commit SHA is required.");let t={purpose:"build",resources:{cpu:1,memoryBytes:1073741824,diskBytes:5368709120},leaseSeconds:3600,...e.requirements},r=this.placement.place({projectId:e.projectId,resourceId:e.resourceId,requirements:t}),o=new Date(this.now().getTime()+900000).toISOString(),m=this.store.createBuild({projectId:e.projectId,resourceId:e.resourceId,poolId:r.poolId,placementId:r.id,sourceSha:e.sourceSha,buildSpec:e.buildSpec,tokenExpiresAt:o}),h=this.queue.enqueue({projectId:e.projectId,resourceId:e.resourceId,kind:"build.remote",input:{buildId:m.id},lockKey:`build:${m.id}`,providerKey:`pool:${r.poolId}`,buildSlot:!0,timeoutSeconds:3600,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return m=this.store.updateBuild(m.id,{operationId:h.id}),m}cancel(e){let t=this.store.getBuild(e);if(!t)throw Error("Remote build was not found.");if(t.operationId)this.queue.requestCancellation(t.operationId);return this.store.updateBuild(e,{status:"cancelled"})}}var FA=/^sha256:[a-f0-9]{64}$/,zA=/^(?:s3|https|oci):\/\//;function yA(e,t){return{"build.remote":async(r)=>{let o=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},m=e.getBuild(String(o.buildId??""));if(!m)throw Error("Queued remote build was not found.");let h=e.getPool(m.poolId);if(!h||h.purpose!=="build"||h.status!=="active")throw Error("The selected build pool is unavailable.");if(!h.ephemeralWorkspaces)throw Error("Remote builds require an ephemeral workspace pool.");if(m.credentialPolicy.productionSecrets||h.allowProductionSecrets)throw Error("Production secrets are forbidden in remote build workers.");if(new Date(m.credentialPolicy.shortLivedTokenExpiresAt)<=new Date)throw Error("The short-lived build credential has expired.");let I=t.find((A)=>A.backend===h.backend);if(!I)throw Error(`No ${h.backend} remote build driver is configured.`);let R=`build://${h.id}/${m.id}`;e.updateBuild(m.id,{status:"running",workspace:R}),r.checkpoint("checkout",`Preparing isolated workspace for ${m.sourceSha}.`);try{r.throwIfCancellationRequested(),r.checkpoint("build","Executing resource-limited build.");let A=await I.run({build:e.getBuild(m.id),pool:h,signal:r.signal,log:(E)=>r.log(E,{stream:"stdout"})});if(r.throwIfCancellationRequested(),!FA.test(A.artifactDigest)||!zA.test(A.artifactUri))throw Error("Builder returned an unverified artifact reference.");return e.updateBuild(m.id,{status:"uploading",cacheKey:A.cacheKey,artifactUri:A.artifactUri,artifactDigest:A.artifactDigest}),r.checkpoint("verify","Verified content-addressed artifact upload."),await I.cleanup({build:e.getBuild(m.id),pool:h}),e.updateBuild(m.id,{status:"succeeded",workspace:void 0,cleanupAt:new Date().toISOString()}),{buildId:m.id,artifactUri:A.artifactUri,artifactDigest:A.artifactDigest,cacheKey:A.cacheKey??null}}catch(A){try{await I.cleanup({build:e.getBuild(m.id),pool:h}),e.updateBuild(m.id,{status:r.cancellationRequested()?"cancelled":"failed",workspace:void 0,cleanupAt:new Date().toISOString()})}catch{e.updateBuild(m.id,{status:"cleanup_required"})}throw A}}}}class Bi{backend;transport;handles=new Map;constructor(e,t){this.backend=e;this.transport=t}async run({build:e,pool:t,signal:r,log:o}){let m=await this.transport.provision({backend:this.backend,pool:t,build:e,tokenExpiresAt:e.credentialPolicy.shortLivedTokenExpiresAt});return this.handles.set(e.id,m.handle),o(`${this.backend} builder provisioned`),await this.transport.execute({handle:m.handle,spec:e.buildSpec,sourceSha:e.sourceSha,signal:r,onLog:o}),this.transport.publish({handle:m.handle,sourceSha:e.sourceSha})}async cleanup({build:e}){let t=this.handles.get(e.id);if(!t)return;await this.transport.destroy({handle:t}),this.handles.delete(e.id)}}var IA=(e)=>new Bi("server",e),SA=(e)=>new Bi("ecs",e),CA=(e)=>new Bi("asg",e);var Qi=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},Fn=(e)=>e==null?void 0:String(e),jv=(e)=>({id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:Fn(e.environment_id),name:String(e.name),hostname:String(e.hostname),homeRegion:String(e.home_region),regions:Qi(e.regions,[]),trafficPolicy:String(e.traffic_policy),dataPolicy:Qi(e.data_policy,{replicate:[],maxLagSeconds:60,retainOnDestroy:!0}),status:String(e.status),activeRegion:String(e.active_region),revision:Fn(e.revision),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),rg=(e)=>({id:String(e.id),topologyId:String(e.topology_id),region:String(e.region),role:String(e.role),provider:String(e.provider),stackId:Fn(e.stack_id),stackRevision:Fn(e.stack_revision),status:String(e.status),health:Qi(e.health,{}),lastHealthyAt:Fn(e.last_healthy_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),ng=(e)=>({id:String(e.id),topologyId:String(e.topology_id),kind:String(e.kind),sourceRegion:String(e.source_region),targetRegion:String(e.target_region),config:Qi(e.config,{}),status:String(e.status),checkpoint:Fn(e.checkpoint),lagSeconds:e.lag_seconds==null?void 0:Number(e.lag_seconds),lastVerifiedAt:Fn(e.last_verified_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),ig=(e)=>({id:String(e.id),topologyId:String(e.topology_id),hostname:String(e.hostname),dnsProvider:String(e.dns_provider),cdnEnabled:Number(e.cdn_enabled)===1,wafEnabled:Number(e.waf_enabled)===1,weights:Qi(e.weights,{}),desiredWeights:Qi(e.desired_weights,{}),status:String(e.status),providerState:Qi(e.provider_state,{}),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Mv=(e)=>({id:String(e.id),topologyId:String(e.topology_id),operationId:Fn(e.operation_id),kind:String(e.kind),requestedRegion:Fn(e.requested_region),revision:Fn(e.revision),plan:Qi(e.plan,[]),currentStep:Fn(e.current_step),completedSteps:Qi(e.completed_steps,[]),status:String(e.status),error:Fn(e.error),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class Vo{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}create(e){return this.control.transaction(()=>{if(e.regions.length<2||new Set(e.regions.map((h)=>h.region)).size!==e.regions.length||e.regions.filter((h)=>h.role==="primary").length!==1)throw Error("A topology requires unique regions and exactly one primary.");let t=e.regions.find((h)=>h.role==="primary"),r=this.id(),o=this.now().toISOString();this.control.database.run("INSERT INTO regional_topologies (id,organization_id,project_id,environment_id,name,hostname,home_region,regions,traffic_policy,data_policy,status,active_region,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,'draft',?,?,?)",[r,e.organizationId,e.projectId,e.environmentId??null,e.name,e.hostname,t.region,JSON.stringify(e.regions),e.trafficPolicy,JSON.stringify(e.dataPolicy),t.region,o,o]);for(let h of e.regions)this.control.database.run("INSERT INTO regional_targets (id,topology_id,region,role,provider,status,created_at,updated_at) VALUES (?,?,?,?,?,'pending',?,?)",[this.id(),r,h.region,h.role,h.provider,o,o]);for(let h of e.dataPolicy.replicate)for(let I of e.regions)for(let R of e.regions.filter((A)=>A.region!==I.region))this.control.database.run("INSERT INTO regional_replication_channels (id,topology_id,kind,source_region,target_region,config,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,h,I.region,R.region,"{}",o,o]);let m=Object.fromEntries(e.regions.map((h)=>[h.region,h.region===t.region?100:0]));return this.control.database.run("INSERT INTO regional_traffic_routes (id,topology_id,hostname,dns_provider,cdn_enabled,waf_enabled,weights,desired_weights,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'pending',?,?)",[this.id(),r,e.hostname,e.dnsProvider??"route53",e.cdnEnabled?1:0,e.wafEnabled?1:0,JSON.stringify(m),JSON.stringify(m),o,o]),this.get(r)})}get(e){let t=this.control.database.query("SELECT * FROM regional_topologies WHERE id=?").get(e);return t?jv(t):void 0}list(e){return this.control.database.query("SELECT * FROM regional_topologies WHERE project_id=? ORDER BY name").all(e).map(jv)}targets(e){return this.control.database.query("SELECT * FROM regional_targets WHERE topology_id=? ORDER BY role,region").all(e).map(rg)}channels(e){return this.control.database.query("SELECT * FROM regional_replication_channels WHERE topology_id=? ORDER BY kind,target_region").all(e).map(ng)}route(e){let t=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE topology_id=?").get(e);return t?ig(t):void 0}updateTopology(e,t){let r=this.get(e);if(!r)throw Error("Regional topology was not found.");let o={...r,...t},m=this.now().toISOString();return this.control.database.run("UPDATE regional_topologies SET status=?,active_region=?,revision=?,regions=?,version=version+1,updated_at=? WHERE id=?",[o.status,o.activeRegion,o.revision??null,JSON.stringify(o.regions),m,e]),this.get(e)}updateTarget(e,t){let r=this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(e);if(!r)throw Error("Regional target was not found.");let o=rg(r),m={...o,...t},h=this.now().toISOString();return this.control.database.run("UPDATE regional_targets SET role=?,stack_id=?,stack_revision=?,status=?,health=?,last_healthy_at=?,version=version+1,updated_at=? WHERE id=?",[m.role,m.stackId??null,m.stackRevision??null,m.status,JSON.stringify(m.health),m.lastHealthyAt??null,h,e]),rg(this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(e))}updateChannel(e,t){let r=this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(e);if(!r)throw Error("Replication channel was not found.");let o=ng(r),m={...o,...t},h=this.now().toISOString();return this.control.database.run("UPDATE regional_replication_channels SET status=?,checkpoint=?,lag_seconds=?,last_verified_at=?,version=version+1,updated_at=? WHERE id=?",[m.status,m.checkpoint??null,m.lagSeconds??null,m.lastVerifiedAt??null,h,e]),ng(this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(e))}updateRoute(e,t){let r=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(e);if(!r)throw Error("Traffic route was not found.");let o=ig(r),m={...o,...t},h=this.now().toISOString();return this.control.database.run("UPDATE regional_traffic_routes SET weights=?,desired_weights=?,status=?,provider_state=?,version=version+1,updated_at=? WHERE id=?",[JSON.stringify(m.weights),JSON.stringify(m.desiredWeights),m.status,JSON.stringify(m.providerState),h,e]),ig(this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(e))}createExecution(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO regional_executions (id,topology_id,operation_id,kind,requested_region,revision,plan,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'queued',?,?)",[t,e.topologyId,e.operationId??null,e.kind,e.requestedRegion??null,e.revision??null,JSON.stringify(e.plan),r,r]),this.execution(t)}execution(e){let t=this.control.database.query("SELECT * FROM regional_executions WHERE id=?").get(e);return t?Mv(t):void 0}executions(e){return this.control.database.query("SELECT * FROM regional_executions WHERE topology_id=? ORDER BY created_at DESC").all(e).map(Mv)}updateExecution(e,t){let r=this.execution(e);if(!r)throw Error("Regional execution was not found.");let o={...r,...t},m=this.now().toISOString();return this.control.database.run("UPDATE regional_executions SET operation_id=?,current_step=?,completed_steps=?,status=?,error=?,updated_at=? WHERE id=?",[o.operationId??null,o.currentStep??null,JSON.stringify(o.completedSteps),o.status,o.error??null,m,e]),this.execution(e)}}class jo{store;queue;constructor(e,t){this.store=e;this.queue=t??new c(e.control)}create(e){return this.store.create(e)}plan(e,t,r){if(!this.store.get(e))throw Error("Regional topology was not found.");let m=this.store.targets(e),h=this.store.channels(e);if(t==="rollout")return[...m.filter((I)=>I.role==="secondary").map((I)=>`apply:${I.region}`),...m.filter((I)=>I.role==="primary").map((I)=>`apply:${I.region}`),...h.map((I)=>`replicate:${I.kind}:${I.targetRegion}`),"traffic:activate"];if(t==="failover"||t==="failback")return[`health:${r}`,`replication:${r}`,`traffic:${r}`,`roles:${r}`];if(t==="destroy")return["traffic:drain",...m.filter((I)=>I.role==="secondary").map((I)=>`delete:${I.region}`),...m.filter((I)=>I.role==="primary").map((I)=>`delete:${I.region}`),"complete"];return["observe","repair"]}enqueue(e){let t=this.store.get(e.topologyId);if(!t)throw Error("Regional topology was not found.");if(["failover","failback"].includes(e.kind)&&(!e.targetRegion||!t.regions.some((h)=>h.region===e.targetRegion)))throw Error("A topology target region is required.");if(e.kind==="failover"&&e.targetRegion===t.activeRegion)throw Error("Target region is already active.");if((e.kind==="destroy"||e.deleteData)&&e.confirmation!==t.name)throw Error("Exact topology name confirmation is required.");if(e.deleteData&&t.dataPolicy.retainOnDestroy)throw Error("Topology policy requires regional data retention.");if(e.kind==="rollout"&&!/^[A-Za-z0-9._:@/-]{7,200}$/.test(e.revision??""))throw Error("An immutable revision is required.");let r=this.plan(t.id,e.kind,e.targetRegion),o=this.store.createExecution({topologyId:t.id,kind:e.kind,requestedRegion:e.targetRegion,revision:e.revision,plan:r}),m=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,kind:`region.${e.kind}`,input:{executionId:o.id,manifest:e.manifest??{},deleteData:e.deleteData===!0},lockKey:`regional-topology:${t.id}`,providerKey:"multi-region",timeoutSeconds:7200,cancellationMode:"provider_non_cancellable",resumePolicy:"requeue",maxAttempts:3}).operation;return this.store.updateExecution(o.id,{operationId:m.id}),{execution:this.store.execution(o.id),operation:m}}}var UA=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{};function ml(e,t){let r=(E)=>{let x=t.find((N)=>N.provider===E.provider);if(!x)throw Error(`No ${E.provider} regional driver is configured.`);return x},o=(E,x,N)=>{E.throwIfCancellationRequested(),E.checkpoint(N,N),e.updateExecution(x.id,{status:"running",currentStep:N,completedSteps:[...e.execution(x.id).completedSteps,N]})},m=async(E,x)=>{let N=e.route(E.id);if(!N)throw Error("Regional traffic route was not found.");let F=e.targets(E.id).find((H)=>H.region===E.activeRegion)??e.targets(E.id)[0];if(!F)throw Error("Regional traffic target was not found.");e.updateRoute(N.id,{status:"applying",desiredWeights:x});let z=await r(F).applyTraffic({route:e.route(E.id),topology:E,weights:x});e.updateRoute(N.id,{status:Object.values(x).every((H)=>H===0)?"drained":"in_sync",weights:x,providerState:z.providerState})},h=async(E,x,N,F)=>{e.updateTopology(N.id,{status:"provisioning"});let z=x.revision,H=F.manifest??{},K=e.targets(N.id).sort((oe,ye)=>Number(oe.role==="primary")-Number(ye.role==="primary"));for(let oe of K){o(E,x,`apply:${oe.region}`),e.updateTarget(oe.id,{status:"provisioning"});let ye=await r(oe).applyStack({target:oe,revision:z,manifest:H,signal:E.signal}),ne=await r(oe).health({target:e.updateTarget(oe.id,{stackId:ye.stackId,stackRevision:z})});if(!ne.healthy)throw Error(`Regional health gate failed in ${oe.region}.`);e.updateTarget(oe.id,{status:"ready",health:ne.evidence,lastHealthyAt:new Date().toISOString()})}for(let oe of e.channels(N.id)){o(E,x,`replicate:${oe.kind}:${oe.targetRegion}`),e.updateChannel(oe.id,{status:"configuring"});let ye=K.find((Ce)=>Ce.region===oe.sourceRegion),ne=await r(ye).configureReplication({channel:oe,topology:N}),fe=await r(ye).verifyReplication({channel:e.updateChannel(oe.id,{checkpoint:ne.checkpoint,lagSeconds:ne.lagSeconds}),topology:N});if(!fe.healthy||fe.lagSeconds>N.dataPolicy.maxLagSeconds)throw Error(`${oe.kind} replication to ${oe.targetRegion} exceeds the RPO.`);e.updateChannel(oe.id,{status:"in_sync",checkpoint:fe.checkpoint,lagSeconds:fe.lagSeconds,lastVerifiedAt:new Date().toISOString()})}o(E,x,"traffic:activate");let X=Object.fromEntries(N.regions.map((oe)=>[oe.region,oe.region===N.activeRegion?100:0]));return await m(N,X),e.updateTopology(N.id,{status:"ready",revision:z}),{revision:z,activeRegion:N.activeRegion}},I=async(E,x,N)=>{let F=x.requestedRegion,z=e.targets(N.id).find((X)=>X.region===F);if(!z)throw Error("Requested regional target was not found.");e.updateTopology(N.id,{status:x.kind==="failover"?"failing_over":"failing_back"}),o(E,x,`health:${F}`);let H=await r(z).health({target:z});if(!H.healthy)throw Error(`Target region ${F} is unhealthy.`);e.updateTarget(z.id,{status:"ready",health:H.evidence,lastHealthyAt:new Date().toISOString()}),o(E,x,`replication:${F}`);for(let X of e.channels(N.id).filter((oe)=>oe.targetRegion===F)){let oe=await r(z).verifyReplication({channel:X,topology:N});if(!oe.healthy||oe.lagSeconds>N.dataPolicy.maxLagSeconds)throw Error(`${X.kind} replication is outside the failover RPO.`);e.updateChannel(X.id,{status:"in_sync",checkpoint:oe.checkpoint,lagSeconds:oe.lagSeconds,lastVerifiedAt:new Date().toISOString()})}o(E,x,`traffic:${F}`),await m(N,Object.fromEntries(N.regions.map((X)=>[X.region,X.region===F?100:0]))),o(E,x,`roles:${F}`);let K=N.regions.map((X)=>({...X,role:X.region===F?"primary":"secondary"}));for(let X of e.targets(N.id))e.updateTarget(X.id,{role:X.region===F?"primary":"secondary"});return e.updateTopology(N.id,{status:x.kind==="failover"?"failed_over":"ready",activeRegion:F,regions:K}),{activeRegion:F}},R=async(E,x,N,F)=>{e.updateTopology(N.id,{status:"destroying"}),o(E,x,"traffic:drain"),await m(N,Object.fromEntries(N.regions.map((H)=>[H.region,0])));let z=F.deleteData!==!0;for(let H of e.targets(N.id).sort((K,X)=>Number(K.role==="primary")-Number(X.role==="primary")))o(E,x,`delete:${H.region}`),e.updateTarget(H.id,{status:"deleting"}),await r(H).deleteStack({target:H,retainData:z,signal:E.signal}),e.updateTarget(H.id,{status:"deleted"});return o(E,x,"complete"),e.updateTopology(N.id,{status:"destroyed"}),{destroyed:!0,dataRetained:z}},A=async(E)=>{let x=UA(E.operation.input),N=e.execution(String(x.executionId??""));if(!N)throw Error("Regional execution was not found.");let F=e.get(N.topologyId);if(!F)throw Error("Regional topology was not found.");try{let z;if(N.kind==="rollout")z=await h(E,N,F,x);else if(N.kind==="failover"||N.kind==="failback")z=await I(E,N,F);else if(N.kind==="destroy")z=await R(E,N,F,x);else throw Error("Regional reconciliation is not configured.");return e.updateExecution(N.id,{status:"succeeded",currentStep:void 0}),{executionId:N.id,...z}}catch(z){if(e.updateExecution(N.id,{status:E.cancellationRequested()?"cancelled":"failed",error:z instanceof Error?z.message:String(z)}),e.get(F.id)?.status!=="destroyed")e.updateTopology(F.id,{status:"failed"});throw z}};return{"region.rollout":A,"region.failover":A,"region.failback":A,"region.destroy":A,"region.reconcile":A}}class pm{transport;provider="aws";constructor(e){this.transport=e}async applyStack({target:e,revision:t,manifest:r}){return this.transport.applyCloudFormation({region:e.region,stackId:e.stackId,revision:t,manifest:r})}async deleteStack({target:e,retainData:t}){if(!e.stackId)return;await this.transport.deleteCloudFormation({region:e.region,stackId:e.stackId,retainData:t})}async health({target:e}){if(!e.stackId)return{healthy:!1,evidence:{reason:"stack is not provisioned"}};return this.transport.stackHealth({region:e.region,stackId:e.stackId})}async configureReplication({channel:e}){let t={sourceRegion:e.sourceRegion,targetRegion:e.targetRegion,config:e.config};if(e.kind==="s3")return this.transport.configureS3Replication(t);if(e.kind==="dynamodb")return this.transport.configureDynamoGlobalTable(t);return this.transport.replicateSecrets(t)}async verifyReplication({channel:e}){return this.transport.verifyReplication({kind:e.kind,sourceRegion:e.sourceRegion,targetRegion:e.targetRegion,checkpoint:e.checkpoint})}async applyTraffic({route:e,weights:t}){return this.transport.applyEdge({hostname:e.hostname,weights:t,route53:e.dnsProvider==="route53",cloudFront:e.cdnEnabled,waf:e.wafEnabled})}}class zo{provider;reason;constructor(e,t="Configure a regional provider transport before executing this operation."){this.provider=e;this.reason=t}fail(){throw Error(this.reason)}async applyStack(){return this.fail()}async deleteStack(){this.fail()}async health(){return this.fail()}async configureReplication(){return this.fail()}async verifyReplication(){return this.fail()}async applyTraffic(){return this.fail()}}function de(e,t,r){return[e,t,r].map((o)=>encodeURIComponent(o)).join(":")}function em(e){return Object.fromEntries(["start","stop","restart","redeploy","scale","logs","exec","inspect","files"].map((t)=>[t,{supported:!1,reason:e}]))}function pt(e,t,r=["exec","files"]){let o=em(t);for(let m of e)o[m]={supported:!0,requiresConfirmation:!["logs","inspect"].includes(m),requiresRecentAuth:r.includes(m)};return o}var qA=/(?:secret|password|passwd|token|api[_-]?key|private[_-]?key|credential|authorization|cookie)/i;function ve(e){let t=String(e??"").trim().toLowerCase();if(["active","running","ready","healthy","available","steady","active:running"].includes(t))return"running";if(["activating","pending","provisioning","starting","created","initializing"].includes(t))return"starting";if(["deactivating","stopping","draining","terminating"].includes(t))return"stopping";if(["inactive","stopped","complete","completed","exited","disabled"].includes(t))return"stopped";if(["degraded","unhealthy","warning"].includes(t))return"degraded";if(["failed","dead","error","crashed","oomkilled"].includes(t))return"failed";return"unknown"}function Te(e){if(Array.isArray(e))return e.map((r)=>Te(r));if(!e||typeof e!=="object")return e;let t={};for(let[r,o]of Object.entries(e))t[r]=qA.test(r)?"[REDACTED]":Te(o);return t}function gt(e,t=new Date){if(!e)return;let r=new Date(e).getTime();return Number.isFinite(r)?Math.max(0,Math.floor((t.getTime()-r)/1000)):void 0}function Zd(e){let t=Number(e);return Number.isFinite(t)&&t>=0?t:void 0}function VA(e){let t=String(e?.message??e);if(/(?:unauthorized|accessdenied|forbidden|credentials)/i.test(t))return"unauthorized";if(/(?:timeout|unreachable|econnrefused|enotfound|network)/i.test(t))return"unreachable";return"error"}async function el(e,t={},r={}){let o=t.now??new Date,m=Math.max(100,r.timeoutMs??1e4),h=Math.max(1,r.staleAfterSeconds??60),I=await Promise.all(e.map(async(A)=>{try{let E=await Promise.race([A.discover({...t,now:o}),new Promise((x,N)=>setTimeout(()=>N(Error(`Runtime source ${A.id} timed out after ${m}ms`)),m))]);return{workloads:E,source:{id:A.id,provider:A.provider,status:"fresh",discoveredAt:o.toISOString(),staleAfterSeconds:h,itemCount:E.length}}}catch(E){return{workloads:[],source:{id:A.id,provider:A.provider,status:VA(E),discoveredAt:o.toISOString(),staleAfterSeconds:h,itemCount:0,message:String(E?.message??E).slice(0,500)}}}})),R=I.map((A)=>A.source);return{generatedAt:o.toISOString(),workloads:I.flatMap((A)=>A.workloads).sort((A,E)=>A.name.localeCompare(E.name)||A.id.localeCompare(E.id)),sources:R,degraded:R.some((A)=>A.status!=="fresh")}}function Ma(e){return e?.split("/").at(-1)??e?.split(":").at(-1)??"unknown"}function tl(e,t,r,o="ecs:aws",m=[]){let h=r.now??new Date;return e.map((I)=>{let R=I.serviceName??Ma(I.serviceArn),A=t.filter((oe)=>!I.clusterArn||oe.clusterArn===I.clusterArn),E=A.some((oe)=>!!oe.group)?A.filter((oe)=>oe.group===`service:${R}`):A,x=I.status==="ACTIVE"?(I.runningCount??0)<(I.desiredCount??0)?"degraded":"running":ve(I.status),N=m.find((oe)=>oe.taskDefinitionArn===I.taskDefinition),F=Array.isArray(N?.containerDefinitions)?N.containerDefinitions:[],z=[...new Set(F.map((oe)=>oe.logConfiguration?.options?.["awslogs-group"]).filter((oe)=>typeof oe==="string"))],H=F.flatMap((oe)=>(oe.mountPoints??[]).map((ye)=>({source:ye.sourceVolume,target:ye.containerPath,type:"volume",readOnly:!!ye.readOnly}))),K=F.flatMap((oe)=>(oe.portMappings??[]).map((ye,ne)=>({id:`${oe.name??"container"}:${ne}`,name:oe.name,mode:N?.networkMode,ports:[{container:ye.containerPort,host:ye.hostPort,protocol:ye.protocol}]}))),X=r.project&&r.environment&&R.startsWith(`${r.project}-${r.environment}-`)?R.slice(`${r.project}-${r.environment}-`.length):R;return{id:de("ecs",o,I.serviceArn??R),provider:"ecs",kind:"service",name:R,status:x,rawStatus:I.status,health:x==="running"?"healthy":x==="failed"||x==="degraded"?"unhealthy":"unknown",desiredReplicas:I.desiredCount,runningReplicas:I.runningCount,image:F[0]?.image,runtime:I.launchType??"ECS",version:Ma(I.taskDefinition),ageSeconds:gt(I.deployments?.[0]?.createdAt,h),restartCount:0,tags:{},links:{project:r.project,environment:r.environment,service:X,release:Ma(I.taskDefinition),providerId:I.serviceArn},replicas:E.map((oe)=>{let ye=ve(oe.lastStatus);return{id:de("ecs",o,oe.taskArn??Ma(oe.taskArn)),name:Ma(oe.taskArn),status:ye,rawStatus:oe.lastStatus,createdAt:oe.createdAt,startedAt:oe.startedAt,stoppedAt:oe.stoppedAt,host:oe.containerInstanceArn,containers:(oe.containers??[]).map((ne)=>({id:ne.containerArn??ne.name??"container",name:ne.name??"container",image:F.find((fe)=>fe.name===ne.name)?.image,imageDigest:ne.imageDigest,status:ve(ne.lastStatus),rawStatus:ne.lastStatus,exitCode:ne.exitCode,reason:ne.reason,runtime:"ecs"}))}}),networks:K,mounts:H,capabilities:pt(["start","stop","restart","redeploy","scale","inspect",...z.length?["logs"]:[]],"This ECS runtime does not expose exec or file transfer; logs require an awslogs task-definition driver"),config:Te({clusterArn:I.clusterArn,taskDefinition:I.taskDefinition,launchType:I.launchType,pendingCount:I.pendingCount,deployments:I.deployments,logGroups:z,executionRoleArn:N?.executionRoleArn,taskRoleArn:N?.taskRoleArn,cpu:N?.cpu,memory:N?.memory}),discoveredAt:h.toISOString(),sourceId:o}})}function rl(e,t,r="lambda:aws"){let o=t.now??new Date;return e.map((m)=>{let h=m.FunctionName??Ma(m.FunctionArn),I=m.State==="Active"?"running":ve(m.State);return{id:de("lambda",r,m.FunctionArn??h),provider:"lambda",kind:"function",name:h,status:I,rawStatus:m.State,health:I==="running"?"healthy":I==="failed"?"unhealthy":"unknown",desiredReplicas:void 0,runningReplicas:void 0,image:void 0,runtime:m.Runtime,version:m.Version,architecture:m.Architectures?.join(", "),ageSeconds:gt(m.LastModified,o),restartCount:0,tags:{},links:{project:t.project,environment:t.environment,service:h,providerId:m.FunctionArn},resources:{memoryLimitBytes:m.MemorySize==null?void 0:m.MemorySize*1024*1024},replicas:[],networks:[],mounts:[],capabilities:pt(["logs","inspect"],"Lambda has no persistent process to start, stop, restart, exec, or browse files; deploy a release to replace code"),config:Te({handler:m.Handler,timeout:m.Timeout,codeSize:m.CodeSize,stateReason:m.StateReason,environmentKeys:Object.keys(m.Environment?.Variables??{})}),discoveredAt:o.toISOString(),sourceId:r}})}function tm(e){let t=e.trim();if(!t)return[];let r=JSON.parse(t);if(!Array.isArray(r))throw Error("Docker inspect output must be an array");return r.filter((o)=>o&&typeof o.Id==="string")}function WA(e){let t=Object.entries(e.NetworkSettings?.Ports??{}).flatMap(([r,o])=>{let[m,h]=r.split("/");return(o??[]).map((I)=>({container:Number(m)||void 0,host:Number(I.HostPort)||void 0,protocol:h,address:I.HostIp}))});return Object.entries(e.NetworkSettings?.Networks??{}).map(([r,o])=>({id:o.NetworkID||r,name:r,mode:e.HostConfig?.NetworkMode,addresses:[o.IPAddress,o.GlobalIPv6Address].filter(Boolean),ports:t}))}function HA(e){return(e.Mounts??[]).filter((t)=>!!t.Destination).map((t)=>({source:t.Source,target:t.Destination,type:t.Type,readOnly:t.RW===!1}))}function rm(e,t,r=t.server??"local"){let o=t.now??new Date;return e.map((m)=>{let h=m.State?.OOMKilled?"oomkilled":m.State?.Restarting?"starting":m.State?.Status,I=ve(h),R=(m.Name??m.Id.slice(0,12)).replace(/^\//,""),A=m.Config?.Labels??{},E=HA(m),x=WA(m),N={id:m.Id,name:R,image:m.Config?.Image,imageDigest:m.Image,runtime:"docker",status:I,rawStatus:h,exitCode:m.State?.ExitCode,reason:m.State?.Error,resources:{memoryLimitBytes:m.HostConfig?.Memory||void 0},networks:x,mounts:E};return{id:de("docker",r,m.Id),provider:"docker",kind:"container",name:R,status:I,rawStatus:h,health:I==="running"?"healthy":I==="failed"?"unhealthy":"unknown",desiredReplicas:1,runningReplicas:I==="running"?1:0,image:m.Config?.Image,runtime:"docker",ageSeconds:gt(m.State?.StartedAt,o),restartCount:m.RestartCount??0,tags:A,links:{project:t.project,environment:t.environment,server:t.server??r.replace(/^docker:/,""),service:A["com.docker.compose.service"]??A["ts-cloud.service"]??R,release:A["ts-cloud.release"],providerId:m.Id},resources:N.resources,replicas:[{id:de("docker",r,`${m.Id}:0`),name:R,status:I,rawStatus:h,startedAt:m.State?.StartedAt,stoppedAt:m.State?.FinishedAt,restartCount:m.RestartCount,containers:[N],resources:N.resources}],networks:x,mounts:E,capabilities:pt(["start","stop","restart","logs","exec","inspect","files"],"Use the owning Compose service for redeploy and scale"),config:Te({image:m.Config?.Image,labels:A,environmentKeys:(m.Config?.Env??[]).map((F)=>F.split("=",1)[0]),networkMode:m.HostConfig?.NetworkMode}),discoveredAt:o.toISOString(),sourceId:r}})}class To{inspect;id;provider="docker";constructor(e,t="docker:local"){this.inspect=e;this.id=t}async discover(e){return rm(tm(await this.inspect(e)),e,this.id)}}function nm(e){let t=[];for(let r of e.split(`
169
- `)){if(!r.startsWith("TSCLOUD_SYSTEMD\t"))continue;let[,o,m,h,I,R,A,E,x,N,F,z,H,K]=r.split("\t");if(!o||!/^[A-Za-z0-9_.@:-]+\.service$/.test(o))continue;t.push({unit:o,load:m,active:h,sub:I,description:R,enabled:A,pid:Number(E)||void 0,memoryBytes:Zd(x),restartCount:Number(N)||0,activeSince:F||void 0,fragmentPath:z||void 0,workingDirectory:H?.startsWith("/")?H:void 0,user:K||void 0})}return t}function im(e,t,r=t.server??"local"){let o=t.now??new Date;return e.map((m)=>{let h=ve(m.active==="active"?m.sub||m.active:m.active),I=m.unit.replace(/\.service$/,""),R=/^(.*?) (?:release [^ ]+|queue worker|daemon |scheduler)(?: |$)/.exec(m.description??"")?.[1]??(t.project&&I.startsWith(`${t.project}-`)?I.slice(t.project.length+1).split("@",1)[0]:void 0),A=I.includes("@")?I.slice(I.indexOf("@")+1):void 0,E=m.workingDirectory?[{target:m.workingDirectory,type:"working-directory"}]:[],x=["start","stop","restart","logs","exec","inspect",...E.length?["files"]:[]];return{id:de("systemd",r,m.unit),provider:"systemd",kind:"service",name:I,displayName:m.description||I,status:h,rawStatus:[m.load,m.active,m.sub].filter(Boolean).join("/"),health:h==="running"?"healthy":h==="failed"?"unhealthy":"unknown",desiredReplicas:1,runningReplicas:h==="running"?1:0,ageSeconds:gt(m.activeSince,o),restartCount:m.restartCount,tags:{enabled:m.enabled??"unknown"},links:{project:t.project,environment:t.environment,server:t.server??r.replace(/^systemd:/,""),service:R,release:A,providerId:m.unit},resources:{memoryBytes:m.memoryBytes},replicas:[{id:de("systemd",r,`${m.unit}:main`),name:"main",status:h,pid:m.pid,startedAt:m.activeSince,restartCount:m.restartCount,resources:{memoryBytes:m.memoryBytes}}],networks:[],mounts:E,capabilities:pt(x,E.length?"This systemd runtime does not support redeploy or replica scaling through the scoped explorer":"File transfer requires a provider-reported service working directory; redeploy and scaling are unavailable"),config:Te({fragmentPath:m.fragmentPath,workingDirectory:m.workingDirectory,user:m.user,environment:m.environment,enabled:m.enabled}),discoveredAt:o.toISOString(),sourceId:r}})}class wo{read;id;provider="systemd";constructor(e,t="systemd:local"){this.read=e;this.id=t}async discover(e){return im(nm(await this.read(e)),e,this.id)}}function KA(e,t){if(!e.success)throw Error(e.error||e.perInstance?.[0]?.error||`${t} discovery failed`);return e.perInstance?.[0]?.output??""}function JA(){return["set -uo pipefail",'command -v systemctl >/dev/null 2>&1 || { echo "systemctl is unavailable" >&2; exit 127; }',"systemctl list-units --type=service --all --plain --no-legend 2>/dev/null | awk '{print $1}' | while IFS= read -r unit; do",' [ -n "$unit" ] || continue',' clean() { printf "%s" "$1" | tr "\\t\\r\\n" " "; }',' load=$(systemctl show "$unit" -p LoadState --value 2>/dev/null || true)',' active=$(systemctl show "$unit" -p ActiveState --value 2>/dev/null || true)',' sub=$(systemctl show "$unit" -p SubState --value 2>/dev/null || true)',' description=$(systemctl show "$unit" -p Description --value 2>/dev/null || true)',' enabled=$(systemctl is-enabled "$unit" 2>/dev/null || true)',' pid=$(systemctl show "$unit" -p MainPID --value 2>/dev/null || true)',' memory=$(systemctl show "$unit" -p MemoryCurrent --value 2>/dev/null || true)',' restarts=$(systemctl show "$unit" -p NRestarts --value 2>/dev/null || true)',' since=$(systemctl show "$unit" -p ActiveEnterTimestamp --value 2>/dev/null || true)',' fragment=$(systemctl show "$unit" -p FragmentPath --value 2>/dev/null || true)',' working=$(systemctl show "$unit" -p WorkingDirectory --value 2>/dev/null || true)',' user=$(systemctl show "$unit" -p User --value 2>/dev/null || true)',' printf "TSCLOUD_SYSTEMD\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\n" "$(clean "$unit")" "$(clean "$load")" "$(clean "$active")" "$(clean "$sub")" "$(clean "$description")" "$(clean "$enabled")" "$(clean "$pid")" "$(clean "$memory")" "$(clean "$restarts")" "$(clean "$since")" "$(clean "$fragment")" "$(clean "$working")" "$(clean "$user")"',"done"]}function GA(){return["set -uo pipefail",'if ! command -v docker >/dev/null 2>&1; then echo "[]"; exit 0; fi',"ids=$(docker ps -aq)",'if [ -z "$ids" ]; then echo "[]"; else docker inspect $ids; fi']}function Bv(e,t,r,o,m){let h=`${e}:${r.id}`,I=async()=>KA(await t.runRemoteDeploy({targets:[r],commands:e==="systemd"?JA():GA(),timeoutSeconds:30,comment:`ts-cloud runtime discovery:${e}`,tags:{Project:o.project.slug,Environment:m,Role:"app"}}),h);return e==="systemd"?new wo(I,h):new To(I,h)}async function hu(e,t=100){let r=[],o;for(let m=0;m<t;m++){let h=await e(o);if(r.push(...h.items),!h.nextToken)return r;o=h.nextToken}throw Error(`Provider pagination exceeded ${t} pages`)}class nl{client;prefix;id="ecs:aws";provider="ecs";constructor(e,t){this.client=e;this.prefix=t}async discover(e){let t=await hu(async(h)=>{let I=await this.client.listClusters({nextToken:h,maxResults:100});return{items:I.clusterArns??[],nextToken:I.nextToken}}),r=[],o=[],m=[];for(let h of t){let I=(await hu(async(R)=>{let A=await this.client.listServices(h,{nextToken:R,maxResults:100});return{items:A.serviceArns??[],nextToken:A.nextToken}})).filter((R)=>R.split("/").at(-1)?.startsWith(this.prefix));for(let R=0;R<I.length;R+=10){let A=await this.client.describeServices({cluster:h,services:I.slice(R,R+10)});r.push(...A.services??[])}for(let R of r.filter((A)=>A.clusterArn===h||!A.clusterArn)){let A=await hu(async(E)=>{let x=await this.client.listTasks(h,R.serviceName,{nextToken:E,maxResults:100});return{items:x.taskArns??[],nextToken:x.nextToken}});for(let E=0;E<A.length;E+=100){let x=await this.client.describeTasks(h,A.slice(E,E+100));o.push(...x.tasks??[])}}}if(this.client.describeTaskDefinition)for(let h of[...new Set(r.map((I)=>I.taskDefinition).filter((I)=>!!I))]){let I=await this.client.describeTaskDefinition(h);if(I.taskDefinition)m.push(I.taskDefinition)}return tl(r,o,e,this.id,m)}}class il{client;prefix;id="lambda:aws";provider="lambda";constructor(e,t){this.client=e;this.prefix=t}async discover(e){let t=(await hu(async(r)=>{let o=await this.client.listFunctions({Marker:r,MaxItems:50});return{items:o.Functions??[],nextToken:o.NextMarker}})).filter((r)=>r.FunctionName?.startsWith(this.prefix));return rl(t,e,this.id)}}async function sm(e,t,r={}){let o=[],m=O(e),h=ce(e),I=e.aws?.profile,R=e.aws?.region??e.project.region??"us-east-1",A=`${e.project.slug}-${t}`;if(m!=="serverless"){let E=r.driver??k({config:e}),x=await E.findComputeTargets({slug:e.project.slug,environment:t,role:"app"});for(let N of x)o.push(Bv("systemd",E,N,e,t)),o.push(Bv("docker",E,N,e,t))}if(h==="aws")o.push(new nl(r.ecs??new Ke(R,I),A)),o.push(new il(r.lambda??new C(R,I),A));return o}async function te(e,t,r={}){let o={project:e.project.slug,environment:t};try{return await el(await sm(e,t,r),o)}catch(m){return{generatedAt:new Date().toISOString(),workloads:[],sources:[{id:"runtime:bootstrap",provider:ce(e)==="aws"?"ecs":"systemd",status:"error",discoveredAt:new Date().toISOString(),staleAfterSeconds:60,itemCount:0,message:String(m?.message??m).slice(0,500)}],degraded:!0}}}var Lv=65536,hc=49152,vu=/^[A-Za-z0-9_.@:-]+\.service$/,bu=/^[a-fA-F0-9]{12,128}$/,QA=["/boot","/dev","/etc","/proc","/root","/run","/sys","/var/run"];function Ba(e){let t=Buffer.from(e);return t.byteLength<=Lv?e:`${t.subarray(0,Lv-24).toString("utf8")}
170
- [output truncated]`}function yu(e){return{success:!1,instanceCount:0,perInstance:[],error:e instanceof Error?e.message:String(e)}}function zn(e){return`'${e.replaceAll("'",`'"'"'`)}'`}function YA(e,t){return Number.isFinite(e)?Math.min(1e4,Math.max(0,Math.floor(e))):t}function ZA(e){let t=e.config,r=typeof t.clusterArn==="string"?t.clusterArn:void 0,o=e.links.providerId||e.name;return r&&o?{cluster:r,service:o}:void 0}function XA(e,t){return e.find((r)=>r.id===t.links.server)??(e.length===1?e[0]:void 0)}function eC(e,t){if(e.provider==="systemd"){let r=e.links.providerId;if(!r||!vu.test(r)||!["start","stop","restart"].includes(t))return;return[`systemctl ${t} ${r}`,`systemctl is-active ${r} 2>/dev/null || true`]}if(e.provider==="docker"){let r=e.links.providerId;if(!r||!bu.test(r)||!["start","stop","restart"].includes(t))return;return[`docker ${t} ${r}`,`docker inspect --format '{{.State.Status}}' ${r}`]}return}function om(e,t){if(!t.startsWith("/")||t.includes("\x00"))return{ok:!1,error:"An absolute path is required."};let r=[];for(let R of t.split("/")){if(!R||R===".")continue;if(R===".."){if(!r.length)return{ok:!1,error:"Path traversal is not allowed."};r.pop()}else r.push(R)}let o=`/${r.join("/")}`;if(QA.some((R)=>o===R||o.startsWith(`${R}/`)))return{ok:!1,error:"Sensitive host paths are not available through runtime file access."};let m=e.links.project?.replace(/[^A-Za-z0-9_-]/g,""),h=e.links.service?.replace(/[^A-Za-z0-9_-]/g,"");if(![...m&&h?[`/var/www/${m}/${h}`,`/srv/${m}/${h}`]:[],...e.mounts.map((R)=>R.target).filter((R)=>R.startsWith("/"))].some((R)=>o===R||o.startsWith(`${R.replace(/\/$/,"")}/`)))return{ok:!1,error:"Path is outside this service’s owned roots."};return{ok:!0,path:o}}function tC(e,t){let r=e.links.project?.replace(/[^A-Za-z0-9_-]/g,""),o=e.links.service?.replace(/[^A-Za-z0-9_-]/g,"");return[...r&&o?[`/var/www/${r}/${o}`,`/srv/${r}/${o}`]:[],...e.mounts.map((m)=>m.target).filter((m)=>m.startsWith("/"))].sort((m,h)=>h.length-m.length).find((m)=>t===m||t.startsWith(`${m.replace(/\/$/,"")}/`))}var sl={process:["ps","-eo","pid,ppid,user,%cpu,%mem,etime,command","--sort=-%cpu"],sockets:["ss","-lntup"],filesystem:["df","-h"]};class le{config;environment;dependencies;region;profile;constructor(e,t,r={}){this.config=e;this.environment=t;this.dependencies=r;this.region=e.aws?.region??e.project.region??"us-east-1",this.profile=e.aws?.profile}async inventory(){return this.dependencies.inventory?.()??te(this.config,this.environment,{driver:this.dependencies.driver})}async workload(e){return(await this.inventory()).workloads.find((t)=>t.id===e)}async remote(e,t,r,o){let m=this.dependencies.driver??k({config:this.config}),h=await m.findComputeTargets({slug:this.config.project.slug,environment:this.environment,role:"app"}),I=XA(h,e);if(!I)throw Error("The workload server is no longer reachable in this scope.");return m.runRemoteDeploy({targets:[I],commands:t,timeoutSeconds:r,comment:o,tags:{Project:this.config.project.slug,Environment:this.environment,Role:"app"}})}async run(e){let t=await this.workload(e.workloadId),r={workloadId:e.workloadId,action:e.action};if(!t)return{...r,ok:!1,error:"Workload was not found in the current project and environment."};let o=t.capabilities[e.action];if(!o.supported)return{...r,ok:!1,error:o.reason??`${e.action} is unsupported for ${t.provider}.`};if(o.requiresConfirmation&&e.confirm!==t.name)return{...r,ok:!1,error:`Type "${t.name}" to ${e.action} this workload.`};if(o.requiresRecentAuth&&!e.recentAuth)return{...r,ok:!1,error:"Sign in again before using elevated runtime access."};if(e.action==="inspect")return{...r,ok:!0,workload:t};if(t.provider==="systemd"||t.provider==="docker"){let m=eC(t,e.action);if(!m)return{...r,ok:!1,error:`${e.action} is not implemented for ${t.provider}.`};let h=await this.remote(t,["set -uo pipefail",...m],60,`ts-cloud runtime:${e.action}`).catch(yu);return{...r,ok:h.success,command:m[0],stdout:Ba(h.perInstance?.[0]?.output??""),stderr:Ba(h.perInstance?.[0]?.error??h.error??""),error:h.success?void 0:h.error??"Runtime operation failed."}}if(t.provider==="ecs"){let m=ZA(t);if(!m)return{...r,ok:!1,error:"ECS cluster or service identity is unavailable."};let h=this.dependencies.ecs??new Ke(this.region,this.profile);if(e.action==="scale"){let I=YA(e.replicas,t.desiredReplicas??1);return await h.scaleService(m.cluster,m.service,I),{...r,ok:!0,command:`ecs scale ${t.name} ${I}`}}if(e.action==="start"||e.action==="stop"){let I=e.action==="stop"?0:Math.max(1,t.desiredReplicas??1);return await h.scaleService(m.cluster,m.service,I),{...r,ok:!0,command:`ecs scale ${t.name} ${I}`}}if(e.action==="restart"||e.action==="redeploy")return await h.forceNewDeployment(m.cluster,m.service),{...r,ok:!0,command:`ecs redeploy ${t.name}`}}return{...r,ok:!1,error:`${e.action} is not implemented for ${t.provider}.`}}async exec(e){let t={workloadId:e.workloadId,preset:e.preset},r=await this.workload(e.workloadId);if(!r)return{...t,ok:!1,error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_EXEC==="0")return{...t,ok:!1,error:"Runtime exec is disabled by TS_CLOUD_RUNTIME_EXEC."};if(!r.capabilities.exec.supported)return{...t,ok:!1,error:r.capabilities.exec.reason??"Exec is unsupported for this workload."};if(e.confirm!==r.name)return{...t,ok:!1,error:`Type "${r.name}" to open exec access.`};if(!e.recentAuth)return{...t,ok:!1,error:"Sign in again before using elevated runtime access."};let o=e.preset&&sl[e.preset];if(!o&&!e.command?.trim())return{...t,ok:!1,error:"Choose a diagnostic preset or provide a command."};if(e.command&&r.provider!=="docker")return{...t,ok:!1,error:"Free-form exec is restricted to isolated containers; use a diagnostic preset for system services."};let m=r.links.providerId??"",h;if(r.provider==="docker"&&bu.test(m)){let R=e.command?.trim()||o.map(zn).join(" ");h=`docker exec ${m} sh -lc ${zn(R)}`}else if(r.provider==="systemd"&&vu.test(m)&&e.preset)h=e.preset==="process"?`systemctl status ${m} --no-pager --full`:sl[e.preset].map(zn).join(" ");if(!h)return{...t,ok:!1,error:"Exec target identity is invalid or unsupported."};let I=await this.remote(r,["set -uo pipefail",h],60,"ts-cloud runtime:exec").catch(yu);return{...t,ok:I.success,command:h,stdout:Ba(I.perInstance?.[0]?.output??""),stderr:Ba(I.perInstance?.[0]?.error??I.error??""),error:I.success?void 0:I.error??"Exec command failed."}}async readFile(e){let t={workloadId:e.workloadId,path:e.path},r=await this.fileTarget(e);if("error"in r)return{...t,ok:!1,error:r.error};let{workload:o,path:m,root:h,providerId:I}=r,A=`sh -c ${zn('resolved=$(realpath -m "$1"); root=$(realpath -m "$3"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; test -f "$resolved"; size=$(wc -c < "$resolved"); printf "__TSCLOUD_SIZE__=%s\\n" "$size"; head -c "$2" "$resolved" | base64')} sh ${zn(m)} ${hc} ${zn(h)}`,E=o.provider==="docker"?`docker exec ${I} ${A}`:A,x=await this.remote(o,[E],30,"ts-cloud runtime:file-read").catch(yu);if(!x.success)return{...t,ok:!1,error:x.error??x.perInstance?.[0]?.error??"File read failed."};let N=x.perInstance?.[0]?.output??"",F=/__TSCLOUD_SIZE__=(\d+)\r?\n/.exec(N);if(!F)return{...t,ok:!1,error:"The remote file response was invalid."};let z=Number(F[1]),H=N.slice((F.index??0)+F[0].length).replace(/\s+/g,"");if(Buffer.from(H,"base64").byteLength>hc)return{...t,ok:!1,error:"The remote file exceeded the transfer limit."};return{...t,ok:!0,contentBase64:H,size:z,truncated:z>hc}}async writeFile(e){let t={workloadId:e.workloadId,path:e.path},r=await this.fileTarget(e);if("error"in r)return{...t,ok:!1,error:r.error};if(!/^[A-Za-z0-9+/]*={0,2}$/.test(e.contentBase64))return{...t,ok:!1,error:"File content must be valid base64."};let o=Buffer.from(e.contentBase64,"base64");if(o.toString("base64")!==e.contentBase64)return{...t,ok:!1,error:"File content must be canonical base64."};if(o.byteLength>hc)return{...t,ok:!1,error:`File uploads are limited to ${hc} bytes.`};let{workload:m,path:h,root:I,providerId:R}=r,E=`sh -c ${zn('resolved=$(realpath -m "$1"); root=$(realpath -m "$2"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; mkdir -p "$(dirname "$resolved")"; tmp="$resolved.ts-cloud-$$"; base64 -d > "$tmp"; chmod 600 "$tmp"; mv "$tmp" "$resolved"')} sh ${zn(h)} ${zn(I)}`,x=m.provider==="docker"?`printf %s ${zn(e.contentBase64)} | docker exec -i ${R} ${E}`:`printf %s ${zn(e.contentBase64)} | ${E}`,N=await this.remote(m,[x],30,"ts-cloud runtime:file-write").catch(yu);return{...t,ok:N.success,size:o.byteLength,truncated:!1,error:N.success?void 0:N.error??N.perInstance?.[0]?.error??"File write failed."}}async fileTarget(e){let t=await this.workload(e.workloadId);if(!t)return{error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_FILE_ACCESS==="0")return{error:"Runtime file access is disabled by TS_CLOUD_RUNTIME_FILE_ACCESS."};if(!t.capabilities.files.supported)return{error:t.capabilities.files.reason??"File access is unsupported for this workload."};if(e.confirm!==t.name)return{error:`Type "${t.name}" to access workload files.`};if(!e.recentAuth)return{error:"Sign in again before using elevated runtime access."};let r=om(t,e.path);if(!r.ok)return{error:r.error};let o=tC(t,r.path),m=t.links.providerId??"";if(!o||t.provider==="systemd"&&!vu.test(m)||t.provider==="docker"&&!bu.test(m))return{error:"File target identity is invalid or unsupported."};return{workload:t,path:r.path,root:o,providerId:m}}async logs(e,t={}){let r=await this.workload(e);if(!r)throw Error("Workload was not found in the current project and environment.");if(!r.capabilities.logs.supported)throw Error(r.capabilities.logs.reason??"Logs are unsupported for this workload.");let o=Math.min(1000,Math.max(1,Math.floor(t.limit??200)));if(r.provider==="lambda"||r.provider==="ecs"){let x=this.dependencies.logs??new pe(this.region,this.profile),N=r.config.logGroups,F=r.provider==="lambda"?`/aws/lambda/${r.name}`:Array.isArray(N)&&typeof N[0]==="string"?N[0]:void 0;if(!F)throw Error("The ECS task definition does not declare an awslogs group.");let z=await x.filterLogEvents({logGroupName:F,startTime:t.since?.getTime(),limit:o}),H=(z.events??[]).slice(0,o).map((K)=>({timestamp:K.timestamp==null?void 0:new Date(K.timestamp).toISOString(),message:Ba(String(K.message??""))}));return{workloadId:e,provider:r.provider,lines:H,nextCursor:z.nextToken,truncated:(z.events?.length??0)>=o}}let m=r.links.providerId??"",h=t.since&&Number.isFinite(t.since.getTime())?t.since:void 0,I=r.provider==="systemd"&&vu.test(m)?`journalctl -u ${m} --no-pager -n ${o} -o short-iso${h?` --since ${zn(h.toISOString())}`:""}`:r.provider==="docker"&&bu.test(m)?`docker logs --timestamps --tail ${o}${h?` --since ${Math.floor(h.getTime()/1000)}`:""} ${m} 2>&1`:void 0;if(!I)throw Error("Log target identity is invalid.");let R=await this.remote(r,[I],30,"ts-cloud runtime:logs");if(!R.success)throw Error(R.error??R.perInstance?.[0]?.error??"Log read failed.");let A=Ba(R.perInstance?.[0]?.output??""),E=A.split(`
169
+ `)){if(!r.startsWith("TSCLOUD_SYSTEMD\t"))continue;let[,o,m,h,I,R,A,E,x,N,F,z,H,K]=r.split("\t");if(!o||!/^[A-Za-z0-9_.@:-]+\.service$/.test(o))continue;t.push({unit:o,load:m,active:h,sub:I,description:R,enabled:A,pid:Number(E)||void 0,memoryBytes:Zd(x),restartCount:Number(N)||0,activeSince:F||void 0,fragmentPath:z||void 0,workingDirectory:H?.startsWith("/")?H:void 0,user:K||void 0})}return t}function im(e,t,r=t.server??"local"){let o=t.now??new Date;return e.map((m)=>{let h=ve(m.active==="active"?m.sub||m.active:m.active),I=m.unit.replace(/\.service$/,""),R=/^(.*?) (?:release [^ ]+|queue worker|daemon |scheduler)(?: |$)/.exec(m.description??"")?.[1]??(t.project&&I.startsWith(`${t.project}-`)?I.slice(t.project.length+1).split("@",1)[0]:void 0),A=I.includes("@")?I.slice(I.indexOf("@")+1):void 0,E=m.workingDirectory?[{target:m.workingDirectory,type:"working-directory"}]:[],x=["start","stop","restart","logs","exec","inspect",...E.length?["files"]:[]];return{id:de("systemd",r,m.unit),provider:"systemd",kind:"service",name:I,displayName:m.description||I,status:h,rawStatus:[m.load,m.active,m.sub].filter(Boolean).join("/"),health:h==="running"?"healthy":h==="failed"?"unhealthy":"unknown",desiredReplicas:1,runningReplicas:h==="running"?1:0,ageSeconds:gt(m.activeSince,o),restartCount:m.restartCount,tags:{enabled:m.enabled??"unknown"},links:{project:t.project,environment:t.environment,server:t.server??r.replace(/^systemd:/,""),service:R,release:A,providerId:m.unit},resources:{memoryBytes:m.memoryBytes},replicas:[{id:de("systemd",r,`${m.unit}:main`),name:"main",status:h,pid:m.pid,startedAt:m.activeSince,restartCount:m.restartCount,resources:{memoryBytes:m.memoryBytes}}],networks:[],mounts:E,capabilities:pt(x,E.length?"This systemd runtime does not support redeploy or replica scaling through the scoped explorer":"File transfer requires a provider-reported service working directory; redeploy and scaling are unavailable"),config:Te({fragmentPath:m.fragmentPath,workingDirectory:m.workingDirectory,user:m.user,environment:m.environment,enabled:m.enabled}),discoveredAt:o.toISOString(),sourceId:r}})}class wo{read;id;provider="systemd";constructor(e,t="systemd:local"){this.read=e;this.id=t}async discover(e){return im(nm(await this.read(e)),e,this.id)}}function KA(e,t){if(!e.success)throw Error(e.error||e.perInstance?.[0]?.error||`${t} discovery failed`);return e.perInstance?.[0]?.output??""}function JA(){return["set -uo pipefail",'command -v systemctl >/dev/null 2>&1 || { echo "systemctl is unavailable" >&2; exit 127; }',"systemctl list-units --type=service --all --plain --no-legend 2>/dev/null | awk '{print $1}' | while IFS= read -r unit; do",' [ -n "$unit" ] || continue',' clean() { printf "%s" "$1" | tr "\\t\\r\\n" " "; }',' load=$(systemctl show "$unit" -p LoadState --value 2>/dev/null || true)',' active=$(systemctl show "$unit" -p ActiveState --value 2>/dev/null || true)',' sub=$(systemctl show "$unit" -p SubState --value 2>/dev/null || true)',' description=$(systemctl show "$unit" -p Description --value 2>/dev/null || true)',' enabled=$(systemctl is-enabled "$unit" 2>/dev/null || true)',' pid=$(systemctl show "$unit" -p MainPID --value 2>/dev/null || true)',' memory=$(systemctl show "$unit" -p MemoryCurrent --value 2>/dev/null || true)',' restarts=$(systemctl show "$unit" -p NRestarts --value 2>/dev/null || true)',' since=$(systemctl show "$unit" -p ActiveEnterTimestamp --value 2>/dev/null || true)',' fragment=$(systemctl show "$unit" -p FragmentPath --value 2>/dev/null || true)',' working=$(systemctl show "$unit" -p WorkingDirectory --value 2>/dev/null || true)',' user=$(systemctl show "$unit" -p User --value 2>/dev/null || true)',' printf "TSCLOUD_SYSTEMD\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\n" "$(clean "$unit")" "$(clean "$load")" "$(clean "$active")" "$(clean "$sub")" "$(clean "$description")" "$(clean "$enabled")" "$(clean "$pid")" "$(clean "$memory")" "$(clean "$restarts")" "$(clean "$since")" "$(clean "$fragment")" "$(clean "$working")" "$(clean "$user")"',"done"]}function GA(){return["set -uo pipefail",'if ! command -v docker >/dev/null 2>&1; then echo "[]"; exit 0; fi',"ids=$(docker ps -aq)",'if [ -z "$ids" ]; then echo "[]"; else docker inspect $ids; fi']}function Bv(e,t,r,o,m){let h=`${e}:${r.id}`,I=async()=>KA(await t.runRemoteDeploy({targets:[r],commands:e==="systemd"?JA():GA(),timeoutSeconds:30,comment:`ts-cloud runtime discovery:${e}`,tags:{Project:o.project.slug,Environment:m,Role:"app"}}),h);return e==="systemd"?new wo(I,h):new To(I,h)}async function hu(e,t=100){let r=[],o;for(let m=0;m<t;m++){let h=await e(o);if(r.push(...h.items),!h.nextToken)return r;o=h.nextToken}throw Error(`Provider pagination exceeded ${t} pages`)}class nl{client;prefix;id="ecs:aws";provider="ecs";constructor(e,t){this.client=e;this.prefix=t}async discover(e){let t=await hu(async(h)=>{let I=await this.client.listClusters({nextToken:h,maxResults:100});return{items:I.clusterArns??[],nextToken:I.nextToken}}),r=[],o=[],m=[];for(let h of t){let I=(await hu(async(R)=>{let A=await this.client.listServices(h,{nextToken:R,maxResults:100});return{items:A.serviceArns??[],nextToken:A.nextToken}})).filter((R)=>R.split("/").at(-1)?.startsWith(this.prefix));for(let R=0;R<I.length;R+=10){let A=await this.client.describeServices({cluster:h,services:I.slice(R,R+10)});r.push(...A.services??[])}for(let R of r.filter((A)=>A.clusterArn===h||!A.clusterArn)){let A=await hu(async(E)=>{let x=await this.client.listTasks(h,R.serviceName,{nextToken:E,maxResults:100});return{items:x.taskArns??[],nextToken:x.nextToken}});for(let E=0;E<A.length;E+=100){let x=await this.client.describeTasks(h,A.slice(E,E+100));o.push(...x.tasks??[])}}}if(this.client.describeTaskDefinition)for(let h of[...new Set(r.map((I)=>I.taskDefinition).filter((I)=>!!I))]){let I=await this.client.describeTaskDefinition(h);if(I.taskDefinition)m.push(I.taskDefinition)}return tl(r,o,e,this.id,m)}}class il{client;prefix;id="lambda:aws";provider="lambda";constructor(e,t){this.client=e;this.prefix=t}async discover(e){let t=(await hu(async(r)=>{let o=await this.client.listFunctions({Marker:r,MaxItems:50});return{items:o.Functions??[],nextToken:o.NextMarker}})).filter((r)=>r.FunctionName?.startsWith(this.prefix));return rl(t,e,this.id)}}async function sm(e,t,r={}){let o=[],m=O(e),h=ce(e),I=e.aws?.profile,R=e.aws?.region??e.project.region??"us-east-1",A=`${e.project.slug}-${t}`;if(m!=="serverless"){let E=r.driver??k({config:e}),x=await E.findComputeTargets({slug:e.project.slug,environment:t,role:"app"});for(let N of x)o.push(Bv("systemd",E,N,e,t)),o.push(Bv("docker",E,N,e,t))}if(h==="aws")o.push(new nl(r.ecs??new We(R,I),A)),o.push(new il(r.lambda??new C(R,I),A));return o}async function te(e,t,r={}){let o={project:e.project.slug,environment:t};try{return await el(await sm(e,t,r),o)}catch(m){return{generatedAt:new Date().toISOString(),workloads:[],sources:[{id:"runtime:bootstrap",provider:ce(e)==="aws"?"ecs":"systemd",status:"error",discoveredAt:new Date().toISOString(),staleAfterSeconds:60,itemCount:0,message:String(m?.message??m).slice(0,500)}],degraded:!0}}}var Lv=65536,hc=49152,vu=/^[A-Za-z0-9_.@:-]+\.service$/,bu=/^[a-fA-F0-9]{12,128}$/,QA=["/boot","/dev","/etc","/proc","/root","/run","/sys","/var/run"];function Ba(e){let t=Buffer.from(e);return t.byteLength<=Lv?e:`${t.subarray(0,Lv-24).toString("utf8")}
170
+ [output truncated]`}function yu(e){return{success:!1,instanceCount:0,perInstance:[],error:e instanceof Error?e.message:String(e)}}function zn(e){return`'${e.replaceAll("'",`'"'"'`)}'`}function YA(e,t){return Number.isFinite(e)?Math.min(1e4,Math.max(0,Math.floor(e))):t}function ZA(e){let t=e.config,r=typeof t.clusterArn==="string"?t.clusterArn:void 0,o=e.links.providerId||e.name;return r&&o?{cluster:r,service:o}:void 0}function XA(e,t){return e.find((r)=>r.id===t.links.server)??(e.length===1?e[0]:void 0)}function eC(e,t){if(e.provider==="systemd"){let r=e.links.providerId;if(!r||!vu.test(r)||!["start","stop","restart"].includes(t))return;return[`systemctl ${t} ${r}`,`systemctl is-active ${r} 2>/dev/null || true`]}if(e.provider==="docker"){let r=e.links.providerId;if(!r||!bu.test(r)||!["start","stop","restart"].includes(t))return;return[`docker ${t} ${r}`,`docker inspect --format '{{.State.Status}}' ${r}`]}return}function om(e,t){if(!t.startsWith("/")||t.includes("\x00"))return{ok:!1,error:"An absolute path is required."};let r=[];for(let R of t.split("/")){if(!R||R===".")continue;if(R===".."){if(!r.length)return{ok:!1,error:"Path traversal is not allowed."};r.pop()}else r.push(R)}let o=`/${r.join("/")}`;if(QA.some((R)=>o===R||o.startsWith(`${R}/`)))return{ok:!1,error:"Sensitive host paths are not available through runtime file access."};let m=e.links.project?.replace(/[^A-Za-z0-9_-]/g,""),h=e.links.service?.replace(/[^A-Za-z0-9_-]/g,"");if(![...m&&h?[`/var/www/${m}/${h}`,`/srv/${m}/${h}`]:[],...e.mounts.map((R)=>R.target).filter((R)=>R.startsWith("/"))].some((R)=>o===R||o.startsWith(`${R.replace(/\/$/,"")}/`)))return{ok:!1,error:"Path is outside this service’s owned roots."};return{ok:!0,path:o}}function tC(e,t){let r=e.links.project?.replace(/[^A-Za-z0-9_-]/g,""),o=e.links.service?.replace(/[^A-Za-z0-9_-]/g,"");return[...r&&o?[`/var/www/${r}/${o}`,`/srv/${r}/${o}`]:[],...e.mounts.map((m)=>m.target).filter((m)=>m.startsWith("/"))].sort((m,h)=>h.length-m.length).find((m)=>t===m||t.startsWith(`${m.replace(/\/$/,"")}/`))}var sl={process:["ps","-eo","pid,ppid,user,%cpu,%mem,etime,command","--sort=-%cpu"],sockets:["ss","-lntup"],filesystem:["df","-h"]};class le{config;environment;dependencies;region;profile;constructor(e,t,r={}){this.config=e;this.environment=t;this.dependencies=r;this.region=e.aws?.region??e.project.region??"us-east-1",this.profile=e.aws?.profile}async inventory(){return this.dependencies.inventory?.()??te(this.config,this.environment,{driver:this.dependencies.driver})}async workload(e){return(await this.inventory()).workloads.find((t)=>t.id===e)}async remote(e,t,r,o){let m=this.dependencies.driver??k({config:this.config}),h=await m.findComputeTargets({slug:this.config.project.slug,environment:this.environment,role:"app"}),I=XA(h,e);if(!I)throw Error("The workload server is no longer reachable in this scope.");return m.runRemoteDeploy({targets:[I],commands:t,timeoutSeconds:r,comment:o,tags:{Project:this.config.project.slug,Environment:this.environment,Role:"app"}})}async run(e){let t=await this.workload(e.workloadId),r={workloadId:e.workloadId,action:e.action};if(!t)return{...r,ok:!1,error:"Workload was not found in the current project and environment."};let o=t.capabilities[e.action];if(!o.supported)return{...r,ok:!1,error:o.reason??`${e.action} is unsupported for ${t.provider}.`};if(o.requiresConfirmation&&e.confirm!==t.name)return{...r,ok:!1,error:`Type "${t.name}" to ${e.action} this workload.`};if(o.requiresRecentAuth&&!e.recentAuth)return{...r,ok:!1,error:"Sign in again before using elevated runtime access."};if(e.action==="inspect")return{...r,ok:!0,workload:t};if(t.provider==="systemd"||t.provider==="docker"){let m=eC(t,e.action);if(!m)return{...r,ok:!1,error:`${e.action} is not implemented for ${t.provider}.`};let h=await this.remote(t,["set -uo pipefail",...m],60,`ts-cloud runtime:${e.action}`).catch(yu);return{...r,ok:h.success,command:m[0],stdout:Ba(h.perInstance?.[0]?.output??""),stderr:Ba(h.perInstance?.[0]?.error??h.error??""),error:h.success?void 0:h.error??"Runtime operation failed."}}if(t.provider==="ecs"){let m=ZA(t);if(!m)return{...r,ok:!1,error:"ECS cluster or service identity is unavailable."};let h=this.dependencies.ecs??new We(this.region,this.profile);if(e.action==="scale"){let I=YA(e.replicas,t.desiredReplicas??1);return await h.scaleService(m.cluster,m.service,I),{...r,ok:!0,command:`ecs scale ${t.name} ${I}`}}if(e.action==="start"||e.action==="stop"){let I=e.action==="stop"?0:Math.max(1,t.desiredReplicas??1);return await h.scaleService(m.cluster,m.service,I),{...r,ok:!0,command:`ecs scale ${t.name} ${I}`}}if(e.action==="restart"||e.action==="redeploy")return await h.forceNewDeployment(m.cluster,m.service),{...r,ok:!0,command:`ecs redeploy ${t.name}`}}return{...r,ok:!1,error:`${e.action} is not implemented for ${t.provider}.`}}async exec(e){let t={workloadId:e.workloadId,preset:e.preset},r=await this.workload(e.workloadId);if(!r)return{...t,ok:!1,error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_EXEC==="0")return{...t,ok:!1,error:"Runtime exec is disabled by TS_CLOUD_RUNTIME_EXEC."};if(!r.capabilities.exec.supported)return{...t,ok:!1,error:r.capabilities.exec.reason??"Exec is unsupported for this workload."};if(e.confirm!==r.name)return{...t,ok:!1,error:`Type "${r.name}" to open exec access.`};if(!e.recentAuth)return{...t,ok:!1,error:"Sign in again before using elevated runtime access."};let o=e.preset&&sl[e.preset];if(!o&&!e.command?.trim())return{...t,ok:!1,error:"Choose a diagnostic preset or provide a command."};if(e.command&&r.provider!=="docker")return{...t,ok:!1,error:"Free-form exec is restricted to isolated containers; use a diagnostic preset for system services."};let m=r.links.providerId??"",h;if(r.provider==="docker"&&bu.test(m)){let R=e.command?.trim()||o.map(zn).join(" ");h=`docker exec ${m} sh -lc ${zn(R)}`}else if(r.provider==="systemd"&&vu.test(m)&&e.preset)h=e.preset==="process"?`systemctl status ${m} --no-pager --full`:sl[e.preset].map(zn).join(" ");if(!h)return{...t,ok:!1,error:"Exec target identity is invalid or unsupported."};let I=await this.remote(r,["set -uo pipefail",h],60,"ts-cloud runtime:exec").catch(yu);return{...t,ok:I.success,command:h,stdout:Ba(I.perInstance?.[0]?.output??""),stderr:Ba(I.perInstance?.[0]?.error??I.error??""),error:I.success?void 0:I.error??"Exec command failed."}}async readFile(e){let t={workloadId:e.workloadId,path:e.path},r=await this.fileTarget(e);if("error"in r)return{...t,ok:!1,error:r.error};let{workload:o,path:m,root:h,providerId:I}=r,A=`sh -c ${zn('resolved=$(realpath -m "$1"); root=$(realpath -m "$3"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; test -f "$resolved"; size=$(wc -c < "$resolved"); printf "__TSCLOUD_SIZE__=%s\\n" "$size"; head -c "$2" "$resolved" | base64')} sh ${zn(m)} ${hc} ${zn(h)}`,E=o.provider==="docker"?`docker exec ${I} ${A}`:A,x=await this.remote(o,[E],30,"ts-cloud runtime:file-read").catch(yu);if(!x.success)return{...t,ok:!1,error:x.error??x.perInstance?.[0]?.error??"File read failed."};let N=x.perInstance?.[0]?.output??"",F=/__TSCLOUD_SIZE__=(\d+)\r?\n/.exec(N);if(!F)return{...t,ok:!1,error:"The remote file response was invalid."};let z=Number(F[1]),H=N.slice((F.index??0)+F[0].length).replace(/\s+/g,"");if(Buffer.from(H,"base64").byteLength>hc)return{...t,ok:!1,error:"The remote file exceeded the transfer limit."};return{...t,ok:!0,contentBase64:H,size:z,truncated:z>hc}}async writeFile(e){let t={workloadId:e.workloadId,path:e.path},r=await this.fileTarget(e);if("error"in r)return{...t,ok:!1,error:r.error};if(!/^[A-Za-z0-9+/]*={0,2}$/.test(e.contentBase64))return{...t,ok:!1,error:"File content must be valid base64."};let o=Buffer.from(e.contentBase64,"base64");if(o.toString("base64")!==e.contentBase64)return{...t,ok:!1,error:"File content must be canonical base64."};if(o.byteLength>hc)return{...t,ok:!1,error:`File uploads are limited to ${hc} bytes.`};let{workload:m,path:h,root:I,providerId:R}=r,E=`sh -c ${zn('resolved=$(realpath -m "$1"); root=$(realpath -m "$2"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; mkdir -p "$(dirname "$resolved")"; tmp="$resolved.ts-cloud-$$"; base64 -d > "$tmp"; chmod 600 "$tmp"; mv "$tmp" "$resolved"')} sh ${zn(h)} ${zn(I)}`,x=m.provider==="docker"?`printf %s ${zn(e.contentBase64)} | docker exec -i ${R} ${E}`:`printf %s ${zn(e.contentBase64)} | ${E}`,N=await this.remote(m,[x],30,"ts-cloud runtime:file-write").catch(yu);return{...t,ok:N.success,size:o.byteLength,truncated:!1,error:N.success?void 0:N.error??N.perInstance?.[0]?.error??"File write failed."}}async fileTarget(e){let t=await this.workload(e.workloadId);if(!t)return{error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_FILE_ACCESS==="0")return{error:"Runtime file access is disabled by TS_CLOUD_RUNTIME_FILE_ACCESS."};if(!t.capabilities.files.supported)return{error:t.capabilities.files.reason??"File access is unsupported for this workload."};if(e.confirm!==t.name)return{error:`Type "${t.name}" to access workload files.`};if(!e.recentAuth)return{error:"Sign in again before using elevated runtime access."};let r=om(t,e.path);if(!r.ok)return{error:r.error};let o=tC(t,r.path),m=t.links.providerId??"";if(!o||t.provider==="systemd"&&!vu.test(m)||t.provider==="docker"&&!bu.test(m))return{error:"File target identity is invalid or unsupported."};return{workload:t,path:r.path,root:o,providerId:m}}async logs(e,t={}){let r=await this.workload(e);if(!r)throw Error("Workload was not found in the current project and environment.");if(!r.capabilities.logs.supported)throw Error(r.capabilities.logs.reason??"Logs are unsupported for this workload.");let o=Math.min(1000,Math.max(1,Math.floor(t.limit??200)));if(r.provider==="lambda"||r.provider==="ecs"){let x=this.dependencies.logs??new pe(this.region,this.profile),N=r.config.logGroups,F=r.provider==="lambda"?`/aws/lambda/${r.name}`:Array.isArray(N)&&typeof N[0]==="string"?N[0]:void 0;if(!F)throw Error("The ECS task definition does not declare an awslogs group.");let z=await x.filterLogEvents({logGroupName:F,startTime:t.since?.getTime(),limit:o}),H=(z.events??[]).slice(0,o).map((K)=>({timestamp:K.timestamp==null?void 0:new Date(K.timestamp).toISOString(),message:Ba(String(K.message??""))}));return{workloadId:e,provider:r.provider,lines:H,nextCursor:z.nextToken,truncated:(z.events?.length??0)>=o}}let m=r.links.providerId??"",h=t.since&&Number.isFinite(t.since.getTime())?t.since:void 0,I=r.provider==="systemd"&&vu.test(m)?`journalctl -u ${m} --no-pager -n ${o} -o short-iso${h?` --since ${zn(h.toISOString())}`:""}`:r.provider==="docker"&&bu.test(m)?`docker logs --timestamps --tail ${o}${h?` --since ${Math.floor(h.getTime()/1000)}`:""} ${m} 2>&1`:void 0;if(!I)throw Error("Log target identity is invalid.");let R=await this.remote(r,[I],30,"ts-cloud runtime:logs");if(!R.success)throw Error(R.error??R.perInstance?.[0]?.error??"Log read failed.");let A=Ba(R.perInstance?.[0]?.output??""),E=A.split(`
171
171
  `).filter(Boolean).slice(-o).map((x)=>{let N=/^(\d{4}-\d{2}-\d{2}T\S+)\s+(.*)$/.exec(x);return{timestamp:N?.[1],message:N?.[2]??x}});return{workloadId:e,provider:r.provider,lines:E,truncated:A.includes("[output truncated]")||E.length>=o}}}import{randomUUID as rC}from"node:crypto";class Ro{records=new Map;maxBufferBytes;ttlMs;now;constructor(e={}){this.maxBufferBytes=Math.max(1024,e.maxBufferBytes??262144),this.ttlMs=Math.max(1000,e.ttlMs??900000),this.now=e.now??(()=>new Date)}create(e,t){this.sweep();let r=this.now().toISOString(),o={id:rC(),workloadId:t,kind:e,state:"open",chunks:[],cursor:0,droppedBytes:0,bufferedBytes:0,createdAt:r,updatedAt:r,abort:new AbortController,listeners:new Set};return this.records.set(o.id,o),this.snapshot(o,0)}signal(e){return this.records.get(e)?.abort.signal}append(e,t,r="stdout"){let o=this.records.get(e);if(!o||o.state!=="open"||!t)return o?this.snapshot(o,o.cursor):void 0;let m=Buffer.from(t),h=m.byteLength>this.maxBufferBytes?m.subarray(m.byteLength-this.maxBufferBytes).toString("utf8"):t,I={cursor:++o.cursor,stream:r,data:h,at:this.now().toISOString()};o.chunks.push(I),o.bufferedBytes+=Buffer.byteLength(h),o.updatedAt=I.at;while(o.bufferedBytes>this.maxBufferBytes&&o.chunks.length>1){let R=o.chunks.shift(),A=Buffer.byteLength(R.data);o.bufferedBytes-=A,o.droppedBytes+=A}return this.publish(o),this.snapshot(o,I.cursor-1)}read(e,t,r=0){let o=this.records.get(e);if(!o||o.workloadId!==t)return;return o.updatedAt=this.now().toISOString(),this.snapshot(o,Math.max(0,Math.floor(r)))}close(e,t="complete",r){let o=this.records.get(e);if(!o||o.state!=="open")return o?this.snapshot(o,o.cursor):void 0;if(o.state=t,o.error=r,o.updatedAt=this.now().toISOString(),t==="cancelled")o.abort.abort();return this.publish(o),this.snapshot(o,o.cursor)}cancel(e,t){let r=this.records.get(e);if(!r||r.workloadId!==t)return;return this.close(e,"cancelled")}subscribe(e,t,r){let o=this.records.get(e);if(!o||o.workloadId!==t)return;return o.listeners.add(r),()=>o.listeners.delete(r)}sweep(){let e=this.now().getTime()-this.ttlMs,t=0;for(let[r,o]of this.records){if(new Date(o.updatedAt).getTime()>e)continue;o.abort.abort(),this.records.delete(r),t++}return t}clear(){for(let e of this.records.values())e.abort.abort();this.records.clear()}snapshot(e,t){let r=e.chunks[0]?.cursor??e.cursor+1,o=t>0&&t<r-1;return{id:e.id,workloadId:e.workloadId,kind:e.kind,state:e.state,chunks:e.chunks.filter((m)=>o||m.cursor>t),cursor:e.cursor,reset:o,droppedBytes:e.droppedBytes,createdAt:e.createdAt,updatedAt:e.updatedAt,error:e.error}}publish(e){let t=this.snapshot(e,0);for(let r of e.listeners)r(t)}}import{createHash as nC}from"node:crypto";var cg={info:0,low:1,medium:2,high:3,critical:4},dg={record:0,warn:1,block:2},Fv=new Set(["skipped","unavailable","unsupported","stale"]);function vr(e){return typeof e==="string"?e:void 0}function ps(e,t){try{return JSON.parse(String(e))}catch{return t}}function Qn(e){return JSON.stringify(s(e))}function iC(e){if(!e)return;return String(s(e,2000))}function og(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:vr(e.project_id),environmentId:vr(e.environment_id),resourceId:vr(e.resource_id),releaseId:vr(e.release_id),scannerId:String(e.scanner_id),scannerVersion:String(e.scanner_version),status:String(e.status),error:vr(e.error),metadata:ps(e.metadata,{}),findingsCount:Number(e.findings_count),startedAt:String(e.started_at),completedAt:String(e.completed_at),durationMs:Number(e.duration_ms)}}function zv(e){return{id:String(e.id),fingerprint:String(e.fingerprint),organizationId:String(e.organization_id),projectId:vr(e.project_id),environmentId:vr(e.environment_id),resourceId:vr(e.resource_id),releaseId:vr(e.release_id),scanRunId:String(e.scan_run_id),scannerId:String(e.scanner_id),scannerVersion:String(e.scanner_version),ruleId:String(e.rule_id),severity:String(e.severity),title:String(e.title),description:String(e.description),evidence:ps(e.evidence,{}),remediation:vr(e.remediation),subject:String(e.subject),status:String(e.status),ownerActorId:vr(e.owner_actor_id),recurrenceCount:Number(e.recurrence_count),firstSeenAt:String(e.first_seen_at),lastSeenAt:String(e.last_seen_at),resolvedAt:vr(e.resolved_at),updatedAt:String(e.updated_at)}}function sg(e){return{id:String(e.id),organizationId:String(e.organization_id),environmentId:vr(e.environment_id),name:String(e.name),rules:ps(e.rules,[]),requiredScanners:ps(e.required_scanners,[]),scannerFailMode:String(e.scanner_fail_mode),enabled:Number(e.enabled)===1,version:Number(e.version),createdByActorId:vr(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Uv(e,t){let r=vr(e.revoked_at),o=String(e.expires_at);return{id:String(e.id),findingId:String(e.finding_id),policyId:vr(e.policy_id),reason:String(e.reason),referenceUrl:vr(e.reference_url),createdByActorId:String(e.created_by_actor_id),expiresAt:o,revokedAt:r,state:r?"revoked":o<=t?"expired":"active",createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function ag(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:vr(e.environment_id),releaseId:String(e.release_id),kind:String(e.kind),format:String(e.format),digest:String(e.digest),summary:ps(e.summary,{}),content:vr(e.content),sensitive:Number(e.sensitive)===1,createdAt:String(e.created_at)}}function qv(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:String(e.environment_id),operationId:vr(e.operation_id),policyId:String(e.policy_id),policyVersion:Number(e.policy_version),outcome:String(e.outcome),scannerVersions:ps(e.scanner_versions,{}),findingIds:ps(e.finding_ids,[]),waiverIds:ps(e.waiver_ids,[]),explanation:String(e.explanation),createdAt:String(e.created_at)}}function oC(e,t){let r=[e.trim().toLowerCase(),t.ruleId.trim().toLowerCase(),t.organizationId,t.projectId??"",t.environmentId??"",t.resourceId??"",t.releaseId??"",t.subject.trim().toLowerCase()].join("\x00");return nC("sha256").update(r).digest("hex")}function Vv(e){if(!e)return;let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw Error("Security references must use HTTP or HTTPS");return t.toString()}function Wv(e){if(!e.length)throw Error("A security policy needs at least one rule");return e.map((t)=>{if(!(t.minimumSeverity in cg))throw Error(`Unknown security severity: ${t.minimumSeverity}`);if(!(t.action in dg))throw Error(`Unknown security policy action: ${t.action}`);return{minimumSeverity:t.minimumSeverity,action:t.action,...t.scannerId?{scannerId:t.scannerId.trim()}:{}}})}class Fr{controlPlane;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}recordScan(e){if(!e.organizationId||!e.scannerId.trim()||!e.scannerVersion.trim())throw Error("Organization, scanner id, and scanner version are required");let t=e.completedAt??this.now(),r=e.startedAt??t,o=e.durationMs??Math.max(0,new Date(t).getTime()-new Date(r).getTime()),m=e.findings??[],h=this.idFn(),I=new Set,R=[];return this.controlPlane.transaction(()=>{this.run(`INSERT INTO security_scan_runs
172
172
  (id, organization_id, project_id, environment_id, resource_id, release_id, scanner_id, scanner_version, status, error, metadata, findings_count, started_at, completed_at, duration_ms)
173
173
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[h,e.organizationId,e.projectId??null,e.environmentId??null,e.resourceId??null,e.releaseId??null,e.scannerId.trim(),e.scannerVersion.trim(),e.status,iC(e.error)??null,Qn(e.metadata??{}),m.length,r,t,Math.max(0,Math.floor(o))]);for(let A of m){let E={...A,organizationId:e.organizationId,projectId:A.projectId??e.projectId,environmentId:A.environmentId??e.environmentId,resourceId:A.resourceId??e.resourceId,releaseId:A.releaseId??e.releaseId},x=E.fingerprint?.trim()||oC(e.scannerId,E);I.add(x);let N=this.controlPlane.database.query("SELECT * FROM security_findings WHERE fingerprint = ?").get(x),F=N?this.controlPlane.database.query("SELECT * FROM security_waivers WHERE finding_id = ? AND revoked_at IS NULL AND expires_at > ? ORDER BY expires_at DESC LIMIT 1").get(String(N.id),t):void 0;if(N){let z=String(N.status)==="resolved"?Number(N.recurrence_count)+1:Number(N.recurrence_count),H=F?"waived":String(N.status)==="acknowledged"?"acknowledged":"open";this.run(`UPDATE security_findings SET scan_run_id = ?, scanner_version = ?, severity = ?, title = ?, description = ?, evidence = ?, remediation = ?,
@@ -179,14 +179,14 @@ export type ConfigOf = Config
179
179
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[I,t.id,e.policyId??null,r,R??null,e.actorId,m.toISOString(),o,o]),this.run("UPDATE security_findings SET status = 'waived', updated_at = ? WHERE id = ?",[o,t.id]),this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:t.projectId,resourceId:t.resourceId,actorId:e.actorId,type:"security.waiver.created",level:"warning",payload:{waiverId:I,findingId:t.id,policyId:e.policyId??null,reason:r,expiresAt:m.toISOString(),referenceUrl:R??null}})}),this.getWaiver(I)}revokeWaiver(e,t){let r=this.getWaiver(e);if(!r)throw Error("Security waiver was not found");if(r.revokedAt)return r;let o=this.getFinding(r.findingId),m=this.now();return this.controlPlane.transaction(()=>{this.run("UPDATE security_waivers SET revoked_at = ?, updated_at = ? WHERE id = ?",[m,m,e]),this.run("UPDATE security_findings SET status = 'open', updated_at = ? WHERE id = ? AND status = 'waived'",[m,r.findingId]),this.controlPlane.appendEvent({organizationId:o.organizationId,projectId:o.projectId,resourceId:o.resourceId,actorId:t,type:"security.waiver.revoked",level:"warning",payload:{waiverId:e,findingId:r.findingId}})}),this.getWaiver(e)}getWaiver(e){let t=this.controlPlane.database.query("SELECT * FROM security_waivers WHERE id = ?").get(e);return t?Uv(t,this.now()):void 0}listWaivers(e){return(e?this.controlPlane.database.query("SELECT * FROM security_waivers WHERE finding_id = ? ORDER BY created_at DESC").all(e):this.controlPlane.database.query("SELECT * FROM security_waivers ORDER BY created_at DESC").all()).map((r)=>Uv(r,this.now()))}expireWaivers(){let e=this.now(),t=this.controlPlane.database.query(`SELECT w.id AS waiver_id, f.* FROM security_waivers w JOIN security_findings f ON f.id = w.finding_id
180
180
  WHERE w.revoked_at IS NULL AND w.expires_at <= ? AND f.status = 'waived'`).all(e);for(let r of t)this.run("UPDATE security_findings SET status = 'open', updated_at = ? WHERE id = ?",[e,String(r.id)]),this.controlPlane.appendEvent({organizationId:String(r.organization_id),projectId:vr(r.project_id),resourceId:vr(r.resource_id),type:"security.waiver.expired",level:"warning",payload:{waiverId:String(r.waiver_id),findingId:String(r.id)}});return t.length}createPolicy(e){let t=e.name.trim();if(!t)throw Error("Security policy name is required");let r=Wv(e.rules),o=this.idFn(),m=this.now(),h=[...new Set((e.requiredScanners??[]).map((I)=>I.trim()).filter(Boolean))].sort();return this.run(`INSERT INTO security_policies (id, organization_id, environment_id, name, rules, required_scanners, scanner_fail_mode, created_by_actor_id, created_at, updated_at)
181
181
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[o,e.organizationId,e.environmentId??null,t,Qn(r),Qn(h),e.scannerFailMode,e.actorId??null,m,m]),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.actorId,type:"security.policy.created",payload:{policyId:o,environmentId:e.environmentId??null,scannerFailMode:e.scannerFailMode,requiredScanners:h,rules:s(r)}}),this.getPolicy(o)}updatePolicy(e,t,r){let o=this.getPolicy(e);if(!o||o.version!==t)throw Error(`Security policy ${e} changed since version ${t}`);let m=r.rules?Wv(r.rules):o.rules,h=r.requiredScanners?[...new Set(r.requiredScanners.map((A)=>A.trim()).filter(Boolean))].sort():o.requiredScanners,I=this.now();if(this.controlPlane.database.run("UPDATE security_policies SET name = ?, rules = ?, required_scanners = ?, scanner_fail_mode = ?, enabled = ?, version = version + 1, updated_at = ? WHERE id = ? AND version = ?",[r.name?.trim()||o.name,Qn(m),Qn(h),r.scannerFailMode??o.scannerFailMode,r.enabled??o.enabled?1:0,I,e,t]).changes!==1)throw Error(`Security policy ${e} changed since version ${t}`);return this.controlPlane.appendEvent({organizationId:o.organizationId,actorId:r.actorId,type:"security.policy.updated",payload:{policyId:e,fromVersion:t,toVersion:t+1}}),this.getPolicy(e)}getPolicy(e){let t=this.controlPlane.database.query("SELECT * FROM security_policies WHERE id = ?").get(e);return t?sg(t):void 0}listPolicies(e){return this.controlPlane.database.query("SELECT * FROM security_policies WHERE organization_id = ? ORDER BY environment_id, name").all(e).map(sg)}evaluateGate(e){this.expireWaivers();let t=e.policyId?this.getPolicy(e.policyId):this.controlPlane.database.query(`SELECT * FROM security_policies WHERE organization_id = ? AND enabled = 1 AND (environment_id = ? OR environment_id IS NULL)
182
- ORDER BY CASE WHEN environment_id = ? THEN 0 ELSE 1 END, updated_at DESC LIMIT 1`).get(e.organizationId,e.environmentId,e.environmentId),r=t&&"rules"in t&&Array.isArray(t.rules)?t:t?sg(t):void 0;if(!r||!r.enabled)throw Error("No enabled security policy applies to this environment");let o=this.listFindings({organizationId:e.organizationId,projectId:e.projectId,environmentId:e.environmentId,limit:1000}).filter((_e)=>_e.status!=="resolved"),m=new Map;for(let _e of o){let he=this.listWaivers(_e.id).find((Ue)=>Ue.state==="active"&&(!Ue.policyId||Ue.policyId===r.id));if(he)m.set(_e.id,he)}let h=(_e)=>r.rules.filter((he)=>(!he.scannerId||he.scannerId===_e.scannerId)&&cg[_e.severity]>=cg[he.minimumSeverity]).reduce((he,Ue)=>dg[Ue.action]>dg[he]?Ue.action:he,"record"),I=o.filter((_e)=>!m.has(_e.id)&&h(_e)==="block"),R=o.filter((_e)=>!m.has(_e.id)&&h(_e)==="warn"),A=this.controlPlane.database.query(`SELECT run.* FROM security_scan_runs run
182
+ ORDER BY CASE WHEN environment_id = ? THEN 0 ELSE 1 END, updated_at DESC LIMIT 1`).get(e.organizationId,e.environmentId,e.environmentId),r=t&&"rules"in t&&Array.isArray(t.rules)?t:t?sg(t):void 0;if(!r||!r.enabled)throw Error("No enabled security policy applies to this environment");let o=this.listFindings({organizationId:e.organizationId,projectId:e.projectId,environmentId:e.environmentId,limit:1000}).filter((xe)=>xe.status!=="resolved"),m=new Map;for(let xe of o){let he=this.listWaivers(xe.id).find((Ue)=>Ue.state==="active"&&(!Ue.policyId||Ue.policyId===r.id));if(he)m.set(xe.id,he)}let h=(xe)=>r.rules.filter((he)=>(!he.scannerId||he.scannerId===xe.scannerId)&&cg[xe.severity]>=cg[he.minimumSeverity]).reduce((he,Ue)=>dg[Ue.action]>dg[he]?Ue.action:he,"record"),I=o.filter((xe)=>!m.has(xe.id)&&h(xe)==="block"),R=o.filter((xe)=>!m.has(xe.id)&&h(xe)==="warn"),A=this.controlPlane.database.query(`SELECT run.* FROM security_scan_runs run
183
183
  WHERE run.organization_id = ? AND run.project_id = ? AND run.environment_id = ?
184
184
  AND run.id = (SELECT candidate.id FROM security_scan_runs candidate
185
185
  WHERE candidate.organization_id = run.organization_id AND candidate.project_id = run.project_id
186
186
  AND candidate.environment_id = run.environment_id AND candidate.scanner_id = run.scanner_id
187
- ORDER BY candidate.completed_at DESC, candidate.rowid DESC LIMIT 1)`).all(e.organizationId,e.projectId,e.environmentId),E=e.staleAfterMs??86400000,x=this.nowFn().getTime(),N=A.map(og).map((_e)=>x-new Date(_e.completedAt).getTime()>E?{..._e,status:"stale"}:_e),F=new Set(N.map((_e)=>_e.scannerId)),z=r.requiredScanners.filter((_e)=>!F.has(_e)).map((_e)=>({id:`missing:${_e}`,organizationId:e.organizationId,projectId:e.projectId,environmentId:e.environmentId,scannerId:_e,scannerVersion:"unavailable",status:"unavailable",metadata:{},findingsCount:0,startedAt:this.now(),completedAt:this.now(),durationMs:0})),H=[...N,...z],K=H.filter((_e)=>r.requiredScanners.includes(_e.scannerId)&&Fv.has(_e.status)),X=Object.fromEntries(H.map((_e)=>[_e.scannerId,_e.scannerVersion])),oe=r.scannerFailMode==="closed"&&K.length>0,ye=I.length||oe?"block":R.length||K.length?"warn":"allow",ne=[];if(I.length)ne.push(`${I.length} finding${I.length===1?"":"s"} blocked by policy`);if(R.length)ne.push(`${R.length} warning${R.length===1?"":"s"} require review`);if(K.length)ne.push(`${K.length} scanner${K.length===1?"":"s"} ${r.scannerFailMode==="closed"?"failed closed":"failed open"}`);if(m.size)ne.push(`${m.size} active time-limited waiver${m.size===1?"":"s"}`);if(!ne.length)ne.push("All recorded checks satisfy policy");let fe=this.idFn(),Ce=this.now();return this.run(`INSERT INTO security_deploy_decisions
187
+ ORDER BY candidate.completed_at DESC, candidate.rowid DESC LIMIT 1)`).all(e.organizationId,e.projectId,e.environmentId),E=e.staleAfterMs??86400000,x=this.nowFn().getTime(),N=A.map(og).map((xe)=>x-new Date(xe.completedAt).getTime()>E?{...xe,status:"stale"}:xe),F=new Set(N.map((xe)=>xe.scannerId)),z=r.requiredScanners.filter((xe)=>!F.has(xe)).map((xe)=>({id:`missing:${xe}`,organizationId:e.organizationId,projectId:e.projectId,environmentId:e.environmentId,scannerId:xe,scannerVersion:"unavailable",status:"unavailable",metadata:{},findingsCount:0,startedAt:this.now(),completedAt:this.now(),durationMs:0})),H=[...N,...z],K=H.filter((xe)=>r.requiredScanners.includes(xe.scannerId)&&Fv.has(xe.status)),X=Object.fromEntries(H.map((xe)=>[xe.scannerId,xe.scannerVersion])),oe=r.scannerFailMode==="closed"&&K.length>0,ye=I.length||oe?"block":R.length||K.length?"warn":"allow",ne=[];if(I.length)ne.push(`${I.length} finding${I.length===1?"":"s"} blocked by policy`);if(R.length)ne.push(`${R.length} warning${R.length===1?"":"s"} require review`);if(K.length)ne.push(`${K.length} scanner${K.length===1?"":"s"} ${r.scannerFailMode==="closed"?"failed closed":"failed open"}`);if(m.size)ne.push(`${m.size} active time-limited waiver${m.size===1?"":"s"}`);if(!ne.length)ne.push("All recorded checks satisfy policy");let fe=this.idFn(),Ce=this.now();return this.run(`INSERT INTO security_deploy_decisions
188
188
  (id, organization_id, project_id, environment_id, operation_id, policy_id, policy_version, outcome, scanner_versions, finding_ids, waiver_ids, explanation, created_at)
189
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[fe,e.organizationId,e.projectId,e.environmentId,e.operationId??null,r.id,r.version,ye,Qn(X),Qn([...I,...R].map((_e)=>_e.id)),Qn([...m.values()].map((_e)=>_e.id)),ne.join("; "),Ce]),this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,operationId:e.operationId,type:"security.deploy.decision",level:ye==="block"?"error":ye==="warn"?"warning":"info",payload:{decisionId:fe,outcome:ye,policyId:r.id,policyVersion:r.version,scannerVersions:X,blockerIds:I.map((_e)=>_e.id),waiverIds:[...m.values()].map((_e)=>_e.id),explanation:ne.join("; ")}}),this.getDecision(fe)}getDecision(e){let t=this.controlPlane.database.query("SELECT * FROM security_deploy_decisions WHERE id = ?").get(e);return t?qv(t):void 0}listDecisions(e,t=100){return this.controlPlane.database.query("SELECT * FROM security_deploy_decisions WHERE environment_id = ? ORDER BY created_at DESC LIMIT ?").all(e,Math.min(500,Math.max(1,t))).map(qv)}addReleaseArtifact(e){let t=this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE release_id = ? AND kind = ? AND digest = ?").get(e.releaseId,e.kind,e.digest);if(t)return ag(t);let r=this.idFn(),o=this.now();return this.run(`INSERT INTO release_security_artifacts
189
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[fe,e.organizationId,e.projectId,e.environmentId,e.operationId??null,r.id,r.version,ye,Qn(X),Qn([...I,...R].map((xe)=>xe.id)),Qn([...m.values()].map((xe)=>xe.id)),ne.join("; "),Ce]),this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,operationId:e.operationId,type:"security.deploy.decision",level:ye==="block"?"error":ye==="warn"?"warning":"info",payload:{decisionId:fe,outcome:ye,policyId:r.id,policyVersion:r.version,scannerVersions:X,blockerIds:I.map((xe)=>xe.id),waiverIds:[...m.values()].map((xe)=>xe.id),explanation:ne.join("; ")}}),this.getDecision(fe)}getDecision(e){let t=this.controlPlane.database.query("SELECT * FROM security_deploy_decisions WHERE id = ?").get(e);return t?qv(t):void 0}listDecisions(e,t=100){return this.controlPlane.database.query("SELECT * FROM security_deploy_decisions WHERE environment_id = ? ORDER BY created_at DESC LIMIT ?").all(e,Math.min(500,Math.max(1,t))).map(qv)}addReleaseArtifact(e){let t=this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE release_id = ? AND kind = ? AND digest = ?").get(e.releaseId,e.kind,e.digest);if(t)return ag(t);let r=this.idFn(),o=this.now();return this.run(`INSERT INTO release_security_artifacts
190
190
  (id, organization_id, project_id, environment_id, release_id, kind, format, digest, summary, content, sensitive, created_at)
191
191
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,e.organizationId,e.projectId,e.environmentId??null,e.releaseId,e.kind,e.format,e.digest,Qn(e.summary),e.content??null,e.sensitive?1:0,o]),this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,type:"security.release_artifact.created",payload:{artifactId:r,releaseId:e.releaseId,kind:e.kind,format:e.format,digest:e.digest,sensitive:e.sensitive}}),ag(this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE id = ?").get(r))}listReleaseArtifacts(e,t=!1){return this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE release_id = ? ORDER BY created_at, kind").all(e).map(ag).map((r)=>r.sensitive&&!t?{...r,content:void 0}:r)}summary(e,t,r){let o=this.listFindings({organizationId:e,projectId:t,environmentId:r,limit:1000}),m=this.listScanRuns({organizationId:e,projectId:t,environmentId:r,limit:1000}),h={info:0,low:0,medium:0,high:0,critical:0};for(let R of o)if(R.status==="open"||R.status==="acknowledged")h[R.severity]++;let I={passed:0,failed:0,skipped:0,unavailable:0,unsupported:0,stale:0};for(let R of m)I[R.status]++;return{open:h,waived:o.filter((R)=>R.status==="waived").length,resolved:o.filter((R)=>R.status==="resolved").length,checks:I,lastScannedAt:m[0]?.completedAt}}exportPosture(e){let t=this.controlPlane.listProjects().filter((r)=>r.organizationId===e);return s({format:"ts-cloud-security-posture",version:1,exportedAt:this.now(),organizationId:e,policies:this.listPolicies(e),findings:this.listFindings({organizationId:e,limit:1000}),waivers:this.listWaivers().filter((r)=>this.getFinding(r.findingId)?.organizationId===e),scans:t.flatMap((r)=>this.listScanRuns({organizationId:e,projectId:r.id,limit:1000})),decisions:t.flatMap((r)=>this.controlPlane.listEnvironments(r.id).flatMap((o)=>this.listDecisions(o.id,1000)))})}}import{existsSync as sC,readdirSync as aC,readFileSync as cC,statSync as dC}from"node:fs";import{extname as lC,join as uC,relative as pC}from"node:path";var jd=[{name:"AWS Access Key ID",pattern:/(?:^|[^A-Z0-9])((AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16})(?:[^A-Z0-9]|$)/g,severity:"critical",description:"AWS Access Key ID detected"},{name:"AWS Secret Access Key",pattern:/(?:aws_secret_access_key|aws_secret_key|secret_access_key|secretAccessKey)['"]?\s*[=:]\s*['"]?([A-Za-z0-9/+=]{40})['"]?/gi,severity:"critical",description:"AWS Secret Access Key detected"},{name:"AWS Secret Key (Generic)",pattern:/(?:^|['"`:=\s])([A-Za-z0-9/+=]{40})(?:['"`\s]|$)/g,severity:"high",description:"Potential AWS Secret Key (40-char base64)"},{name:"Generic API Key",pattern:/(?:api[_-]?key|apikey|api[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9_\-]{20,})['"]?/gi,severity:"high",description:"Generic API key detected"},{name:"RSA Private Key",pattern:/-----BEGIN RSA PRIVATE KEY-----/g,severity:"critical",description:"RSA private key detected"},{name:"OpenSSH Private Key",pattern:/-----BEGIN OPENSSH PRIVATE KEY-----/g,severity:"critical",description:"OpenSSH private key detected"},{name:"EC Private Key",pattern:/-----BEGIN EC PRIVATE KEY-----/g,severity:"critical",description:"EC private key detected"},{name:"PGP Private Key",pattern:/-----BEGIN PGP PRIVATE KEY BLOCK-----/g,severity:"critical",description:"PGP private key detected"},{name:"GitHub Token",pattern:/(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}/g,severity:"critical",description:"GitHub personal access token detected"},{name:"GitHub OAuth",pattern:/github[_-]?oauth[_-]?token\s*[=:]\s*['"]?([A-Za-z0-9_]{40})['"]?/gi,severity:"critical",description:"GitHub OAuth token detected"},{name:"Slack Token",pattern:/xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*/g,severity:"critical",description:"Slack token detected"},{name:"Slack Webhook",pattern:/https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/g,severity:"high",description:"Slack webhook URL detected"},{name:"Discord Webhook",pattern:/https:\/\/discord(?:app)?\.com\/api\/webhooks\/[0-9]+\/[A-Za-z0-9_-]+/g,severity:"high",description:"Discord webhook URL detected"},{name:"JWT Token",pattern:/eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*/g,severity:"high",description:"JWT token detected"},{name:"Google API Key",pattern:/AIza[0-9A-Za-z_-]{35}/g,severity:"critical",description:"Google API key detected"},{name:"Google OAuth ID",pattern:/[0-9]+-[A-Za-z0-9_]{32}\.apps\.googleusercontent\.com/g,severity:"high",description:"Google OAuth client ID detected"},{name:"Firebase API Key",pattern:/(?:firebase[_-]?api[_-]?key)\s*[=:]\s*['"]?([A-Za-z0-9_-]{39})['"]?/gi,severity:"critical",description:"Firebase API key detected"},{name:"Cloudflare API Token",pattern:/(?:cloudflare[_-]?api[_-]?token|cf[_-]?api[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{40})['"]?/gi,severity:"critical",description:"Cloudflare API token detected"},{name:"Azure Client Secret",pattern:/(?:azure[_-]?client[_-]?secret|client[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9~._-]{34,})['"]?/gi,severity:"critical",description:"Azure client secret detected"},{name:"Heroku API Key",pattern:/(?:heroku[_-]?api[_-]?key)\s*[=:]\s*['"]?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})['"]?/gi,severity:"critical",description:"Heroku API key detected"},{name:"Database Connection String",pattern:/(?:mysql|postgres|postgresql|mongodb|redis|mongodb\+srv):\/\/[^:]+:[^@]+@[^/\s]+/gi,severity:"critical",description:"Database connection string with credentials detected"},{name:"Database Password",pattern:/(?:db[_-]?password|database[_-]?password|mysql[_-]?password|postgres[_-]?password)\s*[=:]\s*['"]?([^'"\s]{8,})['"]?/gi,severity:"critical",description:"Database password detected"},{name:"Stripe API Key",pattern:/(?:sk|pk)_(?:test|live)_[0-9a-zA-Z]{24,}/g,severity:"critical",description:"Stripe API key detected"},{name:"PayPal Client ID",pattern:/(?:paypal[_-]?client[_-]?id)\s*[=:]\s*['"]?([A-Za-z0-9_-]{80})['"]?/gi,severity:"high",description:"PayPal client ID detected"},{name:"Square Access Token",pattern:/sq0[a-z]{3}-[0-9A-Za-z_-]{22,}/g,severity:"critical",description:"Square access token detected"},{name:"Twilio API Key",pattern:/SK[a-f0-9]{32}/g,severity:"critical",description:"Twilio API key detected"},{name:"SendGrid API Key",pattern:/SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}/g,severity:"critical",description:"SendGrid API key detected"},{name:"Mailgun API Key",pattern:/key-[0-9a-zA-Z]{32}/g,severity:"critical",description:"Mailgun API key detected"},{name:"Password in Code",pattern:/(?:password|passwd|pwd)\s*[=:]\s*['"]([^'"]{8,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded password detected"},{name:"Secret/Token Assignment",pattern:/(?:secret|token|auth[_-]?token|access[_-]?token)\s*[=:]\s*['"]([A-Za-z0-9_\-/+=]{16,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded secret or token detected"},{name:"NPM Token",pattern:/(?:npm[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{36})['"]?/gi,severity:"critical",description:"NPM token detected"},{name:"SSH Private Key Path Exposed",pattern:/~\/\.ssh\/id_[a-z]+|\/home\/[^/]+\/\.ssh\/id_[a-z]+/g,severity:"medium",description:"SSH private key path exposed"},{name:"Env Variable with Secret",pattern:/(?:process\.env\.)((?=[A-Z_]*(?:SECRET|KEY|TOKEN|PASSWORD|CREDENTIAL|AUTH))[A-Z_]+)\s*(?:===?\s*['"]([^'"]+)['"])?/g,severity:"medium",description:"Environment variable containing secret may be exposed"}],mC=[".js",".jsx",".ts",".tsx",".mjs",".cjs",".vue",".svelte",".html",".htm",".css",".scss",".less",".json",".yaml",".yml",".toml",".xml",".env",".config",".conf"],gC=["node_modules",".git",".svn",".hg","dist","build","coverage",".nyc_output","__pycache__",".pytest_cache","vendor",".idea",".vscode",".turbo",".next",".nuxt","framework.bak","pantry",".pantry","tests","test","__tests__","spec","__mocks__",".github",".gitlab",".circleci"],fC=["package-lock.json","yarn.lock","pnpm-lock.yaml","bun.lockb","bun.lock","*.min.js","*.min.css","*.map","*.d.ts","*.test.ts","*.test.js","*.spec.ts","*.spec.js",".env",".env.*"];class Ur{patterns;excludeDirs;excludeFiles;maxFileSize;constructor(e){this.patterns=[...jd,...e?.customPatterns||[]],this.excludeDirs=[...gC,...e?.excludeDirs||[]],this.excludeFiles=[...fC,...e?.excludeFiles||[]],this.maxFileSize=e?.maxFileSize||1048576}async scan(e){let t=Date.now(),r=[],o=0,{directory:m,exclude:h=[],include:I,skipPatterns:R=[]}=e,A=e.failOnSeverity||"critical";if(!sC(m))throw Error(`Directory not found: ${m}`);let E=this.getFilesToScan(m,[...this.excludeDirs,...h],I);for(let H of E){let K=pC(m,H);if(this.shouldExcludeFile(K))continue;try{if(dC(H).size>this.maxFileSize)continue;let oe=cC(H,"utf-8"),ye=this.scanContent(oe,K,R);r.push(...ye),o++}catch{continue}}let x={critical:r.filter((H)=>H.pattern.severity==="critical").length,high:r.filter((H)=>H.pattern.severity==="high").length,medium:r.filter((H)=>H.pattern.severity==="medium").length,low:r.filter((H)=>H.pattern.severity==="low").length},N=["low","medium","high","critical"],F=N.indexOf(A),z=!0;for(let H=F;H<N.length;H++)if(x[N[H]]>0){z=!1;break}return{passed:z,findings:r,scannedFiles:o,duration:Date.now()-t,summary:x}}scanContent(e,t,r){let o=[],m=e.split(`
192
192
  `);for(let h of this.patterns){if(r.includes(h.name))continue;h.pattern.lastIndex=0;let I;while((I=h.pattern.exec(e))!==null){let R=e.substring(0,I.index),A=R.split(`
@@ -357,7 +357,7 @@ $(free -m 2>/dev/null | awk '/^Mem:/{total=$2; used=$3; available=$7; cache=$6}
357
357
  EOF`,'echo "MEMTOTAL=${MEMTOTAL:-0}"','echo "MEMUSED=${MEMUSED:-0}"','echo "MEMAVAILABLE=${MEMAVAILABLE:-0}"','echo "MEMCACHE=${MEMCACHE:-0}"','echo "SWAPTOTAL=${SWAPTOTAL:-0}"','echo "SWAPUSED=${SWAPUSED:-0}"',`read DISKTOTG DISKUSEDG DISKPCT <<EOF
358
358
  $(df -BG -P / 2>/dev/null | awk 'NR==2{gsub("G","",$2); gsub("G","",$3); gsub("%","",$5); print $2, $3, $5}')
359
359
  EOF`,'echo "DISKPCT=${DISKPCT:-0}"','echo "DISKUSEDG=${DISKUSEDG:-0}"','echo "DISKTOTG=${DISKTOTG:-0}"',`echo "INODEPCT=$(df -Pi / 2>/dev/null | awk 'NR==2{gsub("%","",$5);print $5}')"`,`echo "NETRX=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{sum+=$3} END{print sum+0}' /proc/net/dev 2>/dev/null)"`,`echo "NETTX=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{sum+=$11} END{print sum+0}' /proc/net/dev 2>/dev/null)"`,". /var/lib/ts-cloud/bandwidth-state 2>/dev/null || true",'echo "NETRXRATE=${RX_RATE:-0}"','echo "NETTXRATE=${TX_RATE:-0}"','echo "NETRXTODAY=${DAY_RX:-0}"','echo "NETTXTODAY=${DAY_TX:-0}"','echo "NETRXMONTH=${MONTH_RX:-0}"','echo "NETTXMONTH=${MONTH_TX:-0}"','echo "NETMONTHKEY=${MONTH_KEY:-}"',`echo "PROCESSES=$(ps -e --no-headers 2>/dev/null | awk 'END{print NR+0}')"`,`echo "UPTIME=$(uptime -p 2>/dev/null | sed 's/^up //' || echo unknown)"`,`echo "UPTIME_SECONDS=$(cut -d' ' -f1 /proc/uptime 2>/dev/null || echo 0)"`,'echo "OS=$(. /etc/os-release 2>/dev/null; echo "$PRETTY_NAME")"'];if(e.includeServices!==!1)t.push(`for s in ${BC.join(" ")}; do st=$(systemctl is-active "$s" 2>/dev/null); if [ -n "$st" ] && [ "$st" != "inactive" ] && [ "$st" != "unknown" ]; then mem=$(systemctl show "$s" -p MemoryCurrent --value 2>/dev/null); en=$(systemctl is-enabled "$s" 2>/dev/null); since=$(systemctl show "$s" -p ActiveEnterTimestamp --value 2>/dev/null); echo "SVC=$s=$st=$mem=$en=$since"; fi; done`);if(e.includeSites!==!1)t.push(LC(e.projectFilter));return t.push("true"),t}function zC(e){let t={services:[],discoveredSites:[]};for(let r of e.split(`
360
- `)){let o=r.trim();if(o.startsWith("DISCOVERED_SITE="))try{let m=JSON.parse(Buffer.from(o.slice(16),"base64").toString("utf8"));if(m?.domain&&m?.route)t.discoveredSites.push(m)}catch{}else if(o.startsWith("SVC=")){let[,m,h,I,R,A]=/^SVC=([^=]+)=([^=]+)(?:=([^=]*)(?:=([^=]*)(?:=(.*))?)?)?$/.exec(o)??[];if(m)t.services.push({name:m,status:h,memBytes:Number(I||0),enabled:R||kn,since:A||kn})}else{let m=o.indexOf("=");if(m>0)t[o.slice(0,m)]=o.slice(m+1)}}return t}function tb(e){let t=e.infrastructure?.compute,r=[];if(t?.webServer==="rpx"||t?.proxy?.engine==="rpx")r.push({name:"rpx-gateway",status:"configured"});else if(t?.webServer==="nginx"||t?.webServer==null)r.push({name:"ts-cloud-nginx",status:"configured"});let o=t?.php?.versions??(t?.runtime==="php"?["8.3"]:[]);for(let I of o)r.push({name:`php${I}-fpm`,status:"configured"});let m=t?.managedServices??{},h=[["mysql","mysql"],["mariadb","mariadb"],["postgres","postgresql"],["redis","redis"],["memcached","memcached"],["meilisearch","meilisearch"]];for(let[I,R]of h)if(m[I])r.push({name:R,status:"configured"});return r}function UC(e){let t=e.infrastructure?.compute?.backups,r=!!t?.enabled,o=t?.schedule??"0 2 * * *";return{enabled:r,schedule:o,destination:r?t?.bucket??"local":"off",retention:r?t?.retentionCount??5:0,last:r?"pending first run":"not configured",size:r?kn:"0 MB"}}function rb(e){return e.infrastructure?.compute?.provider??e.cloud?.provider??e.provider??"aws"}function qC(e){if(rb(e)==="hetzner")return Fa(e);return e.project.region??"us-east-1"}function VC(e){let t=e.infrastructure?.compute?.monitoring,r=Number(typeof t==="object"?t?.alerts?.bandwidthTb??0:0);return Number.isFinite(r)&&r>0?Math.round(r*1000000000000):0}function WC(e,t){let r=xe(g(e,t));if(!jC(r))return null;try{return JSON.parse(MC(r,"utf8"))}catch{return null}}function HC(e){let t=e.sites??{},r=[];for(let[o,m]of Object.entries(t)){let h=m.queues??m.workers;if(Array.isArray(h)){for(let I of h)if(typeof I==="string")r.push({name:`${o}:${I}`,site:o,processes:1,status:"configured"});else if(I?.name)r.push({name:`${o}:${I.name}`,site:o,processes:I.processes??1,status:"configured"})}}return r}function nb(e){if(!e||e==="")return"/";return e.startsWith("/")?e:`/${e}`}function KC(e){let t=nb(e.path);if(!e.domain)return{route:"internal"};return{route:t==="/"?e.domain:`${e.domain}${t}`,href:`https://${e.domain}${t==="/"?"":t}`}}function eb(e,t){let r=u(t);if(r==="redirect")return"redirect";if(r==="proxy")return"proxy";let o=String(t.build??"").toLowerCase(),m=String(t.start??"").toLowerCase();if(e==="main"||m.includes("buddy/src/cli.ts serve"))return"stacks";if(e==="api"||m.includes("/serve/api"))return"api";if(o.includes("buildblog"))return"bunpress blog";if(o.includes("bunpress"))return"bunpress";if(o.includes("site:build")||o.includes("stx"))return"stx static";if(r==="server-static")return t.spa?"spa":"static";if(r==="server-app")return"app";if(r==="server-php")return t.type??"php";return"bucket"}function JC(e){let t=u(e);if(t==="redirect"||t==="proxy")return"—";let r=`${e.start??""} ${e.build??""}`.toLowerCase();if(t==="server-static")return r.includes("bunpress")||r.includes("bun ")||r.includes("bunx ")?"static/bun":"static";if(t==="server-app")return r.includes("bun")?"bun":"node";if(t==="server-php")return`php ${e.php??e.phpVersion??"8.3"}`;return"static"}function GC(e){let t=u(e);if(t==="redirect")return"redirect";if(t==="proxy")return"proxy";if(t==="server-app")return"service";if(t==="server-static")return"server static";if(t==="server-php")return"php release";return"bucket"}function QC(e){let t=new Map;return Object.entries(e.sites??{}).map(([r,o])=>{let m=nb(o.path),{route:h,href:I}=KC(o),R=o.domain?`${o.domain}${m}`:"",A=R?t.get(R):void 0;if(R&&!A)t.set(R,r);return{name:r,route:h,href:I,domain:o.domain??"internal",path:m,kind:eb(r,o),type:eb(r,o),runtime:JC(o),deploy:GC(o),tls:o.domain?o.ssl===!1?"http":"https":"loopback",ssl:o.domain?o.ssl!==!1:!1,status:A?"shadowed":"live",shadowedBy:A,lastDeploy:kn}})}function YC(e,t,r){let o=new Map(e.map((m)=>[String(m.route),{...m,project:r,managedBy:"owner"}]));for(let m of t){let h=o.get(m.route),I=h?.name??`${m.project}:${m.name}`;o.set(m.route,{...h,...m,name:I,kind:h?.kind??m.kind,type:h?.type??m.kind,runtime:h?.runtime??m.runtime,deploy:h?.deploy??m.deploy,root:h?.root??m.root,branch:h?.branch??m.branch,managedBy:m.project===r?"owner":"attached"})}return[...o.values()].sort((m,h)=>{if(m.managedBy!==h.managedBy)return m.managedBy==="owner"?-1:1;return String(m.route).localeCompare(String(h.route))})}function yg(e){return`'${e.replaceAll("'","'\\''")}'`}function ib(e){return e.replace(/[\\&/]/g,"\\$&")}function ZC(e,t){if(e.length===0)return["true"];return["set +e",...e.map((r)=>{let o=yg(`${B(t,r)}/.ts-cloud/deploy-history.log`),m=ib(r);return`TS_CLOUD_HISTORY=${o}; { [ -f "$TS_CLOUD_HISTORY" ] && tail -n 24 "$TS_CLOUD_HISTORY" | sed "s/^/DEPLOY=${m}\\t/"; } || true`}),"true"]}function ob(e){return[...new Set(Object.values(e.sites??{}).map((t)=>t.domain).filter((t)=>typeof t==="string"&&t.length>0))]}function XC(e){return["set +e",'if command -v ss >/dev/null 2>&1; then ss -H -lntup 2>/dev/null | while read -r proto _state _recv _send local _peer rest; do [ -n "$proto" ] && [ -n "$local" ] && printf "PORT=%s\\t%s\\t%s\\n" "$proto" "$local" "$rest"; done; fi','if command -v ufw >/dev/null 2>&1; then ufw status numbered 2>/dev/null | sed "s/^/FIREWALL=/"; else echo "FIREWALL=ufw unavailable"; fi','journalctl _COMM=sshd --no-pager -n 30 -o short-iso 2>/dev/null | sed "s/^/AUTH=/" || true',...ob(e).map((r)=>`TS_CLOUD_DOMAIN=${yg(r)}; TS_CLOUD_EXPIRY=$(echo | timeout 8 openssl s_client -servername "$TS_CLOUD_DOMAIN" -connect "$TS_CLOUD_DOMAIN:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2-); [ -n "$TS_CLOUD_EXPIRY" ] && printf "CERT=%s\\t%s\\n" "$TS_CLOUD_DOMAIN" "$TS_CLOUD_EXPIRY" || printf "CERT=%s\\tunavailable\\n" "$TS_CLOUD_DOMAIN"`),"true"]}function eP(e){let t=new Map,r=(h,I)=>{if(h&&I&&!t.has(I))t.set(I,{pattern:h,label:I})},o=e.infrastructure?.compute,m=e.project.slug;if(o?.webServer==="rpx"||o?.proxy?.engine==="rpx")r("rpx-gateway","rpx-gateway");else r("nginx","nginx");for(let h of tb(e))r(h.name,h.name);for(let[h,I]of Object.entries(e.sites??{})){if(u(I)!=="server-app")continue;if(r(`${m}-${h}`,`${m}-${h}`),Array.isArray(I.queues??I.workers)&&(I.queues??I.workers).length)r(`${m}-${h}-queue-*`,`${m}-${h}-queues`);if(Array.isArray(I.daemons)&&I.daemons.length)r(`${m}-${h}-daemon-*`,`${m}-${h}-daemons`)}return[...t.values()]}function tP(e){let t=eP(e);if(t.length===0)return["true"];return["set +e",...t.map((r)=>{let o=yg(r.pattern),m=ib(r.label);return`journalctl -u ${o} --no-pager -n 150 -o short-iso 2>/dev/null | sed "s/^/LOG=${m}\\t/" || true`}),'[ -f /var/log/ts-cloud-backup.log ] && tail -n 60 /var/log/ts-cloud-backup.log 2>/dev/null | sed "s/^/LOG=backups\\t/" || true',"true"]}function vg(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return e||kn;let r=Math.max(0,Math.round((Date.now()-t.getTime())/1000));if(r<60)return`${r}s ago`;let o=Math.round(r/60);if(o<60)return`${o}m ago`;let m=Math.round(o/60);if(m<48)return`${m}h ago`;return`${Math.round(m/24)}d ago`}function sb(e){if(/(?:error|failed|panic|fatal|exception|denied|unhealthy)/i.test(e))return"error";if(/(?:warn|warning|retry|restart|deprecated|timeout)/i.test(e))return"warn";return"info"}function rP(e){let t=[];for(let r of e.split(`
360
+ `)){let o=r.trim();if(o.startsWith("DISCOVERED_SITE="))try{let m=JSON.parse(Buffer.from(o.slice(16),"base64").toString("utf8"));if(m?.domain&&m?.route)t.discoveredSites.push(m)}catch{}else if(o.startsWith("SVC=")){let[,m,h,I,R,A]=/^SVC=([^=]+)=([^=]+)(?:=([^=]*)(?:=([^=]*)(?:=(.*))?)?)?$/.exec(o)??[];if(m)t.services.push({name:m,status:h,memBytes:Number(I||0),enabled:R||kn,since:A||kn})}else{let m=o.indexOf("=");if(m>0)t[o.slice(0,m)]=o.slice(m+1)}}return t}function tb(e){let t=e.infrastructure?.compute,r=[];if(t?.webServer==="rpx"||t?.proxy?.engine==="rpx")r.push({name:"rpx-gateway",status:"configured"});else if(t?.webServer==="nginx"||t?.webServer==null)r.push({name:"ts-cloud-nginx",status:"configured"});let o=t?.php?.versions??(t?.runtime==="php"?["8.3"]:[]);for(let I of o)r.push({name:`php${I}-fpm`,status:"configured"});let m=t?.managedServices??{},h=[["mysql","mysql"],["mariadb","mariadb"],["postgres","postgresql"],["redis","redis"],["memcached","memcached"],["meilisearch","meilisearch"]];for(let[I,R]of h)if(m[I])r.push({name:R,status:"configured"});return r}function UC(e){let t=e.infrastructure?.compute?.backups,r=!!t?.enabled,o=t?.schedule??"0 2 * * *";return{enabled:r,schedule:o,destination:r?t?.bucket??"local":"off",retention:r?t?.retentionCount??5:0,last:r?"pending first run":"not configured",size:r?kn:"0 MB"}}function rb(e){return e.infrastructure?.compute?.provider??e.cloud?.provider??e.provider??"aws"}function qC(e){if(rb(e)==="hetzner")return Fa(e);return e.project.region??"us-east-1"}function VC(e){let t=e.infrastructure?.compute?.monitoring,r=Number(typeof t==="object"?t?.alerts?.bandwidthTb??0:0);return Number.isFinite(r)&&r>0?Math.round(r*1000000000000):0}function WC(e,t){let r=_e(g(e,t));if(!jC(r))return null;try{return JSON.parse(MC(r,"utf8"))}catch{return null}}function HC(e){let t=e.sites??{},r=[];for(let[o,m]of Object.entries(t)){let h=m.queues??m.workers;if(Array.isArray(h)){for(let I of h)if(typeof I==="string")r.push({name:`${o}:${I}`,site:o,processes:1,status:"configured"});else if(I?.name)r.push({name:`${o}:${I.name}`,site:o,processes:I.processes??1,status:"configured"})}}return r}function nb(e){if(!e||e==="")return"/";return e.startsWith("/")?e:`/${e}`}function KC(e){let t=nb(e.path);if(!e.domain)return{route:"internal"};return{route:t==="/"?e.domain:`${e.domain}${t}`,href:`https://${e.domain}${t==="/"?"":t}`}}function eb(e,t){let r=u(t);if(r==="redirect")return"redirect";if(r==="proxy")return"proxy";let o=String(t.build??"").toLowerCase(),m=String(t.start??"").toLowerCase();if(e==="main"||m.includes("buddy/src/cli.ts serve"))return"stacks";if(e==="api"||m.includes("/serve/api"))return"api";if(o.includes("buildblog"))return"bunpress blog";if(o.includes("bunpress"))return"bunpress";if(o.includes("site:build")||o.includes("stx"))return"stx static";if(r==="server-static")return t.spa?"spa":"static";if(r==="server-app")return"app";if(r==="server-php")return t.type??"php";return"bucket"}function JC(e){let t=u(e);if(t==="redirect"||t==="proxy")return"—";let r=`${e.start??""} ${e.build??""}`.toLowerCase();if(t==="server-static")return r.includes("bunpress")||r.includes("bun ")||r.includes("bunx ")?"static/bun":"static";if(t==="server-app")return r.includes("bun")?"bun":"node";if(t==="server-php")return`php ${e.php??e.phpVersion??"8.3"}`;return"static"}function GC(e){let t=u(e);if(t==="redirect")return"redirect";if(t==="proxy")return"proxy";if(t==="server-app")return"service";if(t==="server-static")return"server static";if(t==="server-php")return"php release";return"bucket"}function QC(e){let t=new Map;return Object.entries(e.sites??{}).map(([r,o])=>{let m=nb(o.path),{route:h,href:I}=KC(o),R=o.domain?`${o.domain}${m}`:"",A=R?t.get(R):void 0;if(R&&!A)t.set(R,r);return{name:r,route:h,href:I,domain:o.domain??"internal",path:m,kind:eb(r,o),type:eb(r,o),runtime:JC(o),deploy:GC(o),tls:o.domain?o.ssl===!1?"http":"https":"loopback",ssl:o.domain?o.ssl!==!1:!1,status:A?"shadowed":"live",shadowedBy:A,lastDeploy:kn}})}function YC(e,t,r){let o=new Map(e.map((m)=>[String(m.route),{...m,project:r,managedBy:"owner"}]));for(let m of t){let h=o.get(m.route),I=h?.name??`${m.project}:${m.name}`;o.set(m.route,{...h,...m,name:I,kind:h?.kind??m.kind,type:h?.type??m.kind,runtime:h?.runtime??m.runtime,deploy:h?.deploy??m.deploy,root:h?.root??m.root,branch:h?.branch??m.branch,managedBy:m.project===r?"owner":"attached"})}return[...o.values()].sort((m,h)=>{if(m.managedBy!==h.managedBy)return m.managedBy==="owner"?-1:1;return String(m.route).localeCompare(String(h.route))})}function yg(e){return`'${e.replaceAll("'","'\\''")}'`}function ib(e){return e.replace(/[\\&/]/g,"\\$&")}function ZC(e,t){if(e.length===0)return["true"];return["set +e",...e.map((r)=>{let o=yg(`${B(t,r)}/.ts-cloud/deploy-history.log`),m=ib(r);return`TS_CLOUD_HISTORY=${o}; { [ -f "$TS_CLOUD_HISTORY" ] && tail -n 24 "$TS_CLOUD_HISTORY" | sed "s/^/DEPLOY=${m}\\t/"; } || true`}),"true"]}function ob(e){return[...new Set(Object.values(e.sites??{}).map((t)=>t.domain).filter((t)=>typeof t==="string"&&t.length>0))]}function XC(e){return["set +e",'if command -v ss >/dev/null 2>&1; then ss -H -lntup 2>/dev/null | while read -r proto _state _recv _send local _peer rest; do [ -n "$proto" ] && [ -n "$local" ] && printf "PORT=%s\\t%s\\t%s\\n" "$proto" "$local" "$rest"; done; fi','if command -v ufw >/dev/null 2>&1; then ufw status numbered 2>/dev/null | sed "s/^/FIREWALL=/"; else echo "FIREWALL=ufw unavailable"; fi','journalctl _COMM=sshd --no-pager -n 30 -o short-iso 2>/dev/null | sed "s/^/AUTH=/" || true',...ob(e).map((r)=>`TS_CLOUD_DOMAIN=${yg(r)}; TS_CLOUD_EXPIRY=$(echo | timeout 8 openssl s_client -servername "$TS_CLOUD_DOMAIN" -connect "$TS_CLOUD_DOMAIN:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2-); [ -n "$TS_CLOUD_EXPIRY" ] && printf "CERT=%s\\t%s\\n" "$TS_CLOUD_DOMAIN" "$TS_CLOUD_EXPIRY" || printf "CERT=%s\\tunavailable\\n" "$TS_CLOUD_DOMAIN"`),"true"]}function eP(e){let t=new Map,r=(h,I)=>{if(h&&I&&!t.has(I))t.set(I,{pattern:h,label:I})},o=e.infrastructure?.compute,m=e.project.slug;if(o?.webServer==="rpx"||o?.proxy?.engine==="rpx")r("rpx-gateway","rpx-gateway");else r("nginx","nginx");for(let h of tb(e))r(h.name,h.name);for(let[h,I]of Object.entries(e.sites??{})){if(u(I)!=="server-app")continue;if(r(`${m}-${h}`,`${m}-${h}`),Array.isArray(I.queues??I.workers)&&(I.queues??I.workers).length)r(`${m}-${h}-queue-*`,`${m}-${h}-queues`);if(Array.isArray(I.daemons)&&I.daemons.length)r(`${m}-${h}-daemon-*`,`${m}-${h}-daemons`)}return[...t.values()]}function tP(e){let t=eP(e);if(t.length===0)return["true"];return["set +e",...t.map((r)=>{let o=yg(r.pattern),m=ib(r.label);return`journalctl -u ${o} --no-pager -n 150 -o short-iso 2>/dev/null | sed "s/^/LOG=${m}\\t/" || true`}),'[ -f /var/log/ts-cloud-backup.log ] && tail -n 60 /var/log/ts-cloud-backup.log 2>/dev/null | sed "s/^/LOG=backups\\t/" || true',"true"]}function vg(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return e||kn;let r=Math.max(0,Math.round((Date.now()-t.getTime())/1000));if(r<60)return`${r}s ago`;let o=Math.round(r/60);if(o<60)return`${o}m ago`;let m=Math.round(o/60);if(m<48)return`${m}h ago`;return`${Math.round(m/24)}d ago`}function sb(e){if(/(?:error|failed|panic|fatal|exception|denied|unhealthy)/i.test(e))return"error";if(/(?:warn|warning|retry|restart|deprecated|timeout)/i.test(e))return"warn";return"info"}function rP(e){let t=[];for(let r of e.split(`
361
361
  `)){let o=r.trim();if(!o.startsWith("LOG="))continue;let m=o.indexOf("\t");if(m<0)continue;let h=o.slice(4,m),I=o.slice(m+1),R=/^(\d{4}-\d{2}-\d{2}T[^\s]+)\s+(\S+)\s+(.*)$/.exec(I),A=R?.[1]??"",E=R?.[2]??"",x=(R?.[3]??I).trim();if(!x)continue;t.push({source:h,timestamp:A,when:A?vg(A):kn,host:E,message:x,level:sb(x)})}return t.sort((r,o)=>String(o.timestamp).localeCompare(String(r.timestamp))).slice(0,600)}function ab(e){if(/^(?:127\.|localhost:|\[?::1\]?)/.test(e))return"loopback";if(/^(?:10\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.|169\.254\.|\[?f[cd][0-9a-f:])/i.test(e))return"private";return"public"}function nP(e){if(ab(e)!=="public")return"ok";if(/:(?:22|80|443)$/.test(e)||/^\*:(?:22|80|443)$/.test(e))return"ok";return"warn"}function iP(e){if(e==null)return"warn";if(e<8)return"bad";if(e<30)return"warn";return"ok"}function oP(e){let t=[],r=[],o=[],m=[];for(let R of e.split(`
362
362
  `)){let A=R.trim();if(A.startsWith("PORT=")){let[E="",x="",N=""]=A.slice(5).split("\t");if(E&&x)t.push({proto:E,listen:x,processName:N||kn,exposure:ab(x),tone:nP(x)})}else if(A.startsWith("FIREWALL=")){let E=A.slice(9).trim();if(E)r.push(E)}else if(A.startsWith("AUTH=")){let E=A.slice(5),x=/^(\d{4}-\d{2}-\d{2}T[^\s]+)\s+(\S+)\s+(.*)$/.exec(E),N=(x?.[3]??E).trim();if(N)o.push({timestamp:x?.[1]??"",when:x?.[1]?vg(x[1]):kn,host:x?.[2]??"",message:N,level:sb(N)})}else if(A.startsWith("CERT=")){let[E="",x=""]=A.slice(5).split("\t");if(!E)continue;let N=new Date(x),F=Number.isNaN(N.getTime())?null:Math.ceil((N.getTime()-Date.now())/86400000);m.push({domain:E,expires:Number.isNaN(N.getTime())?x||kn:N.toISOString().slice(0,10),daysRemaining:F,status:iP(F)})}}let h=r.some((R)=>/Status:\s*active/i.test(R)),I=r.some((R)=>/unavailable/i.test(R));return{ports:t.slice(0,80),firewall:{status:h?"active":I?"unavailable":"inactive",summary:h?"ufw active":I?"ufw unavailable":"ufw inactive or not configured",rules:r.filter((R)=>R&&!/^Status:/i.test(R)).slice(0,60)},tlsCertificates:m,authEvents:o.sort((R,A)=>String(A.timestamp).localeCompare(String(R.timestamp))).slice(0,30)}}function bg(e){let r=e.infrastructure?.compute?.firewall??{},o=[...new Set([22,80,443,...r.allowedPorts??[]])],m=ob(e);return{ports:o.map((h)=>({proto:"tcp",listen:`0.0.0.0:${h}`,processName:"configured firewall",exposure:"public",tone:[22,80,443].includes(Number(h))?"ok":"warn"})),firewall:{status:r.enabled===!1?"disabled":"configured",summary:r.enabled===!1?"host firewall disabled in config":"host firewall configured declaratively",rules:o.map((h)=>`ALLOW ${h}/tcp`)},tlsCertificates:m.map((h)=>({domain:h,expires:kn,daysRemaining:null,status:"warn"})),authEvents:[]}}function cb(e,t){let r=t.security??bg(e),o=!!t._serverReachable&&!t.metricsUnavailable,m=t.sites??[],h=m.filter((E)=>E.status==="shadowed"),I=(t.services??[]).filter((E)=>["failed","stopped"].includes(E.status)),R=(r.tlsCertificates??[]).filter((E)=>E.status!=="ok"),A=t.sshKeys??[];return[{name:"Live server probe",status:o?"pass":"warn",detail:o?"Metrics and remote checks are coming from the compute box.":"The dashboard is rendering config/state data until the box probe succeeds."},{name:"Managed services",status:I.length?"fail":"pass",detail:I.length?`${I.length} service(s) need attention.`:`${(t.services??[]).length} service(s) reported healthy or configured.`},{name:"Route conflicts",status:h.length?"warn":"pass",detail:h.length?`${h.map((E)=>E.name).join(", ")} is shadowed by an earlier route.`:`${m.length} site route(s) are unshadowed.`},{name:"SSH access",status:A.length?"pass":"warn",detail:A.length?`${A.length} declarative authorized key(s) configured.`:"No declarative SSH keys are configured."},{name:"Firewall",status:["active","configured"].includes(r.firewall?.status)?"pass":"warn",detail:r.firewall?.summary??"Firewall status unavailable."},{name:"TLS certificates",status:R.length?"warn":"pass",detail:R.length?`${R.length} certificate(s) need renewal visibility.`:`${(r.tlsCertificates??[]).length} certificate(s) look healthy.`}]}function db(e){let t=[];for(let r of e.serverDeploymentsDetail??e.serverDeployments??[])t.push({type:"deploy",tone:r.status==="failed"?"bad":"ok",title:`${r.site} deployed ${r.sha}`,detail:`${r.branch} · ${r.status}`,when:r.when,timestamp:r.timestamp});for(let r of e.serverLogs??[])if(r.level==="error"||r.level==="warn")t.push({type:"log",tone:r.level==="error"?"bad":"warn",title:`${r.source} ${r.level}`,detail:r.message,when:r.when,timestamp:r.timestamp});for(let r of e.sshKeys??[])t.push({type:"ssh",tone:"ok",title:`${r.name} authorized`,detail:r.fingerprint,when:r.added??kn,timestamp:""});return t.sort((r,o)=>String(o.timestamp).localeCompare(String(r.timestamp))).slice(0,80)}function sP(e,t={}){let r=[];for(let o of e.split(`
363
363
  `)){let m=o.trim();if(!m.startsWith("DEPLOY="))continue;let h=m.split("\t"),I=h[0]?.replace(/^DEPLOY=/,"")??"",[R,A,E,x,N]=h.slice(1);if(!I||!R||!A)continue;let F=t[I]??{},z=u(F),H=(E||A).slice(0,7);r.push({sha:H,release:A,commit:E||A,site:I,branch:F.branch??(z==="server-static"?"build artifact":"main"),status:x||"unknown",when:vg(R),timestamp:R,took:"-",by:"ts-cloud",rc:N?.replace(/^rc=/,"")??"",steps:z==="server-static"?["upload artifact","publish static files"]:["upload artifact","restart service"]})}return r.sort((o,m)=>String(m.timestamp).localeCompare(String(o.timestamp)))}function aP(e,t){let r=WC(e,t),o=tb(e),m=QC(e),h=Math.max(1,Number(e.infrastructure?.compute?.disk?.size??1)),I={server:{name:r?.serverName??`${e.project.slug}-${t}-app`,provider:r?.provider??rb(e),region:qC(e),ip:r?.publicIp??kn,os:"Linux",uptime:kn,probeStatus:"unavailable"},systemMetrics:{load:0,load5:0,load15:0,cpuUsedPct:0,cpus:Math.max(1,Number(e.infrastructure?.compute?.instances??1)),memUsedMb:0,memTotalMb:0,memAvailableMb:0,memCacheMb:0,swapUsedMb:0,swapTotalMb:0,diskUsedPct:0,diskUsedGb:0,diskTotalGb:h,inodeUsedPct:0,networkRxBytes:0,networkTxBytes:0,networkRxBytesPerSec:0,networkTxBytesPerSec:0,networkRxBytesToday:0,networkTxBytesToday:0,networkRxBytesMonth:0,networkTxBytesMonth:0,networkMonthKey:"",processes:0,uptimeSeconds:0},metricsUnavailable:!0,bandwidthBudgetBytes:VC(e),services:o,servicesDetail:o.map((R)=>({...R,since:kn,memMb:0,auto:!0})),backup:UC(e),backupHistory:[],workers:HC(e),serverScheduler:{enabled:!1,lastRun:"not configured"},serverDeployments:[],serverDeploymentsDetail:[],deploymentsEmptyReason:"No deployment history has been recorded yet. Future server deploys will write /var/www/<site>/.ts-cloud/deploy-history.log.",serverLogs:[],serverLogsEmptyReason:"Live server logs are unavailable until the dashboard can reach the compute box.",security:bg(e),securityEmptyReason:"Live security checks are unavailable until the dashboard can reach the compute box.",sites:m,sitesDetail:m.map((R)=>{let A=e.sites?.[R.name]??{},E=u(A);return{...R,root:E==="server-static"?B(e.project.slug,R.name):`${B(e.project.slug,R.name)}/current`,branch:E==="server-static"?"build artifact":"main",build:A.build,php:A.php??A.phpVersion,aliases:Array.isArray(A.aliases)?A.aliases:[],redirects:A.redirects&&typeof A.redirects==="object"?A.redirects:{},envKeys:Object.keys(A.env??A.environment??{})}}),siteHealth:[],sshKeys:gs(e.infrastructure?.compute?.sshKeys??[]),_serverReachable:!1,_metricsStatus:"unavailable"};return I.diagnostics=cb(e,I),I.activity=db(I),I.topology=ft(I,{project:e.project.name,environment:t}),I}async function Su(e,t,r={}){if(!e.infrastructure?.compute)return null;let o=null;try{o=k({config:e})}catch{o=null}let m=null,h=0,I=[];if(o)try{if(I=await o.findComputeTargets({slug:e.project.slug,environment:t,role:"app"}),h=I.length,I.length){let N=(await o.runRemoteDeploy({targets:[I[0]],commands:FC({includeServices:!r.telemetryOnly,includeSites:r.includeSiteHealth!==!1,projectFilter:e.cloud?.attachTo?e.project.slug:void 0}),comment:`ts-cloud dashboard:build ${e.project.slug}`,tags:{Project:e.project.slug,Environment:t,Role:"app"}})).perInstance?.[0]?.output;if(N)m=zC(N)}}catch{}let R=aP(e,t),A=(x,N=0)=>{let F=Number(x);return Number.isFinite(F)?F:N};if(R.server.os=m?.OS||R.server.os,R.server.uptime=m?.UPTIME||R.server.uptime,m){if(R.server.probeStatus="live",R.metricsUnavailable=!1,R._metricsStatus="live",R.systemMetrics={load:A(m.LOAD),load5:A(m.LOAD5),load15:A(m.LOAD15),cpuUsedPct:A(m.CPUUSED),cpus:A(m.CPUS,1),memUsedMb:A(m.MEMUSED),memTotalMb:A(m.MEMTOTAL,1),memAvailableMb:A(m.MEMAVAILABLE),memCacheMb:A(m.MEMCACHE),swapUsedMb:A(m.SWAPUSED),swapTotalMb:A(m.SWAPTOTAL),diskUsedPct:A(m.DISKPCT),diskUsedGb:A(m.DISKUSEDG),diskTotalGb:A(m.DISKTOTG,1),inodeUsedPct:A(m.INODEPCT),networkRxBytes:A(m.NETRX),networkTxBytes:A(m.NETTX),networkRxBytesPerSec:A(m.NETRXRATE),networkTxBytesPerSec:A(m.NETTXRATE),networkRxBytesToday:A(m.NETRXTODAY),networkTxBytesToday:A(m.NETTXTODAY),networkRxBytesMonth:A(m.NETRXMONTH),networkTxBytesMonth:A(m.NETTXMONTH),networkMonthKey:m.NETMONTHKEY||"",processes:A(m.PROCESSES),uptimeSeconds:A(m.UPTIME_SECONDS)},m.services.length){let x=[...new Map(m.services.map((N)=>[N.name,N])).values()];R.services=x.map((N)=>({name:N.name,status:N.status==="active"?"running":N.status})),R.servicesDetail=x.map((N)=>({name:N.name,status:N.status==="active"?"running":N.status,since:N.since&&N.since!==kn?N.since:R.server.uptime,memMb:Math.max(0,Math.round(Number(N.memBytes??0)/1024/1024)),auto:N.enabled?!["disabled","static","masked"].includes(N.enabled):!0}))}if(m.discoveredSites.length)R.sitesDetail=YC(R.sitesDetail,m.discoveredSites,e.project.slug),R.sites=R.sitesDetail.map((x)=>({name:x.name,project:x.project,managedBy:x.managedBy,route:x.route,href:x.href,domain:x.domain,path:x.path,kind:x.kind,type:x.type,runtime:x.runtime,deploy:x.deploy,tls:x.tls,status:x.status,httpStatus:x.httpStatus,responseMs:x.responseMs,tlsDaysRemaining:x.tlsDaysRemaining,checkedAt:x.checkedAt})),R.siteHealth=R.sitesDetail.map((x)=>({name:x.name,project:x.project,route:x.route,status:x.status,httpStatus:x.httpStatus,responseMs:x.responseMs,tlsDaysRemaining:x.tlsDaysRemaining,checkedAt:x.checkedAt}))}if(o&&I.length&&!r.telemetryOnly)await Promise.all([(async()=>{try{let x=Object.keys(e.sites??{}),F=(await o.runRemoteDeploy({targets:[I[0]],commands:ZC(x,e.project.slug),comment:`ts-cloud dashboard:deploy-history ${e.project.slug}`,tags:{Project:e.project.slug,Environment:t,Role:"app"}})).perInstance?.[0]?.output??"",z=sP(F,e.sites);R.serverDeployments=z.slice(0,5),R.serverDeploymentsDetail=z.slice(0,50),R.deploymentsEmptyReason=z.length?void 0:"No deployment history was found on the server yet. Deploy again to populate this timeline."}catch{R.deploymentsEmptyReason="Deployment history could not be read from the server."}})(),(async()=>{try{let N=(await o.runRemoteDeploy({targets:[I[0]],commands:tP(e),comment:`ts-cloud dashboard:server-logs ${e.project.slug}`,tags:{Project:e.project.slug,Environment:t,Role:"app"}})).perInstance?.[0]?.output??"",F=rP(N);R.serverLogs=F,R.serverLogsEmptyReason=F.length?void 0:"No recent journal entries were found for the managed server units."}catch{R.serverLogsEmptyReason="Server logs could not be read from the box."}})(),(async()=>{try{let N=(await o.runRemoteDeploy({targets:[I[0]],commands:XC(e),comment:`ts-cloud dashboard:security ${e.project.slug}`,tags:{Project:e.project.slug,Environment:t,Role:"app"}})).perInstance?.[0]?.output??"",F=oP(N),z=bg(e);if(!F.ports.length)F.ports=z.ports;if(!F.tlsCertificates.length)F.tlsCertificates=z.tlsCertificates;R.security=F,R.securityEmptyReason=void 0}catch{R.securityEmptyReason="Server security checks could not be read from the box."}})()]);else if(o&&h===0)R.deploymentsEmptyReason="No app server target was found for this environment.";let E=e.infrastructure?.compute?.sshKeys??e.infrastructure?.ssh?.keys??e.infrastructure?.sshKeys;if(Array.isArray(E)&&E.length)R.sshKeys=gs(E);return R._serverReachable=h>0&&!!m,R.diagnostics=cb(e,R),R.activity=db(R),R.topology=ft(R,{project:e.project.name,environment:t}),R}var cP=new Set(["singlestore","vitess"]);function Eu(e){return cP.has(e)}var Iu={mysql:"/var/lib/pantry/mysql/mysqld.sock",mariadb:"/var/lib/pantry/mariadb/mariadbd.sock"};function Yi(e){return/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(e)}function dP(e){if(e==="postgres"||e==="pgsql")return"postgres";if(e==="mariadb")return"mariadb";if(e==="singlestore")return"singlestore";if(e==="vitess")return"vitess";return"mysql"}function qs(e){let t=e.infrastructure?.compute,r=p(e)?.engine;if(r)return dP(r);let o=t?.managedServices??{};if(o.postgres)return"postgres";if(o.mariadb)return"mariadb";return"mysql"}var Sg=(e)=>e.replace(/`/g,"``"),ui=(e)=>e.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),zs=(e)=>`"${e.replace(/"/g,'""')}"`,ku=(e)=>`'${e.replace(/'/g,"''")}'`;function wg(e,t){return[`mysql --socket=${e==="mariadb"?Iu.mariadb:Iu.mysql} -u root <<'TS_CLOUD_SQL_EOF'`,...t,"TS_CLOUD_SQL_EOF"]}function kg(e,t){return[`${Rt(t)} -tA <<'TS_CLOUD_PG_EOF'`,...e,"TS_CLOUD_PG_EOF"]}function lP(e,t){if(e==="vitess")return uP(t);if(e==="postgres")return kg(["SELECT 'DB=' || datname FROM pg_database WHERE datistemplate = false;","SELECT 'USER=' || usename FROM pg_user;"],t);return wg(e,["SELECT CONCAT('DB=', schema_name) FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');","SELECT DISTINCT CONCAT('USER=', User) FROM mysql.user WHERE User NOT IN ('root', 'mysql.sys', 'mysql.session', 'mysql.infoschema', 'debian-sys-maint');"])}function za(e,t,r){let o=t?.host??"127.0.0.1",m=t?.username??"root",h=t?.password??"",I=t?.ssl===!1?"":" --ssl-mode=PREFERRED",R=(E)=>`'${String(E).replace(/'/g,"'\\''")}'`;return[`${h?`MYSQL_PWD=${R(h)} `:""}mysql -h ${R(o)} -P ${t?.port??r} -u ${R(m)}${I} --batch --skip-column-names <<'TS_CLOUD_SQL_EOF'`,...e,"TS_CLOUD_SQL_EOF"]}var Ua=15306;function uP(e){let t=za(["SHOW KEYSPACES;"],e,Ua);return t[0]=`${t[0]} | sed 's/^/DB=/'`,t}function pP(e){return za(["SHOW KEYSPACES;","SHOW VITESS_SHARDS;","SHOW VITESS_TABLETS;"],e,Ua)}function mP(e){let t=[],r=[],o=[];for(let m of e.split(`
@@ -655,7 +655,7 @@ EOF`,'echo "DISKPCT=${DISKPCT:-0}"','echo "DISKUSEDG=${DISKUSEDG:-0}"','echo "DI
655
655
  },
656
656
  ${A}`}class Dg{client;region;constructor(e="us-east-1"){this.region=e,this.client=new n}async getTraceSummaries(e){let t={StartTime:Math.floor(e.startTime.getTime()/1000),EndTime:Math.floor(e.endTime.getTime()/1000),TimeRangeType:"Event",Sampling:!1};if(e.filterExpression)t.FilterExpression=e.filterExpression;if(e.nextToken)t.NextToken=e.nextToken;let r=await this.client.request({service:"xray",region:this.region,method:"POST",path:"/TraceSummaries",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});return{summaries:r?.TraceSummaries??[],nextToken:r?.NextToken}}async batchGetTraces(e){if(!e.length)return[];return(await this.client.request({service:"xray",region:this.region,method:"POST",path:"/Traces",headers:{"Content-Type":"application/json"},body:JSON.stringify({TraceIds:e.slice(0,5)})}))?.Traces??[]}}var iS=65536;function gn(e){return e.length<=iS?e:`${e.slice(0,iS)}
657
657
 
658
- [output truncated]`}function $g(e,t){return e.environments?.[t]?.app}function Ng(e,t,r){let o=[],m=$g(e,t);o.push({id:"redeploy",label:"Redeploy current build",group:"deploy",target:"app",mutates:!0,confirm:"redeploy"}),o.push({id:"rollback",label:"Roll back to previous build",group:"deploy",target:"app",mutates:!0,confirm:"rollback",danger:!0});let h=r.maintenance?.enabled;if(h!==!0)o.push({id:"maintenance:on",label:"Enable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"maintenance",danger:!0});if(h!==!1)o.push({id:"maintenance:off",label:"Disable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"live"});if(m?.assets||r.assetsInfo)o.push({id:"assets:invalidate",label:"Invalidate CDN cache",group:"assets",target:"assets",mutates:!0,confirm:"invalidate"});if(m?.database?.connection==="aurora-serverless")o.push({id:"db:scale",label:"Scale Aurora capacity",group:"database",target:"database",mutates:!0,confirm:"scale",inputs:[{name:"min",label:"Min ACUs",placeholder:String(m.database.minCapacity??0.5)},{name:"max",label:"Max ACUs",placeholder:String(m.database.maxCapacity??4)}]});for(let I of r.queues??[]){let R=String(I?.name??"").trim();if(R&&/^[A-Za-z0-9_-]+$/.test(R))o.push({id:`queue:purge:${R}`,label:`Purge queue (${R})`,group:"queue",target:R,mutates:!0,confirm:R,danger:!0})}return o}function oS(e,t,r,o){return Ng(t,r,o).find((m)=>m.id===e)}async function f_(e,t,r){try{let o=new f(r),{Stacks:m}=await o.describeStacks({stackName:Mt(e,t)}),h={};for(let A of m?.[0]?.Outputs??[])if(A.OutputKey)h[A.OutputKey]=A.OutputValue??"";let I=h.AssetsCdnDomain;if(!I)return null;return(await new y(r).findDistributionByDomain(I))?.Id??null}catch{return null}}async function sS(e,t,r,o={}){try{if(r.id==="redeploy")return await Kr(e,t),{operation:r.id,command:"serverless redeploy",ok:!0,stdout:"Redeploy complete."};if(r.id==="rollback")return await Wr(e,t),{operation:r.id,command:"serverless rollback",ok:!0,stdout:"Rollback complete."};if(r.id==="maintenance:on")return await Wt(e,t,!0),{operation:r.id,command:"maintenance on",ok:!0,stdout:"Application is now in maintenance mode."};if(r.id==="maintenance:off")return await Wt(e,t,!1),{operation:r.id,command:"maintenance off",ok:!0,stdout:"Application is live."};if(r.id==="db:scale"){let m=Number(o.min),h=Number(o.max);if(!Number.isFinite(m)||!Number.isFinite(h)||m<=0||h<m)return{operation:r.id,ok:!1,error:"Provide valid Aurora capacities (0 < min ≤ max)."};return await Nf(e,t,m,h),{operation:r.id,command:`db:scale ${m}-${h} ACU`,ok:!0,stdout:`Scaling applied (${m}-${h} ACUs); takes effect shortly.`}}if(r.id==="assets:invalidate"){let m=await Nr(e,t),h=await f_(e,t,m.region);if(!h)return{operation:r.id,ok:!1,error:"Could not resolve the asset CloudFront distribution for this environment."};let R=await new y(m.region).invalidateAll(h);return{operation:r.id,command:`cloudfront invalidate ${h} /*`,ok:!0,stdout:`Invalidation ${R?.Id??"created"} for ${h} (/*).`}}if(r.group==="queue"&&r.id.startsWith("queue:purge:")){let m=r.target,h=await Nr(e,t),I=new re(h.region),R=`${h.slug}-${t}-${m}`,{QueueUrl:A}=await I.getQueueUrl(R);return await I.purgeQueue(A),{operation:r.id,command:`sqs purge ${R}`,ok:!0,stdout:`Purged queue ${R}.`}}return{operation:r.id,ok:!1,error:"Unknown or unavailable serverless operation."}}catch(m){return{operation:r.id,ok:!1,error:gn(m?.message??String(m))}}}async function aS(e,t,r){let o=r.trim();if(!o)return{operation:"command",ok:!1,error:"A command is required."};try{let m=await ze(e,t,o);return{operation:"command",command:o,ok:!0,stdout:gn(m||"(no output)")}}catch(m){return{operation:"command",command:o,ok:!1,error:gn(m?.message??String(m))}}}var Mg="No dead-letter queue is provisioned for this environment.";async function Bg(e,t,r){try{let{QueueUrl:o}=await e.getQueueUrl(`${t}-${r}-dlq`);return o}catch{return null}}async function cS(e,t,r=10){try{let o=await Nr(e,t),m=new re(o.region),h=await Bg(m,o.slug,t);if(!h)return{ok:!1,messages:[],error:Mg};return{ok:!0,messages:((await m.receiveMessages({queueUrl:h,maxMessages:Math.min(10,Math.max(1,r)),waitTimeSeconds:1,visibilityTimeout:2})).Messages??[]).map((A)=>({id:A.MessageId,receiptHandle:A.ReceiptHandle,body:gn(String(A.Body??""))}))}}catch(o){return{ok:!1,messages:[],error:gn(o?.message??String(o))}}}async function dS(e,t,r={}){try{let o=await Nr(e,t),m=$g(e,t),I=(m?Gt(m,o.slug,t):[]).map((z)=>z.name.replace(`${o.slug}-${t}-`,"")),R=r.targetQueue&&I.includes(r.targetQueue)?r.targetQueue:I[0];if(!R)return{operation:"dlq:redrive",ok:!1,error:"No source queue is configured to redrive into."};let A=new re(o.region),E=await Bg(A,o.slug,t);if(!E)return{operation:"dlq:redrive",ok:!1,error:Mg};let{QueueUrl:x}=await A.getQueueUrl(`${o.slug}-${t}-${R}`),N=Math.min(50,Math.max(1,r.max??10)),F=0;while(F<N){let H=(await A.receiveMessages({queueUrl:E,maxMessages:Math.min(10,N-F),waitTimeSeconds:1,visibilityTimeout:30})).Messages??[];if(!H.length)break;for(let K of H)await A.sendMessage({queueUrl:x,messageBody:String(K.Body??"")}),await A.deleteMessage(E,K.ReceiptHandle),F++}return{operation:"dlq:redrive",command:`redrive → ${R}`,ok:!0,stdout:`Moved ${F} message(s) from the DLQ to ${R}.`}}catch(o){return{operation:"dlq:redrive",ok:!1,error:gn(o?.message??String(o))}}}async function lS(e,t){try{let r=await Nr(e,t),o=new re(r.region),m=await Bg(o,r.slug,t);if(!m)return{operation:"dlq:purge",ok:!1,error:Mg};return await o.purgeQueue(m),{operation:"dlq:purge",command:"sqs purge dlq",ok:!0,stdout:"Dead-letter queue purged."}}catch(r){return{operation:"dlq:purge",ok:!1,error:gn(r?.message??String(r))}}}function uS(e,t){let r=$g(e,t);if(!r?.secrets)return[];return Array.isArray(r.secrets)?r.secrets.map((o)=>({key:o.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),secretId:o})):Object.entries(r.secrets).map(([o,m])=>({key:o,secretId:String(m)}))}async function pS(e,t,r,o){if(!r.trim())return{operation:"secret:set",ok:!1,error:"A secret id is required."};try{let m=await Nr(e,t),h=new V(m.region);try{await h.putSecretValue({SecretId:r,SecretString:o})}catch{await h.createSecret({Name:r,SecretString:o})}return{operation:"secret:set",command:`secret set ${r}`,ok:!0,stdout:`Secret ${r} updated. Redeploy to apply it to the functions.`}}catch(m){return{operation:"secret:set",ok:!1,error:gn(m?.message??String(m))}}}async function mS(e,t,r){if(!r.trim())return{operation:"secret:delete",ok:!1,error:"A secret id is required."};try{let o=await Nr(e,t);return await new V(o.region).deleteSecret({SecretId:r,RecoveryWindowInDays:7}),{operation:"secret:delete",command:`secret delete ${r}`,ok:!0,stdout:`Secret ${r} scheduled for deletion (recoverable for 7 days).`}}catch(o){return{operation:"secret:delete",ok:!1,error:gn(o?.message??String(o))}}}var h_=new Set(["http","queue","cli"]);async function gS(e,t,r,o){if(!h_.has(r))return{operation:"function:config",ok:!1,error:`Unknown function mode '${r}'.`};let m=o.memory==null?void 0:Number(o.memory),h=o.timeout==null?void 0:Number(o.timeout);if(m!=null&&(!Number.isInteger(m)||m<128||m>10240))return{operation:"function:config",ok:!1,error:"Memory must be an integer between 128 and 10240 MB."};if(h!=null&&(!Number.isInteger(h)||h<1||h>900))return{operation:"function:config",ok:!1,error:"Timeout must be an integer between 1 and 900 seconds."};if(m==null&&h==null)return{operation:"function:config",ok:!1,error:"Provide a memory and/or timeout value."};try{let I=await Nr(e,t),R=new C(I.region),A=`${I.slug}-${t}-${r}`;await R.updateFunctionConfiguration({FunctionName:A,...m!=null?{MemorySize:m}:{},...h!=null?{Timeout:h}:{}});let E=[m!=null?`${m} MB`:"",h!=null?`${h}s`:""].filter(Boolean).join(", ");return{operation:"function:config",command:`update ${A} (${E})`,ok:!0,stdout:`Updated ${A}: ${E}.`}}catch(I){return{operation:"function:config",ok:!1,error:gn(I?.message??String(I))}}}var Og=[{key:"http-errors",label:"HTTP function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"errors / 5 min"},{key:"http-throttles",label:"HTTP function throttles",namespace:"AWS/Lambda",metricName:"Throttles",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"throttles / 5 min"},{key:"http-duration",label:"HTTP function duration (avg)",namespace:"AWS/Lambda",metricName:"Duration",statistic:"Average",comparison:"GreaterThanThreshold",fnMode:"http",unit:"ms"},{key:"http-concurrency",label:"HTTP concurrent executions",namespace:"AWS/Lambda",metricName:"ConcurrentExecutions",statistic:"Maximum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"concurrent"},{key:"queue-errors",label:"Queue function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"queue",unit:"errors / 5 min"}];function y_(e){return Og.find((t)=>t.key===e)}async function fS(e,t){try{let r=await Nr(e,t);return{ok:!0,alarms:await new hi(r.region).describeAlarms({AlarmNamePrefix:`${r.slug}-${t}-`,MaxRecords:100}),presets:Og}}catch(r){return{ok:!1,alarms:[],presets:Og,error:gn(r?.message??String(r))}}}async function hS(e,t,r,o){let m=y_(r);if(!m)return{operation:"alarm:create",ok:!1,error:`Unknown alarm metric '${r}'.`};if(!Number.isFinite(o)||o<0)return{operation:"alarm:create",ok:!1,error:"Provide a non-negative threshold."};try{let h=await Nr(e,t),I=new hi(h.region),R=`${h.slug}-${t}-${m.key}`,A=m.fnMode?[{Name:"FunctionName",Value:`${h.slug}-${t}-${m.fnMode}`}]:[];return await I.putMetricAlarm({AlarmName:R,Namespace:m.namespace,MetricName:m.metricName,ComparisonOperator:m.comparison,Threshold:o,EvaluationPeriods:1,Period:300,Statistic:m.statistic,Dimensions:A,AlarmDescription:`ts-cloud: ${m.label} > ${o} ${m.unit}`}),{operation:"alarm:create",command:`alarm ${R}`,ok:!0,stdout:`Alarm ${R} armed at ${o} ${m.unit}.`}}catch(h){return{operation:"alarm:create",ok:!1,error:gn(h?.message??String(h))}}}async function yS(e,t,r){try{let o=await Nr(e,t);if(!r.startsWith(`${o.slug}-${t}-`))return{operation:"alarm:delete",ok:!1,error:"Refusing to delete an alarm outside this environment."};return await new hi(o.region).deleteAlarms([r]),{operation:"alarm:delete",command:`delete alarm ${r}`,ok:!0,stdout:`Alarm ${r} deleted.`}}catch(o){return{operation:"alarm:delete",ok:!1,error:gn(o?.message??String(o))}}}function v_(e){let t=e.HasFault?"fault":e.HasError?"error":e.HasThrottle?"throttle":"ok";return{id:String(e.Id??""),timestamp:Number.isFinite(Number(e.StartTime))?new Date(Number(e.StartTime)*1000).toISOString():void 0,durationMs:Math.round((e.Duration??0)*1000),responseMs:Math.round((e.ResponseTime??0)*1000),status:t,method:e.Http?.HttpMethod??"-",url:e.Http?.HttpURL??"-",httpStatus:e.Http?.HttpStatus??0}}async function ju(e,t,r=30){try{let o=await Nr(e,t),m=new Dg(o.region),h=new Date,I=new Date(h.getTime()-Math.min(360,Math.max(1,r))*60000),R=`${o.slug}-${t}-http`,A=await m.getTraceSummaries({startTime:I,endTime:h,filterExpression:`service("${R}")`});if(!A.summaries.length)A=await m.getTraceSummaries({startTime:I,endTime:h});return{ok:!0,traces:A.summaries.slice(0,100).map(v_)}}catch(o){return{ok:!1,traces:[],error:gn(o?.message??String(o))}}}async function Lg(e,t,r){try{let o=await Nr(e,t),m=`${o.slug}-${t}-scheduler`;if(r==="run"){let I=await ze(e,t,"schedule:run");return{operation:"scheduler:run",command:"schedule:run",ok:!0,stdout:gn(I||"Scheduler run triggered.")}}let h=new Zt(o.region);if(r==="enable")await h.enableRule({Name:m});else await h.disableRule({Name:m});return{operation:`scheduler:${r}`,command:`${r} ${m}`,ok:!0,stdout:`Scheduler rule ${m} ${r}d.`}}catch(o){return{operation:`scheduler:${r}`,ok:!1,error:gn(o?.message??String(o))}}}function vS(e,t,r){let o=(Array.isArray(r)?r:String(r??"").split(",")).map(String).filter(Boolean);if(!o.length){if(t)return;let h=e.map((I)=>I.id);return h.length?h:["__no_authorized_telemetry_resources__"]}let m=o.map((h)=>e.find((I)=>I.id===h||I.slug===h)?.id).filter((h)=>!!h);if(m.length!==o.length)throw Error("One or more telemetry resources are outside your authorized scope.");return[...new Set(m)]}import{createHash as SS}from"node:crypto";class wS{now;entries=new Map;constructor(e=Date.now){this.now=e}async getOrCreate(e,t,r,o){let m=this.entries.get(e);if(!r&&m&&m.expiresAt>this.now())return{value:await m.promise,cached:!0};let h=o().catch((I)=>{throw this.entries.delete(e),I});return this.entries.set(e,{expiresAt:this.now()+t,promise:h}),{value:await h,cached:!1}}invalidate(e){for(let t of this.entries.keys())if(t.startsWith(e))this.entries.delete(t)}}class kS{now;lastRun=new Map;constructor(e=Date.now){this.now=e}shouldRun(e,t,r=!1){let o=this.now(),m=this.lastRun.get(e);if(!r&&m!=null&&o-m<t)return!1;return this.lastRun.set(e,o),!0}}var IS=new wS,b_=new kS,S_=2000,w_=3600000;function k_(e,t){if(e.kind==="log"&&!t.collectLogs)return!1;if(e.kind==="trace"&&!t.collectTraces)return!1;if((e.kind==="request"||e.name.startsWith("request."))&&!t.collectRequestAnalytics)return!1;if(!["log","trace","request"].includes(e.kind)&&!e.name.startsWith("request."))return!0;let r=e.requestId??e.traceId??`${e.source}\x00${e.workloadId??""}\x00${e.timestamp}`;return Number.parseInt(SS("sha256").update(r).digest("hex").slice(0,8),16)/4294967295<=t.samplingRate}function fn(...e){return`telemetry:${SS("sha256").update(e.map((t)=>String(t??"")).join("\x00")).digest("hex").slice(0,40)}`}function Ac(e,t,r,o){if(!o)return;return e.listResources(t,r).find((m)=>m.slug===o)?.id}function I_(e,t){let r=String(t??"").toLowerCase();if(["debug","info","warn","warning","error","fatal"].includes(r))return r==="fatal"?"error":r;return/fatal|panic|exception|error/i.test(e)?"error":/warn|timeout|throttl|retr(?:y|ies)/i.test(e)?"warning":"info"}function bS(e){let t=e.timestamp&&Number.isFinite(new Date(e.timestamp).getTime())?new Date(e.timestamp).toISOString():new Date().toISOString(),r={};try{let K=JSON.parse(e.message);if(K&&typeof K==="object"&&!Array.isArray(K))r=K}catch{}let o=Object.fromEntries(Object.entries(r).filter(([K])=>!/^(?:body|requestBody|responseBody|headers|authorization|cookie|cookies|query|queryString)$/i.test(K))),m=String(r.requestId??r.request_id??r["x-request-id"]??"")||void 0,h=String(r.traceId??r.trace_id??r["x-amzn-trace-id"]??"")||void 0,I=Number(r.durationMs??r.duration_ms??r.latencyMs??r.latency_ms),R=Number(r.statusCode??r.status_code??r.status),A=String(r.method??r.httpMethod??"")||void 0,E=ai(String(r.pathTemplate??r.path??r.url??"")||void 0),x=String(r.releaseId??r.release_id??"")||void 0,N=String(r.deploymentId??r.deployment_id??"")||void 0,F={projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,source:e.source,timestamp:t,requestId:m,traceId:h,releaseId:x,deploymentId:N,workloadId:e.workloadId},z=Object.keys(r).length?JSON.stringify(o):e.message,H=[{...F,id:fn(e.source,e.name,t,z),kind:"log",name:e.name,level:I_(z,r.level),message:z,attributes:o}];if(A&&E&&Number.isFinite(R)){if(H.push({...F,id:fn("request",m,t,A,E,R),kind:"request",name:"http.request",method:A,pathTemplate:E,host:r.host,statusCode:R,durationMs:Number.isFinite(I)?I:void 0,bytesIn:Number(r.bytesIn)||void 0,bytesOut:Number(r.bytesOut)||void 0,region:r.region,cacheResult:r.cacheResult??r.cache,upstream:r.upstream,attributes:{userAgentFamily:r.userAgentFamily??"",protocol:r.protocol??""}}),Number.isFinite(I))H.push({...F,id:fn("request-duration",m,t),kind:"metric",name:"request.duration",value:I,unit:"ms",attributes:{method:A,pathTemplate:E,statusCode:R}});if(H.push({...F,id:fn("request-count",m,t),kind:"metric",name:"request.count",value:1,unit:"count",attributes:{method:A,pathTemplate:E,statusCode:R}}),R>=500)H.push({...F,id:fn("request-error",m,t),kind:"metric",name:"request.error",value:1,unit:"count",attributes:{method:A,pathTemplate:E,statusCode:R}})}return H}async function E_(e){let t=new at(e.controlPlane),r=$t(e.controlPlane,e.projectId),o=new Date,m=[],h=[],I={projectId:e.projectId,environmentId:e.environmentId},R=O(e.config);try{let F=(R==="serverless"?await Jr(e.config,e.environment):await Su(e.config,e.environment,{includeSiteHealth:e.includeSiteHealth,telemetryOnly:e.lightweight}))??{};if(R==="serverless"){for(let H of F.functionsDetail??[]){let K=Ac(e.controlPlane,e.projectId,e.environmentId,H.key),X={...I,resourceId:K,source:"cloudwatch",timestamp:o.toISOString(),workloadId:H.name,attributes:{provider:"aws",functionName:H.name,aggregationWindow:"24h"}};for(let[oe,ye,ne]of[["snapshot.traffic.requests_24h",H.invocations,"count"],["snapshot.errors.count_24h",H.errors,"count"],["snapshot.latency.p50_24h",H.p50,"ms"],["snapshot.latency.p95_24h",H.p95,"ms"],["snapshot.latency.p99_24h",H.p99,"ms"],["snapshot.saturation.throttles_24h",H.throttles,"count"],["snapshot.memory.max_24h",H.maxMem,"MB"]])if(Number.isFinite(Number(ye)))m.push({...X,id:fn("cloudwatch",H.name,oe,o.toISOString()),kind:"metric",name:oe,value:Number(ye),unit:ne})}try{let H=await Nr(e.config,e.environment),K=new hi(H.region),X=new Date(o.getTime()-3600000),oe=300;for(let ye of H.functions){let ne=[{Name:"FunctionName",Value:ye.name}],[fe,Ce,_e,he,Ue]=await Promise.all([K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Sum"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Errors",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Sum"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:ne,StartTime:X,EndTime:o,Period:300,ExtendedStatistics:["p50","p95","p99"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Throttles",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Sum"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"ConcurrentExecutions",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Maximum"]})]),me=Ac(e.controlPlane,e.projectId,e.environmentId,ye.mode),We=(nt,wt,cr,st)=>{for(let Ft of nt){let dr=Ft.Timestamp&&Number.isFinite(new Date(Ft.Timestamp).getTime())?new Date(Ft.Timestamp).toISOString():void 0,vt=cr(Ft);if(dr&&vt!=null&&Number.isFinite(vt))m.push({...I,resourceId:me,id:fn("cloudwatch-series",ye.name,wt,dr),kind:"metric",source:"cloudwatch",name:wt,timestamp:dr,value:vt,unit:st,workloadId:ye.name,region:H.region,attributes:{provider:"aws",functionName:ye.name,aggregationWindow:"300s"}})}};We(fe,"traffic.requests",(nt)=>nt.Sum,"count"),We(Ce,"errors.count",(nt)=>nt.Sum,"count"),We(_e,"latency.p50",(nt)=>nt.Percentiles?.p50,"ms"),We(_e,"latency.p95",(nt)=>nt.Percentiles?.p95,"ms"),We(_e,"latency.p99",(nt)=>nt.Percentiles?.p99,"ms"),We(he,"saturation.throttles",(nt)=>nt.Sum,"count"),We(Ue,"saturation.concurrency",(nt)=>nt.Maximum,"count")}}catch(H){h.push({source:"cloudwatch:series",message:H instanceof Error?H.message:String(H)})}for(let H of(F.serverlessLogs??[]).slice(0,S_))m.push(...bS({...I,source:`cloudwatch:${H.source}`,name:`${H.source}.log`,timestamp:H.timestamp,message:String(H.message),resourceId:Ac(e.controlPlane,e.projectId,e.environmentId,H.source)}));for(let H of F.queuesDetail??[]){let K={...I,source:"cloudwatch",timestamp:o.toISOString(),attributes:{queue:H.name}};m.push({...K,id:fn("queue-depth",H.name,o.toISOString()),kind:"metric",name:"queue.depth",value:Number(H.visible??H.depth??0),unit:"count"}),m.push({...K,id:fn("queue-inflight",H.name,o.toISOString()),kind:"metric",name:"queue.inflight",value:Number(H.inFlight??0),unit:"count"})}let z=await ju(e.config,e.environment,30);if(!z.ok)h.push({source:"xray",message:z.error??"X-Ray traces are unavailable."});for(let H of z.traces)m.push({...I,id:fn("xray",H.id),kind:"trace",source:"xray",name:"http.trace",timestamp:H.timestamp??o.toISOString(),traceId:H.id,durationMs:H.durationMs,statusCode:H.httpStatus,method:H.method,pathTemplate:H.url,attributes:{status:H.status,responseMs:H.responseMs}})}else{let z=F.systemMetrics;if(F.metricsUnavailable||!z)h.push({source:"host",message:"The host metrics probe is unavailable."});else{let H=Number(z.memTotalMb)>0?Number(z.memUsedMb)/Number(z.memTotalMb)*100:0,K=Number(z.swapTotalMb)>0?Number(z.swapUsedMb)/Number(z.swapTotalMb)*100:0,X=[["host.load",Number(z.load),"load"],["host.load.5m",Number(z.load5),"load"],["host.load.15m",Number(z.load15),"load"],["host.cpu.capacity",Number(z.cpus),"count"],["host.cpu.used_percent",Number(z.cpuUsedPct),"percent"],["host.memory.used",Number(z.memUsedMb)*1024*1024,"bytes"],["host.memory.total",Number(z.memTotalMb)*1024*1024,"bytes"],["host.memory.available",Number(z.memAvailableMb)*1024*1024,"bytes"],["host.memory.cache",Number(z.memCacheMb)*1024*1024,"bytes"],["host.memory.used_percent",H,"percent"],["host.swap.used",Number(z.swapUsedMb)*1024*1024,"bytes"],["host.swap.total",Number(z.swapTotalMb)*1024*1024,"bytes"],["host.swap.used_percent",K,"percent"],["host.disk.used_percent",Number(z.diskUsedPct),"percent"],["host.disk.used",Number(z.diskUsedGb)*1073741824,"bytes"],["host.disk.total",Number(z.diskTotalGb)*1073741824,"bytes"],["host.disk.inode_used_percent",Number(z.inodeUsedPct),"percent"],["host.network.rx",Number(z.networkRxBytes),"bytes"],["host.network.tx",Number(z.networkTxBytes),"bytes"],["host.network.rx_rate",Number(z.networkRxBytesPerSec),"bytes_per_second"],["host.network.tx_rate",Number(z.networkTxBytesPerSec),"bytes_per_second"],["host.network.rx_today",Number(z.networkRxBytesToday),"bytes"],["host.network.tx_today",Number(z.networkTxBytesToday),"bytes"],["host.network.rx_month",Number(z.networkRxBytesMonth),"bytes"],["host.network.tx_month",Number(z.networkTxBytesMonth),"bytes"],["host.processes",Number(z.processes),"count"],["host.uptime",Number(z.uptimeSeconds),"seconds"]];for(let[oe,ye,ne]of X)if(Number.isFinite(ye))m.push({...I,id:fn("host",oe,o.toISOString()),kind:"metric",source:"host",name:oe,timestamp:o.toISOString(),value:ye,unit:ne});for(let oe of F.siteHealth??[]){let ye=String(oe.project??e.config.project.slug),ne=String(oe.name),fe=ne.startsWith(`${ye}:`)?ne.slice(ye.length+1):ne,Ce=`site:${ye}:${fe}`,_e=Ac(e.controlPlane,e.projectId,e.environmentId,ne),he={...I,resourceId:_e,source:Ce,timestamp:oe.checkedAt||o.toISOString(),host:oe.route,attributes:{project:ye,site:fe,route:String(oe.route),status:String(oe.status)}},Ue=[["site.health.up",oe.status==="live"?1:0,"boolean"],["site.http.status",Number(oe.httpStatus),"status"],["site.response.time",Number(oe.responseMs),"ms"]];if(oe.tlsDaysRemaining!=null)Ue.push(["site.tls.days_remaining",Number(oe.tlsDaysRemaining),"days"]);for(let[me,We,nt]of Ue)if(Number.isFinite(We))m.push({...he,id:fn(Ce,me,he.timestamp),kind:"metric",name:me,value:We,unit:nt})}}}}catch(F){h.push({source:R==="serverless"?"aws":"host",message:F instanceof Error?F.message:String(F)})}{let F=e.config.infrastructure?.compute?.monitoring,z=typeof F==="object"?F?.egressEndpoints:void 0,H=await Zo(z,{now:o.toISOString()});h.push(...H.errors);for(let K of H.metrics)m.push({...I,id:fn(K.attributes.source,K.name,K.timestamp),kind:"metric",source:`egress:${K.attributes.source}`,name:K.name,timestamp:K.timestamp,value:K.value,unit:K.unit,attributes:K.attributes})}if(!e.lightweight)try{let F=await te(e.config,e.environment),z=new le(e.config,e.environment,{inventory:async()=>F});for(let H of F.workloads){let K=Ac(e.controlPlane,e.projectId,e.environmentId,H.links.service),X={...I,resourceId:K,source:`runtime:${H.provider}`,timestamp:o.toISOString(),workloadId:H.id,releaseId:H.links.release,attributes:{status:H.status,provider:H.provider,service:H.links.service??""}};if(m.push({...X,id:fn(H.id,"health",o.toISOString()),kind:"metric",name:"health.up",value:H.status==="running"?1:0,unit:"boolean"}),m.push({...X,id:fn(H.id,"restarts",o.toISOString()),kind:"metric",name:"saturation.restarts",value:H.restartCount??0,unit:"count"}),H.resources?.memoryBytes!=null)m.push({...X,id:fn(H.id,"memory",o.toISOString()),kind:"metric",name:"runtime.memory.used",value:H.resources.memoryBytes,unit:"bytes"});if(!H.capabilities.logs.supported)continue;try{let oe=await z.logs(H.id,{limit:100,since:new Date(o.getTime()-300000)});for(let ye of oe.lines)m.push(...bS({...I,resourceId:K,source:`runtime:${H.provider}`,name:`${H.links.service??H.name}.log`,timestamp:ye.timestamp,message:ye.message,workloadId:H.id}))}catch(oe){h.push({source:`runtime:${H.provider}`,message:oe instanceof Error?oe.message:String(oe)})}}for(let H of F.sources.filter((K)=>K.status!=="fresh"))h.push({source:H.id,message:H.message??`Runtime source is ${H.status}.`})}catch(F){h.push({source:"runtime",message:F instanceof Error?F.message:String(F)})}if(!e.lightweight)for(let F of e.controlPlane.listEvents({projectId:e.projectId,limit:1000})){let z=F.payload;m.push({...I,id:`telemetry:event:${F.id}`,resourceId:F.resourceId,kind:"event",source:"control-plane",name:F.type,timestamp:F.createdAt,level:F.level,message:F.type,deploymentId:F.operationId,releaseId:typeof z.releaseId==="string"?z.releaseId:void 0,traceId:F.correlationId,attributes:z})}let A=m.filter((F)=>k_(F,r)).map((F)=>({...F,sampled:r.samplingRate<1&&(F.kind==="log"||F.kind==="trace"||F.kind==="request"||F.name.startsWith("request."))})),E=t.appendMany(A).length;if(b_.shouldRun(e.projectId,w_,!e.lightweight))t.enforceRetention(r,e.projectId);let x=t.status(e.projectId,e.environmentId,r.rawDays,r.samplingRate);for(let F of h)if(!x.some((z)=>z.source===F.source))x.push({source:F.source,freshness:"unavailable",samplingRate:r.samplingRate,retentionDays:r.rawDays,estimatedDailyBytes:0,message:F.message});let N=o.toISOString();return e.controlPlane.setSetting(`telemetry.collection:${e.projectId}:${e.environmentId??"all"}`,{generatedAt:N,errors:h,statuses:x,policy:r}),{collected:E,cached:!1,generatedAt:N,statuses:x,errors:h,policy:r}}async function Fg(e){let r=`${`${e.projectId}:${e.environmentId??"all"}:${e.environment}`}:${e.lightweight?"lightweight":"full"}`,o=O(e.config)==="serverless"?300000:60000,m=await IS.getOrCreate(r,o,!!e.force,()=>E_(e));return{...m.value,cached:m.cached}}function ES(e){IS.invalidate(`${e}:`)}function RS(e,t={}){let r=t.shell||(process.platform==="win32"?"powershell.exe":"bash"),o=Bun.spawn([r,"-i"],{stdin:"pipe",stdout:"pipe",stderr:"pipe",cwd:t.cwd,env:{...process.env,TERM:"xterm-256color",PS1:"\\w $ "}}),m=new TextDecoder,h=async(I)=>{if(!I)return;let R=I.getReader();try{for(;;){let{done:A,value:E}=await R.read();if(A)break;if(E)e(m.decode(E))}}catch{}};if(h(o.stdout),h(o.stderr),t.onExit)o.exited.then((I)=>t.onExit(I)).catch(()=>{});return{write(I){try{o.stdin.write(I),o.stdin.flush()}catch{}},close(){try{o.stdin.end()}catch{}try{o.kill()}catch{}}}}var D_="127.0.0.1",O_=7676,CS=65536,BS="ts-cloud-dashboard-",Ja=A_(x_(import.meta.url));function $_(e){try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function N_(e=Lu(),t=$_){let r=0;for(let o of AS(e,{withFileTypes:!0})){if(!o.isDirectory()||!o.name.startsWith(BS))continue;let m=rr(e,o.name),h=o.name.match(/^ts-cloud-dashboard-(\d+)-/);if(h){let I=Number(h[1]);if(I===process.pid||t(I))continue}else if(AS(m).length>0)continue;Gs(m,{recursive:!0,force:!0}),r+=1}return r}var j_={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".ico":"image/x-icon"};function M(e,t=200,r={}){return new Response(JSON.stringify(e,null,2),{status:t,headers:{"content-type":"application/json; charset=utf-8",...r}})}function M_(e,t,r,o){let m=new TextEncoder,h=Math.max(0,Math.floor(r)),I,R,A=!1,E=new ReadableStream({start(x){let N=()=>{if(A)return;if(A=!0,I?.(),R)clearInterval(R);o.removeEventListener("abort",N);try{x.close()}catch{}},F=(H)=>{if(A)return;if(H.reset)x.enqueue(m.encode(`event: reset
658
+ [output truncated]`}function $g(e,t){return e.environments?.[t]?.app}function Ng(e,t,r){let o=[],m=$g(e,t);o.push({id:"redeploy",label:"Redeploy current build",group:"deploy",target:"app",mutates:!0,confirm:"redeploy"}),o.push({id:"rollback",label:"Roll back to previous build",group:"deploy",target:"app",mutates:!0,confirm:"rollback",danger:!0});let h=r.maintenance?.enabled;if(h!==!0)o.push({id:"maintenance:on",label:"Enable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"maintenance",danger:!0});if(h!==!1)o.push({id:"maintenance:off",label:"Disable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"live"});if(m?.assets||r.assetsInfo)o.push({id:"assets:invalidate",label:"Invalidate CDN cache",group:"assets",target:"assets",mutates:!0,confirm:"invalidate"});if(m?.database?.connection==="aurora-serverless")o.push({id:"db:scale",label:"Scale Aurora capacity",group:"database",target:"database",mutates:!0,confirm:"scale",inputs:[{name:"min",label:"Min ACUs",placeholder:String(m.database.minCapacity??0.5)},{name:"max",label:"Max ACUs",placeholder:String(m.database.maxCapacity??4)}]});for(let I of r.queues??[]){let R=String(I?.name??"").trim();if(R&&/^[A-Za-z0-9_-]+$/.test(R))o.push({id:`queue:purge:${R}`,label:`Purge queue (${R})`,group:"queue",target:R,mutates:!0,confirm:R,danger:!0})}return o}function oS(e,t,r,o){return Ng(t,r,o).find((m)=>m.id===e)}async function f_(e,t,r){try{let o=new f(r),{Stacks:m}=await o.describeStacks({stackName:Mt(e,t)}),h={};for(let A of m?.[0]?.Outputs??[])if(A.OutputKey)h[A.OutputKey]=A.OutputValue??"";let I=h.AssetsCdnDomain;if(!I)return null;return(await new y(r).findDistributionByDomain(I))?.Id??null}catch{return null}}async function sS(e,t,r,o={}){try{if(r.id==="redeploy")return await Kr(e,t),{operation:r.id,command:"serverless redeploy",ok:!0,stdout:"Redeploy complete."};if(r.id==="rollback")return await Wr(e,t),{operation:r.id,command:"serverless rollback",ok:!0,stdout:"Rollback complete."};if(r.id==="maintenance:on")return await Wt(e,t,!0),{operation:r.id,command:"maintenance on",ok:!0,stdout:"Application is now in maintenance mode."};if(r.id==="maintenance:off")return await Wt(e,t,!1),{operation:r.id,command:"maintenance off",ok:!0,stdout:"Application is live."};if(r.id==="db:scale"){let m=Number(o.min),h=Number(o.max);if(!Number.isFinite(m)||!Number.isFinite(h)||m<=0||h<m)return{operation:r.id,ok:!1,error:"Provide valid Aurora capacities (0 < min ≤ max)."};return await Nf(e,t,m,h),{operation:r.id,command:`db:scale ${m}-${h} ACU`,ok:!0,stdout:`Scaling applied (${m}-${h} ACUs); takes effect shortly.`}}if(r.id==="assets:invalidate"){let m=await Nr(e,t),h=await f_(e,t,m.region);if(!h)return{operation:r.id,ok:!1,error:"Could not resolve the asset CloudFront distribution for this environment."};let R=await new y(m.region).invalidateAll(h);return{operation:r.id,command:`cloudfront invalidate ${h} /*`,ok:!0,stdout:`Invalidation ${R?.Id??"created"} for ${h} (/*).`}}if(r.group==="queue"&&r.id.startsWith("queue:purge:")){let m=r.target,h=await Nr(e,t),I=new re(h.region),R=`${h.slug}-${t}-${m}`,{QueueUrl:A}=await I.getQueueUrl(R);return await I.purgeQueue(A),{operation:r.id,command:`sqs purge ${R}`,ok:!0,stdout:`Purged queue ${R}.`}}return{operation:r.id,ok:!1,error:"Unknown or unavailable serverless operation."}}catch(m){return{operation:r.id,ok:!1,error:gn(m?.message??String(m))}}}async function aS(e,t,r){let o=r.trim();if(!o)return{operation:"command",ok:!1,error:"A command is required."};try{let m=await Ke(e,t,o);return{operation:"command",command:o,ok:!0,stdout:gn(m||"(no output)")}}catch(m){return{operation:"command",command:o,ok:!1,error:gn(m?.message??String(m))}}}var Mg="No dead-letter queue is provisioned for this environment.";async function Bg(e,t,r){try{let{QueueUrl:o}=await e.getQueueUrl(`${t}-${r}-dlq`);return o}catch{return null}}async function cS(e,t,r=10){try{let o=await Nr(e,t),m=new re(o.region),h=await Bg(m,o.slug,t);if(!h)return{ok:!1,messages:[],error:Mg};return{ok:!0,messages:((await m.receiveMessages({queueUrl:h,maxMessages:Math.min(10,Math.max(1,r)),waitTimeSeconds:1,visibilityTimeout:2})).Messages??[]).map((A)=>({id:A.MessageId,receiptHandle:A.ReceiptHandle,body:gn(String(A.Body??""))}))}}catch(o){return{ok:!1,messages:[],error:gn(o?.message??String(o))}}}async function dS(e,t,r={}){try{let o=await Nr(e,t),m=$g(e,t),I=(m?Gt(m,o.slug,t):[]).map((z)=>z.name.replace(`${o.slug}-${t}-`,"")),R=r.targetQueue&&I.includes(r.targetQueue)?r.targetQueue:I[0];if(!R)return{operation:"dlq:redrive",ok:!1,error:"No source queue is configured to redrive into."};let A=new re(o.region),E=await Bg(A,o.slug,t);if(!E)return{operation:"dlq:redrive",ok:!1,error:Mg};let{QueueUrl:x}=await A.getQueueUrl(`${o.slug}-${t}-${R}`),N=Math.min(50,Math.max(1,r.max??10)),F=0;while(F<N){let H=(await A.receiveMessages({queueUrl:E,maxMessages:Math.min(10,N-F),waitTimeSeconds:1,visibilityTimeout:30})).Messages??[];if(!H.length)break;for(let K of H)await A.sendMessage({queueUrl:x,messageBody:String(K.Body??"")}),await A.deleteMessage(E,K.ReceiptHandle),F++}return{operation:"dlq:redrive",command:`redrive → ${R}`,ok:!0,stdout:`Moved ${F} message(s) from the DLQ to ${R}.`}}catch(o){return{operation:"dlq:redrive",ok:!1,error:gn(o?.message??String(o))}}}async function lS(e,t){try{let r=await Nr(e,t),o=new re(r.region),m=await Bg(o,r.slug,t);if(!m)return{operation:"dlq:purge",ok:!1,error:Mg};return await o.purgeQueue(m),{operation:"dlq:purge",command:"sqs purge dlq",ok:!0,stdout:"Dead-letter queue purged."}}catch(r){return{operation:"dlq:purge",ok:!1,error:gn(r?.message??String(r))}}}function uS(e,t){let r=$g(e,t);if(!r?.secrets)return[];return Array.isArray(r.secrets)?r.secrets.map((o)=>({key:o.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),secretId:o})):Object.entries(r.secrets).map(([o,m])=>({key:o,secretId:String(m)}))}async function pS(e,t,r,o){if(!r.trim())return{operation:"secret:set",ok:!1,error:"A secret id is required."};try{let m=await Nr(e,t),h=new V(m.region);try{await h.putSecretValue({SecretId:r,SecretString:o})}catch{await h.createSecret({Name:r,SecretString:o})}return{operation:"secret:set",command:`secret set ${r}`,ok:!0,stdout:`Secret ${r} updated. Redeploy to apply it to the functions.`}}catch(m){return{operation:"secret:set",ok:!1,error:gn(m?.message??String(m))}}}async function mS(e,t,r){if(!r.trim())return{operation:"secret:delete",ok:!1,error:"A secret id is required."};try{let o=await Nr(e,t);return await new V(o.region).deleteSecret({SecretId:r,RecoveryWindowInDays:7}),{operation:"secret:delete",command:`secret delete ${r}`,ok:!0,stdout:`Secret ${r} scheduled for deletion (recoverable for 7 days).`}}catch(o){return{operation:"secret:delete",ok:!1,error:gn(o?.message??String(o))}}}var h_=new Set(["http","queue","cli"]);async function gS(e,t,r,o){if(!h_.has(r))return{operation:"function:config",ok:!1,error:`Unknown function mode '${r}'.`};let m=o.memory==null?void 0:Number(o.memory),h=o.timeout==null?void 0:Number(o.timeout);if(m!=null&&(!Number.isInteger(m)||m<128||m>10240))return{operation:"function:config",ok:!1,error:"Memory must be an integer between 128 and 10240 MB."};if(h!=null&&(!Number.isInteger(h)||h<1||h>900))return{operation:"function:config",ok:!1,error:"Timeout must be an integer between 1 and 900 seconds."};if(m==null&&h==null)return{operation:"function:config",ok:!1,error:"Provide a memory and/or timeout value."};try{let I=await Nr(e,t),R=new C(I.region),A=`${I.slug}-${t}-${r}`;await R.updateFunctionConfiguration({FunctionName:A,...m!=null?{MemorySize:m}:{},...h!=null?{Timeout:h}:{}});let E=[m!=null?`${m} MB`:"",h!=null?`${h}s`:""].filter(Boolean).join(", ");return{operation:"function:config",command:`update ${A} (${E})`,ok:!0,stdout:`Updated ${A}: ${E}.`}}catch(I){return{operation:"function:config",ok:!1,error:gn(I?.message??String(I))}}}var Og=[{key:"http-errors",label:"HTTP function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"errors / 5 min"},{key:"http-throttles",label:"HTTP function throttles",namespace:"AWS/Lambda",metricName:"Throttles",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"throttles / 5 min"},{key:"http-duration",label:"HTTP function duration (avg)",namespace:"AWS/Lambda",metricName:"Duration",statistic:"Average",comparison:"GreaterThanThreshold",fnMode:"http",unit:"ms"},{key:"http-concurrency",label:"HTTP concurrent executions",namespace:"AWS/Lambda",metricName:"ConcurrentExecutions",statistic:"Maximum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"concurrent"},{key:"queue-errors",label:"Queue function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"queue",unit:"errors / 5 min"}];function y_(e){return Og.find((t)=>t.key===e)}async function fS(e,t){try{let r=await Nr(e,t);return{ok:!0,alarms:await new hi(r.region).describeAlarms({AlarmNamePrefix:`${r.slug}-${t}-`,MaxRecords:100}),presets:Og}}catch(r){return{ok:!1,alarms:[],presets:Og,error:gn(r?.message??String(r))}}}async function hS(e,t,r,o){let m=y_(r);if(!m)return{operation:"alarm:create",ok:!1,error:`Unknown alarm metric '${r}'.`};if(!Number.isFinite(o)||o<0)return{operation:"alarm:create",ok:!1,error:"Provide a non-negative threshold."};try{let h=await Nr(e,t),I=new hi(h.region),R=`${h.slug}-${t}-${m.key}`,A=m.fnMode?[{Name:"FunctionName",Value:`${h.slug}-${t}-${m.fnMode}`}]:[];return await I.putMetricAlarm({AlarmName:R,Namespace:m.namespace,MetricName:m.metricName,ComparisonOperator:m.comparison,Threshold:o,EvaluationPeriods:1,Period:300,Statistic:m.statistic,Dimensions:A,AlarmDescription:`ts-cloud: ${m.label} > ${o} ${m.unit}`}),{operation:"alarm:create",command:`alarm ${R}`,ok:!0,stdout:`Alarm ${R} armed at ${o} ${m.unit}.`}}catch(h){return{operation:"alarm:create",ok:!1,error:gn(h?.message??String(h))}}}async function yS(e,t,r){try{let o=await Nr(e,t);if(!r.startsWith(`${o.slug}-${t}-`))return{operation:"alarm:delete",ok:!1,error:"Refusing to delete an alarm outside this environment."};return await new hi(o.region).deleteAlarms([r]),{operation:"alarm:delete",command:`delete alarm ${r}`,ok:!0,stdout:`Alarm ${r} deleted.`}}catch(o){return{operation:"alarm:delete",ok:!1,error:gn(o?.message??String(o))}}}function v_(e){let t=e.HasFault?"fault":e.HasError?"error":e.HasThrottle?"throttle":"ok";return{id:String(e.Id??""),timestamp:Number.isFinite(Number(e.StartTime))?new Date(Number(e.StartTime)*1000).toISOString():void 0,durationMs:Math.round((e.Duration??0)*1000),responseMs:Math.round((e.ResponseTime??0)*1000),status:t,method:e.Http?.HttpMethod??"-",url:e.Http?.HttpURL??"-",httpStatus:e.Http?.HttpStatus??0}}async function ju(e,t,r=30){try{let o=await Nr(e,t),m=new Dg(o.region),h=new Date,I=new Date(h.getTime()-Math.min(360,Math.max(1,r))*60000),R=`${o.slug}-${t}-http`,A=await m.getTraceSummaries({startTime:I,endTime:h,filterExpression:`service("${R}")`});if(!A.summaries.length)A=await m.getTraceSummaries({startTime:I,endTime:h});return{ok:!0,traces:A.summaries.slice(0,100).map(v_)}}catch(o){return{ok:!1,traces:[],error:gn(o?.message??String(o))}}}async function Lg(e,t,r){try{let o=await Nr(e,t),m=`${o.slug}-${t}-scheduler`;if(r==="run"){let I=await Ke(e,t,"schedule:run");return{operation:"scheduler:run",command:"schedule:run",ok:!0,stdout:gn(I||"Scheduler run triggered.")}}let h=new Zt(o.region);if(r==="enable")await h.enableRule({Name:m});else await h.disableRule({Name:m});return{operation:`scheduler:${r}`,command:`${r} ${m}`,ok:!0,stdout:`Scheduler rule ${m} ${r}d.`}}catch(o){return{operation:`scheduler:${r}`,ok:!1,error:gn(o?.message??String(o))}}}function vS(e,t,r){let o=(Array.isArray(r)?r:String(r??"").split(",")).map(String).filter(Boolean);if(!o.length){if(t)return;let h=e.map((I)=>I.id);return h.length?h:["__no_authorized_telemetry_resources__"]}let m=o.map((h)=>e.find((I)=>I.id===h||I.slug===h)?.id).filter((h)=>!!h);if(m.length!==o.length)throw Error("One or more telemetry resources are outside your authorized scope.");return[...new Set(m)]}import{createHash as SS}from"node:crypto";class wS{now;entries=new Map;constructor(e=Date.now){this.now=e}async getOrCreate(e,t,r,o){let m=this.entries.get(e);if(!r&&m&&m.expiresAt>this.now())return{value:await m.promise,cached:!0};let h=o().catch((I)=>{throw this.entries.delete(e),I});return this.entries.set(e,{expiresAt:this.now()+t,promise:h}),{value:await h,cached:!1}}invalidate(e){for(let t of this.entries.keys())if(t.startsWith(e))this.entries.delete(t)}}class kS{now;lastRun=new Map;constructor(e=Date.now){this.now=e}shouldRun(e,t,r=!1){let o=this.now(),m=this.lastRun.get(e);if(!r&&m!=null&&o-m<t)return!1;return this.lastRun.set(e,o),!0}}var IS=new wS,b_=new kS,S_=2000,w_=3600000;function k_(e,t){if(e.kind==="log"&&!t.collectLogs)return!1;if(e.kind==="trace"&&!t.collectTraces)return!1;if((e.kind==="request"||e.name.startsWith("request."))&&!t.collectRequestAnalytics)return!1;if(!["log","trace","request"].includes(e.kind)&&!e.name.startsWith("request."))return!0;let r=e.requestId??e.traceId??`${e.source}\x00${e.workloadId??""}\x00${e.timestamp}`;return Number.parseInt(SS("sha256").update(r).digest("hex").slice(0,8),16)/4294967295<=t.samplingRate}function fn(...e){return`telemetry:${SS("sha256").update(e.map((t)=>String(t??"")).join("\x00")).digest("hex").slice(0,40)}`}function Ac(e,t,r,o){if(!o)return;return e.listResources(t,r).find((m)=>m.slug===o)?.id}function I_(e,t){let r=String(t??"").toLowerCase();if(["debug","info","warn","warning","error","fatal"].includes(r))return r==="fatal"?"error":r;return/fatal|panic|exception|error/i.test(e)?"error":/warn|timeout|throttl|retr(?:y|ies)/i.test(e)?"warning":"info"}function bS(e){let t=e.timestamp&&Number.isFinite(new Date(e.timestamp).getTime())?new Date(e.timestamp).toISOString():new Date().toISOString(),r={};try{let K=JSON.parse(e.message);if(K&&typeof K==="object"&&!Array.isArray(K))r=K}catch{}let o=Object.fromEntries(Object.entries(r).filter(([K])=>!/^(?:body|requestBody|responseBody|headers|authorization|cookie|cookies|query|queryString)$/i.test(K))),m=String(r.requestId??r.request_id??r["x-request-id"]??"")||void 0,h=String(r.traceId??r.trace_id??r["x-amzn-trace-id"]??"")||void 0,I=Number(r.durationMs??r.duration_ms??r.latencyMs??r.latency_ms),R=Number(r.statusCode??r.status_code??r.status),A=String(r.method??r.httpMethod??"")||void 0,E=ai(String(r.pathTemplate??r.path??r.url??"")||void 0),x=String(r.releaseId??r.release_id??"")||void 0,N=String(r.deploymentId??r.deployment_id??"")||void 0,F={projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,source:e.source,timestamp:t,requestId:m,traceId:h,releaseId:x,deploymentId:N,workloadId:e.workloadId},z=Object.keys(r).length?JSON.stringify(o):e.message,H=[{...F,id:fn(e.source,e.name,t,z),kind:"log",name:e.name,level:I_(z,r.level),message:z,attributes:o}];if(A&&E&&Number.isFinite(R)){if(H.push({...F,id:fn("request",m,t,A,E,R),kind:"request",name:"http.request",method:A,pathTemplate:E,host:r.host,statusCode:R,durationMs:Number.isFinite(I)?I:void 0,bytesIn:Number(r.bytesIn)||void 0,bytesOut:Number(r.bytesOut)||void 0,region:r.region,cacheResult:r.cacheResult??r.cache,upstream:r.upstream,attributes:{userAgentFamily:r.userAgentFamily??"",protocol:r.protocol??""}}),Number.isFinite(I))H.push({...F,id:fn("request-duration",m,t),kind:"metric",name:"request.duration",value:I,unit:"ms",attributes:{method:A,pathTemplate:E,statusCode:R}});if(H.push({...F,id:fn("request-count",m,t),kind:"metric",name:"request.count",value:1,unit:"count",attributes:{method:A,pathTemplate:E,statusCode:R}}),R>=500)H.push({...F,id:fn("request-error",m,t),kind:"metric",name:"request.error",value:1,unit:"count",attributes:{method:A,pathTemplate:E,statusCode:R}})}return H}async function E_(e){let t=new at(e.controlPlane),r=$t(e.controlPlane,e.projectId),o=new Date,m=[],h=[],I={projectId:e.projectId,environmentId:e.environmentId},R=O(e.config);try{let F=(R==="serverless"?await Jr(e.config,e.environment):await Su(e.config,e.environment,{includeSiteHealth:e.includeSiteHealth,telemetryOnly:e.lightweight}))??{};if(R==="serverless"){for(let H of F.functionsDetail??[]){let K=Ac(e.controlPlane,e.projectId,e.environmentId,H.key),X={...I,resourceId:K,source:"cloudwatch",timestamp:o.toISOString(),workloadId:H.name,attributes:{provider:"aws",functionName:H.name,aggregationWindow:"24h"}};for(let[oe,ye,ne]of[["snapshot.traffic.requests_24h",H.invocations,"count"],["snapshot.errors.count_24h",H.errors,"count"],["snapshot.latency.p50_24h",H.p50,"ms"],["snapshot.latency.p95_24h",H.p95,"ms"],["snapshot.latency.p99_24h",H.p99,"ms"],["snapshot.saturation.throttles_24h",H.throttles,"count"],["snapshot.memory.max_24h",H.maxMem,"MB"]])if(Number.isFinite(Number(ye)))m.push({...X,id:fn("cloudwatch",H.name,oe,o.toISOString()),kind:"metric",name:oe,value:Number(ye),unit:ne})}try{let H=await Nr(e.config,e.environment),K=new hi(H.region),X=new Date(o.getTime()-3600000),oe=300;for(let ye of H.functions){let ne=[{Name:"FunctionName",Value:ye.name}],[fe,Ce,xe,he,Ue]=await Promise.all([K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Sum"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Errors",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Sum"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:ne,StartTime:X,EndTime:o,Period:300,ExtendedStatistics:["p50","p95","p99"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Throttles",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Sum"]}),K.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"ConcurrentExecutions",Dimensions:ne,StartTime:X,EndTime:o,Period:300,Statistics:["Maximum"]})]),me=Ac(e.controlPlane,e.projectId,e.environmentId,ye.mode),He=(nt,wt,cr,st)=>{for(let Ft of nt){let dr=Ft.Timestamp&&Number.isFinite(new Date(Ft.Timestamp).getTime())?new Date(Ft.Timestamp).toISOString():void 0,vt=cr(Ft);if(dr&&vt!=null&&Number.isFinite(vt))m.push({...I,resourceId:me,id:fn("cloudwatch-series",ye.name,wt,dr),kind:"metric",source:"cloudwatch",name:wt,timestamp:dr,value:vt,unit:st,workloadId:ye.name,region:H.region,attributes:{provider:"aws",functionName:ye.name,aggregationWindow:"300s"}})}};He(fe,"traffic.requests",(nt)=>nt.Sum,"count"),He(Ce,"errors.count",(nt)=>nt.Sum,"count"),He(xe,"latency.p50",(nt)=>nt.Percentiles?.p50,"ms"),He(xe,"latency.p95",(nt)=>nt.Percentiles?.p95,"ms"),He(xe,"latency.p99",(nt)=>nt.Percentiles?.p99,"ms"),He(he,"saturation.throttles",(nt)=>nt.Sum,"count"),He(Ue,"saturation.concurrency",(nt)=>nt.Maximum,"count")}}catch(H){h.push({source:"cloudwatch:series",message:H instanceof Error?H.message:String(H)})}for(let H of(F.serverlessLogs??[]).slice(0,S_))m.push(...bS({...I,source:`cloudwatch:${H.source}`,name:`${H.source}.log`,timestamp:H.timestamp,message:String(H.message),resourceId:Ac(e.controlPlane,e.projectId,e.environmentId,H.source)}));for(let H of F.queuesDetail??[]){let K={...I,source:"cloudwatch",timestamp:o.toISOString(),attributes:{queue:H.name}};m.push({...K,id:fn("queue-depth",H.name,o.toISOString()),kind:"metric",name:"queue.depth",value:Number(H.visible??H.depth??0),unit:"count"}),m.push({...K,id:fn("queue-inflight",H.name,o.toISOString()),kind:"metric",name:"queue.inflight",value:Number(H.inFlight??0),unit:"count"})}let z=await ju(e.config,e.environment,30);if(!z.ok)h.push({source:"xray",message:z.error??"X-Ray traces are unavailable."});for(let H of z.traces)m.push({...I,id:fn("xray",H.id),kind:"trace",source:"xray",name:"http.trace",timestamp:H.timestamp??o.toISOString(),traceId:H.id,durationMs:H.durationMs,statusCode:H.httpStatus,method:H.method,pathTemplate:H.url,attributes:{status:H.status,responseMs:H.responseMs}})}else{let z=F.systemMetrics;if(F.metricsUnavailable||!z)h.push({source:"host",message:"The host metrics probe is unavailable."});else{let H=Number(z.memTotalMb)>0?Number(z.memUsedMb)/Number(z.memTotalMb)*100:0,K=Number(z.swapTotalMb)>0?Number(z.swapUsedMb)/Number(z.swapTotalMb)*100:0,X=[["host.load",Number(z.load),"load"],["host.load.5m",Number(z.load5),"load"],["host.load.15m",Number(z.load15),"load"],["host.cpu.capacity",Number(z.cpus),"count"],["host.cpu.used_percent",Number(z.cpuUsedPct),"percent"],["host.memory.used",Number(z.memUsedMb)*1024*1024,"bytes"],["host.memory.total",Number(z.memTotalMb)*1024*1024,"bytes"],["host.memory.available",Number(z.memAvailableMb)*1024*1024,"bytes"],["host.memory.cache",Number(z.memCacheMb)*1024*1024,"bytes"],["host.memory.used_percent",H,"percent"],["host.swap.used",Number(z.swapUsedMb)*1024*1024,"bytes"],["host.swap.total",Number(z.swapTotalMb)*1024*1024,"bytes"],["host.swap.used_percent",K,"percent"],["host.disk.used_percent",Number(z.diskUsedPct),"percent"],["host.disk.used",Number(z.diskUsedGb)*1073741824,"bytes"],["host.disk.total",Number(z.diskTotalGb)*1073741824,"bytes"],["host.disk.inode_used_percent",Number(z.inodeUsedPct),"percent"],["host.network.rx",Number(z.networkRxBytes),"bytes"],["host.network.tx",Number(z.networkTxBytes),"bytes"],["host.network.rx_rate",Number(z.networkRxBytesPerSec),"bytes_per_second"],["host.network.tx_rate",Number(z.networkTxBytesPerSec),"bytes_per_second"],["host.network.rx_today",Number(z.networkRxBytesToday),"bytes"],["host.network.tx_today",Number(z.networkTxBytesToday),"bytes"],["host.network.rx_month",Number(z.networkRxBytesMonth),"bytes"],["host.network.tx_month",Number(z.networkTxBytesMonth),"bytes"],["host.processes",Number(z.processes),"count"],["host.uptime",Number(z.uptimeSeconds),"seconds"]];for(let[oe,ye,ne]of X)if(Number.isFinite(ye))m.push({...I,id:fn("host",oe,o.toISOString()),kind:"metric",source:"host",name:oe,timestamp:o.toISOString(),value:ye,unit:ne});for(let oe of F.siteHealth??[]){let ye=String(oe.project??e.config.project.slug),ne=String(oe.name),fe=ne.startsWith(`${ye}:`)?ne.slice(ye.length+1):ne,Ce=`site:${ye}:${fe}`,xe=Ac(e.controlPlane,e.projectId,e.environmentId,ne),he={...I,resourceId:xe,source:Ce,timestamp:oe.checkedAt||o.toISOString(),host:oe.route,attributes:{project:ye,site:fe,route:String(oe.route),status:String(oe.status)}},Ue=[["site.health.up",oe.status==="live"?1:0,"boolean"],["site.http.status",Number(oe.httpStatus),"status"],["site.response.time",Number(oe.responseMs),"ms"]];if(oe.tlsDaysRemaining!=null)Ue.push(["site.tls.days_remaining",Number(oe.tlsDaysRemaining),"days"]);for(let[me,He,nt]of Ue)if(Number.isFinite(He))m.push({...he,id:fn(Ce,me,he.timestamp),kind:"metric",name:me,value:He,unit:nt})}}}}catch(F){h.push({source:R==="serverless"?"aws":"host",message:F instanceof Error?F.message:String(F)})}{let F=e.config.infrastructure?.compute?.monitoring,z=typeof F==="object"?F?.egressEndpoints:void 0,H=await Zo(z,{now:o.toISOString()});h.push(...H.errors);for(let K of H.metrics)m.push({...I,id:fn(K.attributes.source,K.name,K.timestamp),kind:"metric",source:`egress:${K.attributes.source}`,name:K.name,timestamp:K.timestamp,value:K.value,unit:K.unit,attributes:K.attributes})}if(!e.lightweight)try{let F=await te(e.config,e.environment),z=new le(e.config,e.environment,{inventory:async()=>F});for(let H of F.workloads){let K=Ac(e.controlPlane,e.projectId,e.environmentId,H.links.service),X={...I,resourceId:K,source:`runtime:${H.provider}`,timestamp:o.toISOString(),workloadId:H.id,releaseId:H.links.release,attributes:{status:H.status,provider:H.provider,service:H.links.service??""}};if(m.push({...X,id:fn(H.id,"health",o.toISOString()),kind:"metric",name:"health.up",value:H.status==="running"?1:0,unit:"boolean"}),m.push({...X,id:fn(H.id,"restarts",o.toISOString()),kind:"metric",name:"saturation.restarts",value:H.restartCount??0,unit:"count"}),H.resources?.memoryBytes!=null)m.push({...X,id:fn(H.id,"memory",o.toISOString()),kind:"metric",name:"runtime.memory.used",value:H.resources.memoryBytes,unit:"bytes"});if(!H.capabilities.logs.supported)continue;try{let oe=await z.logs(H.id,{limit:100,since:new Date(o.getTime()-300000)});for(let ye of oe.lines)m.push(...bS({...I,resourceId:K,source:`runtime:${H.provider}`,name:`${H.links.service??H.name}.log`,timestamp:ye.timestamp,message:ye.message,workloadId:H.id}))}catch(oe){h.push({source:`runtime:${H.provider}`,message:oe instanceof Error?oe.message:String(oe)})}}for(let H of F.sources.filter((K)=>K.status!=="fresh"))h.push({source:H.id,message:H.message??`Runtime source is ${H.status}.`})}catch(F){h.push({source:"runtime",message:F instanceof Error?F.message:String(F)})}if(!e.lightweight)for(let F of e.controlPlane.listEvents({projectId:e.projectId,limit:1000})){let z=F.payload;m.push({...I,id:`telemetry:event:${F.id}`,resourceId:F.resourceId,kind:"event",source:"control-plane",name:F.type,timestamp:F.createdAt,level:F.level,message:F.type,deploymentId:F.operationId,releaseId:typeof z.releaseId==="string"?z.releaseId:void 0,traceId:F.correlationId,attributes:z})}let A=m.filter((F)=>k_(F,r)).map((F)=>({...F,sampled:r.samplingRate<1&&(F.kind==="log"||F.kind==="trace"||F.kind==="request"||F.name.startsWith("request."))})),E=t.appendMany(A).length;if(b_.shouldRun(e.projectId,w_,!e.lightweight))t.enforceRetention(r,e.projectId);let x=t.status(e.projectId,e.environmentId,r.rawDays,r.samplingRate);for(let F of h)if(!x.some((z)=>z.source===F.source))x.push({source:F.source,freshness:"unavailable",samplingRate:r.samplingRate,retentionDays:r.rawDays,estimatedDailyBytes:0,message:F.message});let N=o.toISOString();return e.controlPlane.setSetting(`telemetry.collection:${e.projectId}:${e.environmentId??"all"}`,{generatedAt:N,errors:h,statuses:x,policy:r}),{collected:E,cached:!1,generatedAt:N,statuses:x,errors:h,policy:r}}async function Fg(e){let r=`${`${e.projectId}:${e.environmentId??"all"}:${e.environment}`}:${e.lightweight?"lightweight":"full"}`,o=O(e.config)==="serverless"?300000:60000,m=await IS.getOrCreate(r,o,!!e.force,()=>E_(e));return{...m.value,cached:m.cached}}function ES(e){IS.invalidate(`${e}:`)}function RS(e,t={}){let r=t.shell||(process.platform==="win32"?"powershell.exe":"bash"),o=Bun.spawn([r,"-i"],{stdin:"pipe",stdout:"pipe",stderr:"pipe",cwd:t.cwd,env:{...process.env,TERM:"xterm-256color",PS1:"\\w $ "}}),m=new TextDecoder,h=async(I)=>{if(!I)return;let R=I.getReader();try{for(;;){let{done:A,value:E}=await R.read();if(A)break;if(E)e(m.decode(E))}}catch{}};if(h(o.stdout),h(o.stderr),t.onExit)o.exited.then((I)=>t.onExit(I)).catch(()=>{});return{write(I){try{o.stdin.write(I),o.stdin.flush()}catch{}},close(){try{o.stdin.end()}catch{}try{o.kill()}catch{}}}}var D_="127.0.0.1",O_=7676,CS=65536,BS="ts-cloud-dashboard-",Ja=A_(x_(import.meta.url));function $_(e){try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function N_(e=Lu(),t=$_){let r=0;for(let o of AS(e,{withFileTypes:!0})){if(!o.isDirectory()||!o.name.startsWith(BS))continue;let m=rr(e,o.name),h=o.name.match(/^ts-cloud-dashboard-(\d+)-/);if(h){let I=Number(h[1]);if(I===process.pid||t(I))continue}else if(AS(m).length>0)continue;Gs(m,{recursive:!0,force:!0}),r+=1}return r}var j_={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".ico":"image/x-icon"};function M(e,t=200,r={}){return new Response(JSON.stringify(e,null,2),{status:t,headers:{"content-type":"application/json; charset=utf-8",...r}})}function M_(e,t,r,o){let m=new TextEncoder,h=Math.max(0,Math.floor(r)),I,R,A=!1,E=new ReadableStream({start(x){let N=()=>{if(A)return;if(A=!0,I?.(),R)clearInterval(R);o.removeEventListener("abort",N);try{x.close()}catch{}},F=(H)=>{if(A)return;if(H.reset)x.enqueue(m.encode(`event: reset
659
659
  data: ${JSON.stringify({cursor:H.cursor,droppedBytes:H.droppedBytes})}
660
660
 
661
661
  `));for(let K of H.chunks.filter((X)=>X.cursor>h))h=K.cursor,x.enqueue(m.encode(`id: ${K.cursor}
@@ -673,37 +673,37 @@ data: ${JSON.stringify({cursor:h,at:new Date().toISOString()})}
673
673
  ${R}
674
674
  ${A}`);return null}return o}catch(m){if(o)Gs(o,{recursive:!0,force:!0});if(process.env.TSCLOUD_DASHBOARD_VERBOSE)console.warn(`ts-cloud dashboard: live UI build errored; serving the pre-built UI. ${m.message}`);return null}}function Fi(e){let t=e.infrastructure?.compute?.managedServices?JSON.parse(JSON.stringify(e.infrastructure.compute.managedServices)):void 0;if(t?.vitess?.password)t.vitess.password="";return{project:{name:e.project?.name,slug:e.project?.slug,region:e.project?.region},provider:e.provider,environments:Object.keys(e.environments??{}),compute:e.infrastructure?.compute?{provider:e.infrastructure.compute.provider,runtime:e.infrastructure.compute.runtime,webServer:e.infrastructure.compute.webServer,proxy:e.infrastructure.compute.proxy?{engine:e.infrastructure.compute.proxy.engine,onDemandTls:e.infrastructure.compute.proxy.onDemandTls,cdn:!!e.infrastructure.compute.proxy.cdn}:void 0,managedServices:t,sshKeys:gs(Ga(e)).map((r)=>({name:r.name,type:r.type,fingerprint:r.fingerprint,added:r.added}))}:void 0,sites:Object.fromEntries(Object.entries(e.sites??{}).map(([r,o])=>[r,{domain:o.domain,path:o.path,type:o.type,deploy:o.deploy,root:o.root,port:o.port,ssl:o.ssl}]))}}function Yr(e){return[{id:"status",label:"Refresh Cloud Status",description:"Runs the local ts-cloud status checks against configured providers.",command:["status","--env",e],mutates:!1},{id:"doctor",label:"Run Doctor",description:"Checks local tooling, credentials, and provider access.",command:["doctor"],mutates:!1},{id:"security-scan",label:"Security Scan",description:"Runs the pre-deploy scanner from this checkout.",command:["deploy:security-scan","--source",".","--fail-on","critical"],mutates:!1},{id:"deploy",label:"Deploy Environment",description:"Deploys the selected environment from the local checkout.",command:["deploy","--env",e,"--yes"],mutates:!0,confirm:"deploy"}]}function Ui(e,t){return Yr(t).find((r)=>r.id===e)}function xS(e){if(e.length<=CS)return e;return`${e.slice(0,CS)}
675
675
 
676
- [output truncated]`}async function DS(e,t,r){let o=e.getReader(),m=new TextDecoder,h="";while(!0){let{done:R,value:A}=await o.read();if(R)break;let E=m.decode(A,{stream:!0});if(h+=E,E)r?.(t,E)}let I=m.decode();if(I)h+=I,r?.(t,I);return h}async function Hg(e,t){let r=Bun.spawn([process.execPath,t.cliEntry,...e.command],{cwd:t.cwd,stdout:"pipe",stderr:"pipe",env:{...process.env,...t.env}}),o=()=>{try{r.kill()}catch{}};if(t.signal?.aborted)o();else t.signal?.addEventListener("abort",o,{once:!0});try{let[m,h,I]=await Promise.all([DS(r.stdout,"stdout",t.onOutput),DS(r.stderr,"stderr",t.onOutput),r.exited]);return{action:e.id,command:["cloud",...e.command].join(" "),exitCode:I,ok:I===0,stdout:xS(m),stderr:xS(h)}}finally{t.signal?.removeEventListener("abort",o)}}function eT(){return Object.entries(process.env).filter(([e,t])=>!!t&&t.length>=8&&/(?:secret|token|password|passwd|private|credential|api.?key|access.?key)/i.test(e)).map(([,e])=>e)}var tT=new Set(["/server/sites","/server/deployments","/server/logs","/integrations","/applications/new","/applications/compose","/operations/queue","/operations/previews","/operations/releases","/operations/workloads","/operations/observability","/operations/alerts","/operations/jobs","/data/backups","/account/security","/security","/access-denied"]);function rT(e){let t=_c(e);if(t&&t!==".html")return!1;let r=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(r==="/")return!1;return!tT.has(r)}var nT={"/":"runtime:read","/server/activity":"audit:read","/server/sites":"project:read","/server/deployments":"deployments:read","/server/logs":"runtime:logs","/server/metrics":"runtime:read","/server/services":"runtime:read","/data/backups":"backups:read","/data/volumes":"data:read","/server/fleet":"fleet:read","/server/capacity":"fleet:read","/server/actions":"runtime:restart","/server/database":"data:read","/server/firewall":"fleet:read","/infrastructure/topology":"fleet:read","/server/security":"security:read","/security":"security:read","/integrations":"sources:read","/applications/new":"applications:read","/applications/compose":"applications:read","/operations/queue":"deployments:read","/operations/previews":"deployments:read","/operations/releases":"deployments:read","/operations/regions":"deployments:read","/operations/maintenance":"deployments:read","/operations/workloads":"runtime:read","/operations/observability":"runtime:logs","/operations/alerts":"runtime:read","/operations/jobs":"automation:read","/operations/configuration":"config:read","/server/ssh-keys":"fleet:read","/server/terminal":"runtime:terminal","/server/team":"users:read","/account/security":"project:read","/account/automation":"users:read","/serverless":"project:read","/serverless/deployments":"deployments:read","/serverless/logs":"runtime:logs","/serverless/metrics":"runtime:read","/serverless/traces":"runtime:read","/serverless/functions":"config:read","/serverless/queues":"data:read","/serverless/data":"data:read","/serverless/assets":"project:read","/serverless/secrets":"secrets:read","/serverless/firewall":"fleet:read","/serverless/alarms":"runtime:read","/serverless/cost":"project:read"};function OS(e,t){if(t.role==="admin")return!0;let r=_c(e);if(r&&r!==".html")return!0;if(t.organizationSource==="legacy")return!rT(e);let o=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(o==="/access-denied")return!0;let m=nT[o];return!!m&&!!t.capabilities?.includes(m)}function iT(e,t){let r=decodeURIComponent(t).replace(/^\/+/,""),m=C_(r===""?"index.html":r);if(m.startsWith("..")||m.includes("/../"))return null;let h=rr(e,m);if(Zi(h)&&!MS(h).isDirectory())return h;if(!_c(h)&&Zi(`${h}.html`))return`${h}.html`;if(!_c(h)&&Zi(rr(h,"index.html")))return rr(h,"index.html");return null}async function $S(e,t){let r=iT(e,t);if(!r){let h=rr(e,"404.html");if(Zi(h))return new Response(await pi(h),{status:404,headers:{"content-type":"text/html; charset=utf-8"}});return Fu("Not found",404)}if(MS(r).isDirectory())return Fu("Not found",404);let o=await pi(r),m=j_[_c(r)]??"application/octet-stream";return new Response(o,{headers:{"content-type":m}})}var Bu=["observe","backup","restore","restart","resize","version","rotate","expose","delete","logs","slow_queries","users","databases"],NS=new WeakMap;async function jS(e){let t=NS.get(e);if(t)return t;let r=await import("./spend/index.js"),o=new r.SpendStore(e),m={store:o,service:new r.SpendService(o),gate:new r.SpendGate(e)};return NS.set(e,m),m}async function ga(e={}){N_();let t=e.cwd??process.cwd(),r=e.host??D_,o=e.port??O_,m=e.cliEntry??process.argv[1];if(e.box)process.env.TS_CLOUD_DASHBOARD_BOX="1";await V_(t);let h=e.config??await wd(),I=process.env.TS_CLOUD_DASHBOARD_DB_PASSWORD,R=p(h);if(I&&R&&!R.password)R.password=I;let A=h.infrastructure?.compute?.managedServices?.vitess;if(I&&A&&typeof A==="object"&&!A.password)A.password=I;let E=Rl(t,h);if(E.reconciliation.failed>0)console.warn(` ts-cloud dashboard: marked ${E.reconciliation.failed} orphaned operation(s) as failed after restart.`);let x=Object.keys(h.environments??{}),N=U_(h,e.environment),F=W_(t),z=await Ks(h,N),H=new Map([[N,z]]),K=new Map([[N,Date.now()]]),X=new Map([[N,Date.now()]]),oe=new Map,ye=Math.min(300000,Math.max(5000,Number(process.env.TS_CLOUD_DASHBOARD_REFRESH_MS)||30000)),ne=Math.min(1800000,Math.max(60000,Number(process.env.TS_CLOUD_DASHBOARD_SITE_REFRESH_MS)||300000)),fe=O(h)!=="serverless",Ce=(L)=>{let Qe=H.get(L);if(Qe&&!PS(K.get(L),Date.now(),ye))return Promise.resolve(Qe);let Ze=oe.get(L);if(Ze)return Ze;let He=!fe||PS(X.get(L),Date.now(),ne),it=Ks(h,L,{includeSiteHealth:He}).then((Tt)=>{let W=H.get(L),un=He?Tt:Y_(W,Tt);if(H.set(L,un),K.set(L,Date.now()),He)X.set(L,Date.now());if(W?._serverReachable!==un._serverReachable||W?._metricsStatus!==un._metricsStatus||(W?.sitesDetail?.length??0)!==(un.sitesDetail?.length??0))st();return un}).finally(()=>oe.delete(L));return oe.set(L,it),it},_e=Pt(t),he=process.env.TS_CLOUD_DASHBOARD_TELEMETRY?.trim();if(e.box&&he!=="0"&&(he==="1"||!h.cloud?.attachTo)){let L=!1,Qe=Date.now()+300000,Ze=async()=>{if(L)return;L=!0;try{let it=Date.now(),Tt=it>=Qe;if(Tt)Qe=it+300000;let W=E.environments.get(N);await Fg({controlPlane:E.store,projectId:E.project.id,environmentId:W?.id,config:h,environment:N,force:!0,lightweight:!0,includeSiteHealth:Tt})}catch(it){if(e.verbose)console.warn(` ts-cloud dashboard: background telemetry collection failed: ${it instanceof Error?it.message:String(it)}`)}finally{L=!1}};Ze(),setInterval(()=>void Ze(),60000).unref?.()}let me=new Map,We=new Map,nt=new Set,wt=0;function cr(L,Qe){if(L.role==="admin"&&!E.store.getActorByExternalId("user",`dashboard:${L.username.toLowerCase()}`))return L;let Ze=E.store.getActorByExternalId("user",`dashboard:${L.username.toLowerCase()}`),He=Ze?E.store.getMembershipForActor(E.organization.id,Ze.id):void 0;if(!He||He.status!=="active")return{...L,role:"member",sites:{},capabilities:[]};let it=E.store.listGrants(He.id),Tt=E.store.resolveAuthorizationTarget(E.organization.id,He.scope)??E.store.resolveAuthorizationTarget(E.organization.id,{type:"project",id:E.project.id}),W=Bt({membership:He,grants:it,target:Tt});if(He.roleTemplate==="owner"||He.roleTemplate==="admin")return{...L,role:"admin",sites:{},organizationRole:He.roleTemplate,organizationSource:He.source,capabilities:W};let un=E.environments.get(Qe),kr={};for(let dt of E.store.listResources(E.project.id,un?.id).filter((St)=>St.kind==="application")){let St=E.store.resolveAuthorizationTarget(E.organization.id,{type:"resource",id:dt.id});if(!St||!w({membership:He,grants:it,capability:"project:read",target:St}).allowed)continue;kr[dt.slug]=w({membership:He,grants:it,capability:"config:write",target:St}).allowed?"owner":"collaborator"}return{...L,role:"member",sites:kr,organizationRole:He.roleTemplate,organizationSource:He.source,capabilities:W}}function st(){wt+=1,me.clear();for(let L of nt)Gs(L,{recursive:!0,force:!0});nt.clear()}let Ft=(L,Qe)=>`${Qe}:${L.role==="admin"?"admin":`member:${Object.entries(L.sites).sort(([Ze],[He])=>Ze.localeCompare(He)).map(([Ze,He])=>`${Ze}=${He}`).join(",")}`}:${[...L.capabilities??[]].sort().join(",")}`;async function dr(L,Qe){let Ze=cr(L,Qe),He=Ft(Ze,Qe),it=me.get(He);if(it)return it;let Tt=We.get(He);if(Tt)return Tt;let W=wt,un=(async()=>{let kr=H.get(Qe)??await Ks(h,Qe);H.set(Qe,kr);let dt={...Tg(kr,{user:Ze,slug:h.project.slug}),viewer:{role:Ze.role,organizationRole:Ze.organizationRole,organizationSource:Ze.organizationSource,capabilities:Ze.capabilities??[]}},St=await X_(t,dt);if(St&&W!==wt)return Gs(St,{recursive:!0,force:!0}),_e?.uiRoot;if(St)nt.add(St);let nn=St??_e?.uiRoot;if(nn)me.set(He,nn);return nn})();We.set(He,un);try{return await un}finally{We.delete(He)}}let vt=await dr({username:"",passwordHash:"",role:"admin",sites:{}},N);if(!vt)throw Error("ts-cloud dashboard UI not found. Run `bun run build` in ts-cloud or reinstall the package.");let Y=new WeakMap,be=process.env.TS_CLOUD_DASHBOARD_TERMINAL!=="0",Ee=process.env.TS_CLOUD_DASHBOARD_AUTH==="0";if(Ee&&e.box)throw Error("TS_CLOUD_DASHBOARD_AUTH=0 is refused in box mode: the dashboard is internet-facing there, and disabling auth would expose a root shell.");let Be=!Ee,It=Cb(t),Ut=Be?xb(t,process.env.TS_CLOUD_UI_USERNAME?.trim()||"admin"):void 0,Fe=new bi(E.store,{encryptionKey:qe(t)}),Ct=new Ei(E.store),bt=new Fr(E.store),rt=new Ao(E.store,{encryptionKey:qe(t)}),ln=new ip(E.store),Qs=new cp(E.store,{cwd:t}),Zn=new sp(E.store,{encryptionKey:qe(t)}),nr=new c(E.store,{workerId:`dashboard:${process.pid}`}),lr=new ko(E.store),mi=new Uo(E.store,qe(t)),Xi=new ca(E.store),Tc=new ki(lr,nr,mi),eo=h.project?.region??"us-east-1",Qg=qe(t),Rn=new pa(Xi,{encryptionKey:Qg,backends:[new Xr(E.store,Qg),new da(new V(eo),eo),new la(new Ie(eo),eo),new ua]});await Fl(Rn,E,h);let zu=new j(eo),LS={aws_rds:new Bo(new $o(zu)),aws_aurora:new xo(new Mo(zu)),aws_elasticache:new _o(new Fo(new Je(eo))),server:new Oo(new jt),container:new Lo(new jt)},ef=(L)=>LS[L.provider],Er=new ea(E.store),fs=new Mi(Er,nr),tf=new ta(mi),FS={managed_database:new ra(lr,zu),logical_database:new ia(lr,mi),volume:new sa,files:new na(t),control_plane:new oa(E.store,t),infrastructure:new aa(new Jt(eo))},zS=(L)=>FS[L.resourceKind],US=(L)=>L.provider==="aws_backup"?void 0:tf,Uu=new xt(E.store),qu=[new Sr,new vs(d(t,"volumes"))],gi=new Es(Uu,qu,nr),Qa=new Qo(E.store),ti=new Ho(Qa,[new qr("aws"),new qr("hetzner"),new qr("ssh")],nr),to=new Go(E.store),rf=new qo(to,Qa),hs=new Vo(E.store),nf=new jo(hs,nr),fi=new Ko(E.store),Vu=new Wo(fi,nr),of=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((L)=>new Jo(L,E.store,E.project.id,E.organization.id)),Zr=new Do(E.store),sf=new No(Zr,{queue:nr}),wr=new Ir(E.store),ro=new Cr(E.store),$n=new lt(E.store),ct=new ii(E.store,{encryptionKey:qe(t)}),qS=()=>jS(E.store);for(let L of E.environments.values())Po(Zr,h,{organization:E.organization,project:E.project,environment:L,resources:E.store.listResources(E.project.id,L.id)});let Nn=new si(ct,{emailImpl:async(L)=>{let{email:Qe}=await import("./chunk-v46b25w9.js");return Qe.send(L)}}),af=async(L)=>{let Qe=$s(ct,E.project.id,L),Ze=[];for(let He of Qe.filter((it)=>it.notify&&it.alert))Ze.push(...await Nn.deliverAll(Nn.enqueue(E.organization.id,He.alert,He.transition)));return Ze.push(...await Nn.deliverAll(Nn.enqueueRemindersAndEscalations(E.organization.id,ct.listAlerts(E.project.id,{environmentId:L,states:["firing"]})))),Ze.push(...await Nn.retryDue()),{evaluations:Qe,deliveries:Ze}},Wu=!1,VS=async()=>{if(Wu)return;Wu=!0;try{for(let L of E.environments.values())for(let Qe of ct.listHealthChecks(E.project.id,L.id).filter((Ze)=>Ze.enabled)){let Ze=ct.listHealthResults(Qe.id,1)[0];if(Ze&&Date.now()-new Date(Ze.checkedAt).getTime()<Qe.intervalSeconds*1000)continue;let He=await new Me(ct).runAndEvaluate(Qe);for(let it of He.evaluations.filter((Tt)=>Tt.notify&&Tt.alert))await Nn.deliverAll(Nn.enqueue(E.organization.id,it.alert,it.transition))}}finally{Wu=!1}},cf=setInterval(()=>{for(let L of E.environments.values())af(L.id).catch((Qe)=>console.error("ts-cloud alert evaluation failed:",Qe))},60000);cf.unref?.();let df=setInterval(()=>{VS().catch((L)=>console.error("ts-cloud health check evaluation failed:",L))},30000);df.unref?.();let lf=setInterval(()=>{try{sf.tick()}catch(L){console.error("ts-cloud scheduled job evaluation failed:",L)}},30000);lf.unref?.();let uf=setInterval(()=>{try{fs.enqueueDue(),fs.enqueueRetention()}catch(L){console.error("ts-cloud backup policy evaluation failed:",L)}},30000);uf.unref?.(),wr.cleanup();let pf=setInterval(()=>{try{wr.cleanup()}catch(L){console.error("ts-cloud preview cleanup failed:",L)}},3600000);pf.unref?.();let WS=e.queueWorker??!0,HS=eT(),KS=async(L,Qe)=>{let He=(L.environmentId?E.store.listEnvironments(L.projectId).find((it)=>it.id===L.environmentId):void 0)?.slug??String(N);if(Qe.kind==="dashboard_operation"&&Qe.operationId){let it=H.get(He)??z,Tt=_g(Qe.operationId,h,it);if(!Tt||Tt.danger||!["scheduler","backup","worker"].includes(Tt.group))return{ok:!1,stderr:"The allowlisted dashboard operation is no longer available."};let W=await $u(h,He,Tt);return{ok:W.ok,stdout:W.stdout,stderr:W.stderr??W.error,retryable:/temporar|unavailable|timeout|network/i.test(W.stderr??W.error??""),output:{command:W.command??null,operation:W.operation}}}if(Qe.kind==="serverless_scheduler"){let it=await Lg(h,He,"run");return{ok:it.ok,stdout:it.stdout,stderr:it.error,retryable:/temporar|unavailable|timeout|network/i.test(it.error??""),output:{command:it.command??null,operation:"serverless_scheduler"}}}return{ok:!1,stderr:`No safe executor is configured for ${Qe.kind}.`}},xc=WS?new Cs(nr,{...Sc({store:E.store,execute:async(L,Qe)=>{let Ze=Qe.operation.input&&typeof Qe.operation.input==="object"&&!Array.isArray(Qe.operation.input)?Qe.operation.input:{},He=Ze.source&&typeof Ze.source==="object"?Ze.source:void 0,it=t,Tt,W,un;try{if(He?.bindingId&&He?.connectionId&&He?.commitSha){let dt=rt.getBinding(String(He.bindingId)),St=rt.getConnection(String(He.connectionId));if(!dt||!St||dt.connectionId!==St.id)throw Error("Queued source binding is no longer available");let Dr=(dt.repositoryId?rt.getRepository(dt.repositoryId):rt.listRepositories(St.id).find((Xs)=>Xs.fullName.toLowerCase()===dt.repositoryFullName.toLowerCase()))?.cloneUrl;if(!Dr&&St.provider==="generic_ssh")Dr=`git@${new URL(St.host).hostname}:${dt.repositoryFullName}.git`;if(!Dr)Dr=new URL(`/${dt.repositoryFullName}.git`,St.host.endsWith("/")?St.host:`${St.host}/`).href;let De=dt.deployKeyId?rt.getDeployKey(dt.deployKeyId):void 0,ur=De&&dt.deployKeyId?{...De,privateKey:rt.getDeployPrivateKey(dt.deployKeyId)}:void 0;if(["github","gitlab","bitbucket","gitea"].includes(St.provider)&&L.target.previewId){let Xs=Ve(St,rt.getCredential(St.id)),Se=wr.previews.getInstance(L.target.previewId);un=async(jn,jc)=>{try{await Xs.setCommitStatus(dt.repositoryFullName,String(He.commitSha),{state:jn,url:Se?.url,description:jc})}catch(ma){Qe.log(`Could not publish source status: ${ma instanceof Error?ma.message:String(ma)}`,{stream:"stderr"})}},await un("pending",`Preview deployment started for ${String(He.commitSha).slice(0,12)}`)}Tt=Gg(rr(Lu(),"ts-cloud-queued-source-")),Qe.log(`Checking out immutable source commit ${He.commitSha}.`,{stream:"system"}),it=(await Io({remote:Dr,binding:dt,destination:rr(Tt,"checkout"),ref:String(He.branch??dt.defaultBranch),commitSha:String(He.commitSha)},{credential:rt.getCredential(St.id),deployKey:ur})).directory}if(Qe.operation.kind!=="preview.destroy"){let dt=L.target.previewId?wr.previews.getInstance(L.target.previewId):void 0,St=dt?wr.previews.getDefinition(dt.definitionId):void 0,nn=Qe.operation.resourceId?E.store.getResource(Qe.operation.resourceId):void 0;if(W=await Rn.resolve({projectId:E.project.id,environmentId:Qe.operation.environmentId,resourceId:Qe.operation.resourceId,functionId:nn?.kind==="function"?nn.id:void 0,previewId:dt?.id,trustedPreview:!!dt&&!dt.fork,allowedPreviewSecrets:St?.inheritedSecrets}),W.warnings.some((Dr)=>Dr.code==="missing_required"))throw Error(`Required deployment configuration is unavailable: ${W.warnings.filter((Dr)=>Dr.code==="missing_required").map((Dr)=>Dr.key).join(", ")}`);if(Qe.operation.resourceId)for(let Dr of Object.values(W.entries))Xi.setDependency({entryId:Dr.id,resourceId:Qe.operation.resourceId,injectionTarget:"environment",required:Dr.required,requiresRedeploy:!0});Qe.log(`Resolved configuration ${W.configurationHash.slice(0,18)} for ${Object.keys(W.values).length} keys.`,{stream:"system"})}let kr=await Hg(L,{cwd:it,cliEntry:m,signal:Qe.signal,env:W?.values,onOutput:(dt,St)=>Qe.log(St,{stream:dt,step:"execute",secrets:[...HS,...Object.entries(W?.entries??{}).filter(([,nn])=>nn.kind==="secret").map(([nn])=>W.values[nn]).filter(Boolean)]})});if(kr.ok&&Qe.operation.resourceId&&W)for(let dt of Object.values(W.entries))Xi.setDependency({entryId:dt.id,resourceId:Qe.operation.resourceId,injectionTarget:"environment",required:dt.required,requiresRedeploy:!1,lastDeployedVersion:dt.version});return await un?.(kr.ok?"success":"failure",kr.ok?`Preview is ready at ${String(He?.commitSha).slice(0,12)}`:`Preview deployment failed at ${String(He?.commitSha).slice(0,12)}`),kr}catch(kr){throw await un?.("error",`Preview deployment could not complete at ${String(He?.commitSha).slice(0,12)}`),kr}finally{if(Tt)Gs(Tt,{recursive:!0,force:!0})}}}),...al({store:Zr,executor:KS}),...dl({store:lr,secrets:mi,resolveAdapter:ef}),...pl(Qa,ti.drivers),...ml(hs,[new zo("aws","AWS regional execution requires an injected AwsRegionalTransport; topology and plans were preserved without provider mutation.")]),...Il({store:fi,cleanup:of}),...Cc(Uu,qu),..._l({store:Er,queue:nr,resolveSource:zS,resolveDestination:US,validateHealth:async(L,Qe)=>{if(!L.healthCheckId)return{healthy:!0,mode:"adapter"};let Ze=ct.getHealthCheck(L.healthCheckId);if(!Ze||Ze.projectId!==L.projectId)return{healthy:!1,error:"Configured restore health check was not found."};let He=await new Me(ct).runAndEvaluate(Ze);return{healthy:He.result.status==="healthy",healthCheckId:Ze.id,healthResultId:He.result.id,target:Qe}}}),...Fd({store:E.store,resolveDriver:e.releaseDriver??((L)=>({name:`${E.store.getResource(L.resourceId)?.provider??"provider"} release driver`,capability:()=>({strategy:L.strategy,supported:!1,explanation:"This dashboard process has no immutable activation driver configured for the target provider.",capacityMultiplier:1,costImpact:"none",rollback:"The previous release remains preserved; configure a release driver before retrying."}),activate:async()=>{throw Error("Immutable activation driver is not configured")},rollback:async()=>{throw Error("Immutable rollback driver is not configured")}})),resolveHealthGate:async(L,Qe)=>{let Ze=ct.listHealthChecks(Qe.projectId,Qe.environmentId).find((it)=>it.enabled&&it.name===L&&(!it.resourceId||it.resourceId===Qe.resourceId));if(!Ze)return{healthy:!1,message:`Named health gate ${L} was not found for this release.`};let He=await new Me(ct).runAndEvaluate(Ze);return{healthy:He.result.status==="healthy",evidence:{healthCheckId:Ze.id,healthResultId:He.result.id,status:He.result.status,timings:He.result.timings},message:He.result.message}}})},{parallelism:e.queueParallelism??(Number(process.env.TS_CLOUD_QUEUE_PARALLELISM)||8),onError:(L)=>console.error("ts-cloud deployment queue worker failed:",L)}):void 0;if(Yd(E),Di(bt,ee(E,String(N)),z),Ut)Oi(E,Ut.users),$b(Fe,E,Ut.users);let gr=Db({cwd:t,enabled:Be,secret:It,authentication:Fe,authorization:{store:E.store,organizationId:E.organization.id,projectId:E.project.id,defaultEnvironment:String(N)}}),Rr=new Ro,mf=setInterval(()=>Rr.sweep(),60000);mf.unref?.();let Dc=new Ec,Hu=new Ec(3,900000,900000),Oc=new Ec(8,900000,900000),gf=setInterval(()=>Dc.prune(),300000),ff=setInterval(()=>Hu.prune(),300000),hf=setInterval(()=>Oc.prune(),300000);if(gf.unref?.(),ff.unref?.(),hf.unref?.(),Be){if(Ut?.generated)console.warn(`
676
+ [output truncated]`}async function DS(e,t,r){let o=e.getReader(),m=new TextDecoder,h="";while(!0){let{done:R,value:A}=await o.read();if(R)break;let E=m.decode(A,{stream:!0});if(h+=E,E)r?.(t,E)}let I=m.decode();if(I)h+=I,r?.(t,I);return h}async function Hg(e,t){let r=Bun.spawn([process.execPath,t.cliEntry,...e.command],{cwd:t.cwd,stdout:"pipe",stderr:"pipe",env:{...process.env,...t.env}}),o=()=>{try{r.kill()}catch{}};if(t.signal?.aborted)o();else t.signal?.addEventListener("abort",o,{once:!0});try{let[m,h,I]=await Promise.all([DS(r.stdout,"stdout",t.onOutput),DS(r.stderr,"stderr",t.onOutput),r.exited]);return{action:e.id,command:["cloud",...e.command].join(" "),exitCode:I,ok:I===0,stdout:xS(m),stderr:xS(h)}}finally{t.signal?.removeEventListener("abort",o)}}function eT(){return Object.entries(process.env).filter(([e,t])=>!!t&&t.length>=8&&/(?:secret|token|password|passwd|private|credential|api.?key|access.?key)/i.test(e)).map(([,e])=>e)}var tT=new Set(["/server/sites","/server/deployments","/server/logs","/integrations","/applications/new","/applications/compose","/operations/queue","/operations/previews","/operations/releases","/operations/workloads","/operations/observability","/operations/alerts","/operations/jobs","/data/backups","/account/security","/security","/access-denied"]);function rT(e){let t=_c(e);if(t&&t!==".html")return!1;let r=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(r==="/")return!1;return!tT.has(r)}var nT={"/":"runtime:read","/server/activity":"audit:read","/server/sites":"project:read","/server/deployments":"deployments:read","/server/logs":"runtime:logs","/server/metrics":"runtime:read","/server/services":"runtime:read","/data/backups":"backups:read","/data/volumes":"data:read","/server/fleet":"fleet:read","/server/capacity":"fleet:read","/server/actions":"runtime:restart","/server/database":"data:read","/server/firewall":"fleet:read","/infrastructure/topology":"fleet:read","/server/security":"security:read","/security":"security:read","/integrations":"sources:read","/applications/new":"applications:read","/applications/compose":"applications:read","/operations/queue":"deployments:read","/operations/previews":"deployments:read","/operations/releases":"deployments:read","/operations/regions":"deployments:read","/operations/maintenance":"deployments:read","/operations/workloads":"runtime:read","/operations/observability":"runtime:logs","/operations/alerts":"runtime:read","/operations/jobs":"automation:read","/operations/configuration":"config:read","/server/ssh-keys":"fleet:read","/server/terminal":"runtime:terminal","/server/team":"users:read","/account/security":"project:read","/account/automation":"users:read","/serverless":"project:read","/serverless/deployments":"deployments:read","/serverless/logs":"runtime:logs","/serverless/metrics":"runtime:read","/serverless/traces":"runtime:read","/serverless/functions":"config:read","/serverless/queues":"data:read","/serverless/data":"data:read","/serverless/assets":"project:read","/serverless/secrets":"secrets:read","/serverless/firewall":"fleet:read","/serverless/alarms":"runtime:read","/serverless/cost":"project:read"};function OS(e,t){if(t.role==="admin")return!0;let r=_c(e);if(r&&r!==".html")return!0;if(t.organizationSource==="legacy")return!rT(e);let o=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(o==="/access-denied")return!0;let m=nT[o];return!!m&&!!t.capabilities?.includes(m)}function iT(e,t){let r=decodeURIComponent(t).replace(/^\/+/,""),m=C_(r===""?"index.html":r);if(m.startsWith("..")||m.includes("/../"))return null;let h=rr(e,m);if(Zi(h)&&!MS(h).isDirectory())return h;if(!_c(h)&&Zi(`${h}.html`))return`${h}.html`;if(!_c(h)&&Zi(rr(h,"index.html")))return rr(h,"index.html");return null}async function $S(e,t){let r=iT(e,t);if(!r){let h=rr(e,"404.html");if(Zi(h))return new Response(await pi(h),{status:404,headers:{"content-type":"text/html; charset=utf-8"}});return Fu("Not found",404)}if(MS(r).isDirectory())return Fu("Not found",404);let o=await pi(r),m=j_[_c(r)]??"application/octet-stream";return new Response(o,{headers:{"content-type":m}})}var Bu=["observe","backup","restore","restart","resize","version","rotate","expose","delete","logs","slow_queries","users","databases"],NS=new WeakMap;async function jS(e){let t=NS.get(e);if(t)return t;let r=await import("./spend/index.js"),o=new r.SpendStore(e),m={store:o,service:new r.SpendService(o),gate:new r.SpendGate(e)};return NS.set(e,m),m}async function ga(e={}){N_();let t=e.cwd??process.cwd(),r=e.host??D_,o=e.port??O_,m=e.cliEntry??process.argv[1];if(e.box)process.env.TS_CLOUD_DASHBOARD_BOX="1";await V_(t);let h=e.config??await wd(),I=process.env.TS_CLOUD_DASHBOARD_DB_PASSWORD,R=p(h);if(I&&R&&!R.password)R.password=I;let A=h.infrastructure?.compute?.managedServices?.vitess;if(I&&A&&typeof A==="object"&&!A.password)A.password=I;let E=Rl(t,h);if(E.reconciliation.failed>0)console.warn(` ts-cloud dashboard: marked ${E.reconciliation.failed} orphaned operation(s) as failed after restart.`);let x=Object.keys(h.environments??{}),N=U_(h,e.environment),F=W_(t),z=await Ks(h,N),H=new Map([[N,z]]),K=new Map([[N,Date.now()]]),X=new Map([[N,Date.now()]]),oe=new Map,ye=Math.min(300000,Math.max(5000,Number(process.env.TS_CLOUD_DASHBOARD_REFRESH_MS)||30000)),ne=Math.min(1800000,Math.max(60000,Number(process.env.TS_CLOUD_DASHBOARD_SITE_REFRESH_MS)||300000)),fe=O(h)!=="serverless",Ce=(L)=>{let Ge=H.get(L);if(Ge&&!PS(K.get(L),Date.now(),ye))return Promise.resolve(Ge);let Ye=oe.get(L);if(Ye)return Ye;let Je=!fe||PS(X.get(L),Date.now(),ne),it=Ks(h,L,{includeSiteHealth:Je}).then((Tt)=>{let W=H.get(L),un=Je?Tt:Y_(W,Tt);if(H.set(L,un),K.set(L,Date.now()),Je)X.set(L,Date.now());if(W?._serverReachable!==un._serverReachable||W?._metricsStatus!==un._metricsStatus||(W?.sitesDetail?.length??0)!==(un.sitesDetail?.length??0))st();return un}).finally(()=>oe.delete(L));return oe.set(L,it),it},xe=Pt(t),he=process.env.TS_CLOUD_DASHBOARD_TELEMETRY?.trim();if(e.box&&he!=="0"&&(he==="1"||!h.cloud?.attachTo)){let L=!1,Ge=Date.now()+300000,Ye=async()=>{if(L)return;L=!0;try{let it=Date.now(),Tt=it>=Ge;if(Tt)Ge=it+300000;let W=E.environments.get(N);await Fg({controlPlane:E.store,projectId:E.project.id,environmentId:W?.id,config:h,environment:N,force:!0,lightweight:!0,includeSiteHealth:Tt})}catch(it){if(e.verbose)console.warn(` ts-cloud dashboard: background telemetry collection failed: ${it instanceof Error?it.message:String(it)}`)}finally{L=!1}};Ye(),setInterval(()=>void Ye(),60000).unref?.()}let me=new Map,He=new Map,nt=new Set,wt=0;function cr(L,Ge){if(L.role==="admin"&&!E.store.getActorByExternalId("user",`dashboard:${L.username.toLowerCase()}`))return L;let Ye=E.store.getActorByExternalId("user",`dashboard:${L.username.toLowerCase()}`),Je=Ye?E.store.getMembershipForActor(E.organization.id,Ye.id):void 0;if(!Je||Je.status!=="active")return{...L,role:"member",sites:{},capabilities:[]};let it=E.store.listGrants(Je.id),Tt=E.store.resolveAuthorizationTarget(E.organization.id,Je.scope)??E.store.resolveAuthorizationTarget(E.organization.id,{type:"project",id:E.project.id}),W=Bt({membership:Je,grants:it,target:Tt});if(Je.roleTemplate==="owner"||Je.roleTemplate==="admin")return{...L,role:"admin",sites:{},organizationRole:Je.roleTemplate,organizationSource:Je.source,capabilities:W};let un=E.environments.get(Ge),kr={};for(let dt of E.store.listResources(E.project.id,un?.id).filter((St)=>St.kind==="application")){let St=E.store.resolveAuthorizationTarget(E.organization.id,{type:"resource",id:dt.id});if(!St||!w({membership:Je,grants:it,capability:"project:read",target:St}).allowed)continue;kr[dt.slug]=w({membership:Je,grants:it,capability:"config:write",target:St}).allowed?"owner":"collaborator"}return{...L,role:"member",sites:kr,organizationRole:Je.roleTemplate,organizationSource:Je.source,capabilities:W}}function st(){wt+=1,me.clear();for(let L of nt)Gs(L,{recursive:!0,force:!0});nt.clear()}let Ft=(L,Ge)=>`${Ge}:${L.role==="admin"?"admin":`member:${Object.entries(L.sites).sort(([Ye],[Je])=>Ye.localeCompare(Je)).map(([Ye,Je])=>`${Ye}=${Je}`).join(",")}`}:${[...L.capabilities??[]].sort().join(",")}`;async function dr(L,Ge){let Ye=cr(L,Ge),Je=Ft(Ye,Ge),it=me.get(Je);if(it)return it;let Tt=He.get(Je);if(Tt)return Tt;let W=wt,un=(async()=>{let kr=H.get(Ge)??await Ks(h,Ge);H.set(Ge,kr);let dt={...Tg(kr,{user:Ye,slug:h.project.slug}),viewer:{role:Ye.role,organizationRole:Ye.organizationRole,organizationSource:Ye.organizationSource,capabilities:Ye.capabilities??[]}},St=await X_(t,dt);if(St&&W!==wt)return Gs(St,{recursive:!0,force:!0}),xe?.uiRoot;if(St)nt.add(St);let nn=St??xe?.uiRoot;if(nn)me.set(Je,nn);return nn})();He.set(Je,un);try{return await un}finally{He.delete(Je)}}let vt=await dr({username:"",passwordHash:"",role:"admin",sites:{}},N);if(!vt)throw Error("ts-cloud dashboard UI not found. Run `bun run build` in ts-cloud or reinstall the package.");let Y=new WeakMap,be=process.env.TS_CLOUD_DASHBOARD_TERMINAL!=="0",Ee=process.env.TS_CLOUD_DASHBOARD_AUTH==="0";if(Ee&&e.box)throw Error("TS_CLOUD_DASHBOARD_AUTH=0 is refused in box mode: the dashboard is internet-facing there, and disabling auth would expose a root shell.");let Ne=!Ee,It=Cb(t),Ut=Ne?xb(t,process.env.TS_CLOUD_UI_USERNAME?.trim()||"admin"):void 0,Le=new bi(E.store,{encryptionKey:Ve(t)}),Ct=new Ei(E.store),bt=new Fr(E.store),rt=new Ao(E.store,{encryptionKey:Ve(t)}),ln=new ip(E.store),Qs=new cp(E.store,{cwd:t}),Zn=new sp(E.store,{encryptionKey:Ve(t)}),nr=new c(E.store,{workerId:`dashboard:${process.pid}`}),lr=new ko(E.store),mi=new Uo(E.store,Ve(t)),Xi=new ca(E.store),Tc=new ki(lr,nr,mi),eo=h.project?.region??"us-east-1",Qg=Ve(t),Rn=new pa(Xi,{encryptionKey:Qg,backends:[new Xr(E.store,Qg),new da(new V(eo),eo),new la(new Ie(eo),eo),new ua]});await Fl(Rn,E,h);let zu=new j(eo),LS={aws_rds:new Bo(new $o(zu)),aws_aurora:new xo(new Mo(zu)),aws_elasticache:new _o(new Fo(new Xe(eo))),server:new Oo(new jt),container:new Lo(new jt)},ef=(L)=>LS[L.provider],Er=new ea(E.store),fs=new Mi(Er,nr),tf=new ta(mi),FS={managed_database:new ra(lr,zu),logical_database:new ia(lr,mi),volume:new sa,files:new na(t),control_plane:new oa(E.store,t),infrastructure:new aa(new Jt(eo))},zS=(L)=>FS[L.resourceKind],US=(L)=>L.provider==="aws_backup"?void 0:tf,Uu=new xt(E.store),qu=[new Sr,new vs(d(t,"volumes"))],gi=new Es(Uu,qu,nr),Qa=new Qo(E.store),ti=new Ho(Qa,[new qr("aws"),new qr("hetzner"),new qr("ssh")],nr),to=new Go(E.store),rf=new qo(to,Qa),hs=new Vo(E.store),nf=new jo(hs,nr),fi=new Ko(E.store),Vu=new Wo(fi,nr),of=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((L)=>new Jo(L,E.store,E.project.id,E.organization.id)),Zr=new Do(E.store),sf=new No(Zr,{queue:nr}),wr=new Ir(E.store),ro=new Cr(E.store),$n=new lt(E.store),ct=new ii(E.store,{encryptionKey:Ve(t)}),qS=()=>jS(E.store);for(let L of E.environments.values())Po(Zr,h,{organization:E.organization,project:E.project,environment:L,resources:E.store.listResources(E.project.id,L.id)});let Nn=new si(ct,{emailImpl:async(L)=>{let{email:Ge}=await import("./chunk-w7710vzg.js");return Ge.send(L)}}),af=async(L)=>{let Ge=$s(ct,E.project.id,L),Ye=[];for(let Je of Ge.filter((it)=>it.notify&&it.alert))Ye.push(...await Nn.deliverAll(Nn.enqueue(E.organization.id,Je.alert,Je.transition)));return Ye.push(...await Nn.deliverAll(Nn.enqueueRemindersAndEscalations(E.organization.id,ct.listAlerts(E.project.id,{environmentId:L,states:["firing"]})))),Ye.push(...await Nn.retryDue()),{evaluations:Ge,deliveries:Ye}},Wu=!1,VS=async()=>{if(Wu)return;Wu=!0;try{for(let L of E.environments.values())for(let Ge of ct.listHealthChecks(E.project.id,L.id).filter((Ye)=>Ye.enabled)){let Ye=ct.listHealthResults(Ge.id,1)[0];if(Ye&&Date.now()-new Date(Ye.checkedAt).getTime()<Ge.intervalSeconds*1000)continue;let Je=await new Fe(ct).runAndEvaluate(Ge);for(let it of Je.evaluations.filter((Tt)=>Tt.notify&&Tt.alert))await Nn.deliverAll(Nn.enqueue(E.organization.id,it.alert,it.transition))}}finally{Wu=!1}},cf=setInterval(()=>{for(let L of E.environments.values())af(L.id).catch((Ge)=>console.error("ts-cloud alert evaluation failed:",Ge))},60000);cf.unref?.();let df=setInterval(()=>{VS().catch((L)=>console.error("ts-cloud health check evaluation failed:",L))},30000);df.unref?.();let lf=setInterval(()=>{try{sf.tick()}catch(L){console.error("ts-cloud scheduled job evaluation failed:",L)}},30000);lf.unref?.();let uf=setInterval(()=>{try{fs.enqueueDue(),fs.enqueueRetention()}catch(L){console.error("ts-cloud backup policy evaluation failed:",L)}},30000);uf.unref?.(),wr.cleanup();let pf=setInterval(()=>{try{wr.cleanup()}catch(L){console.error("ts-cloud preview cleanup failed:",L)}},3600000);pf.unref?.();let WS=e.queueWorker??!0,HS=eT(),KS=async(L,Ge)=>{let Je=(L.environmentId?E.store.listEnvironments(L.projectId).find((it)=>it.id===L.environmentId):void 0)?.slug??String(N);if(Ge.kind==="dashboard_operation"&&Ge.operationId){let it=H.get(Je)??z,Tt=_g(Ge.operationId,h,it);if(!Tt||Tt.danger||!["scheduler","backup","worker"].includes(Tt.group))return{ok:!1,stderr:"The allowlisted dashboard operation is no longer available."};let W=await $u(h,Je,Tt);return{ok:W.ok,stdout:W.stdout,stderr:W.stderr??W.error,retryable:/temporar|unavailable|timeout|network/i.test(W.stderr??W.error??""),output:{command:W.command??null,operation:W.operation}}}if(Ge.kind==="serverless_scheduler"){let it=await Lg(h,Je,"run");return{ok:it.ok,stdout:it.stdout,stderr:it.error,retryable:/temporar|unavailable|timeout|network/i.test(it.error??""),output:{command:it.command??null,operation:"serverless_scheduler"}}}return{ok:!1,stderr:`No safe executor is configured for ${Ge.kind}.`}},xc=WS?new Cs(nr,{...Sc({store:E.store,execute:async(L,Ge)=>{let Ye=Ge.operation.input&&typeof Ge.operation.input==="object"&&!Array.isArray(Ge.operation.input)?Ge.operation.input:{},Je=Ye.source&&typeof Ye.source==="object"?Ye.source:void 0,it=t,Tt,W,un;try{if(Je?.bindingId&&Je?.connectionId&&Je?.commitSha){let dt=rt.getBinding(String(Je.bindingId)),St=rt.getConnection(String(Je.connectionId));if(!dt||!St||dt.connectionId!==St.id)throw Error("Queued source binding is no longer available");let Dr=(dt.repositoryId?rt.getRepository(dt.repositoryId):rt.listRepositories(St.id).find((Xs)=>Xs.fullName.toLowerCase()===dt.repositoryFullName.toLowerCase()))?.cloneUrl;if(!Dr&&St.provider==="generic_ssh")Dr=`git@${new URL(St.host).hostname}:${dt.repositoryFullName}.git`;if(!Dr)Dr=new URL(`/${dt.repositoryFullName}.git`,St.host.endsWith("/")?St.host:`${St.host}/`).href;let De=dt.deployKeyId?rt.getDeployKey(dt.deployKeyId):void 0,ur=De&&dt.deployKeyId?{...De,privateKey:rt.getDeployPrivateKey(dt.deployKeyId)}:void 0;if(["github","gitlab","bitbucket","gitea"].includes(St.provider)&&L.target.previewId){let Xs=je(St,rt.getCredential(St.id)),Se=wr.previews.getInstance(L.target.previewId);un=async(jn,jc)=>{try{await Xs.setCommitStatus(dt.repositoryFullName,String(Je.commitSha),{state:jn,url:Se?.url,description:jc})}catch(ma){Ge.log(`Could not publish source status: ${ma instanceof Error?ma.message:String(ma)}`,{stream:"stderr"})}},await un("pending",`Preview deployment started for ${String(Je.commitSha).slice(0,12)}`)}Tt=Gg(rr(Lu(),"ts-cloud-queued-source-")),Ge.log(`Checking out immutable source commit ${Je.commitSha}.`,{stream:"system"}),it=(await Io({remote:Dr,binding:dt,destination:rr(Tt,"checkout"),ref:String(Je.branch??dt.defaultBranch),commitSha:String(Je.commitSha)},{credential:rt.getCredential(St.id),deployKey:ur})).directory}if(Ge.operation.kind!=="preview.destroy"){let dt=L.target.previewId?wr.previews.getInstance(L.target.previewId):void 0,St=dt?wr.previews.getDefinition(dt.definitionId):void 0,nn=Ge.operation.resourceId?E.store.getResource(Ge.operation.resourceId):void 0;if(W=await Rn.resolve({projectId:E.project.id,environmentId:Ge.operation.environmentId,resourceId:Ge.operation.resourceId,functionId:nn?.kind==="function"?nn.id:void 0,previewId:dt?.id,trustedPreview:!!dt&&!dt.fork,allowedPreviewSecrets:St?.inheritedSecrets}),W.warnings.some((Dr)=>Dr.code==="missing_required"))throw Error(`Required deployment configuration is unavailable: ${W.warnings.filter((Dr)=>Dr.code==="missing_required").map((Dr)=>Dr.key).join(", ")}`);if(Ge.operation.resourceId)for(let Dr of Object.values(W.entries))Xi.setDependency({entryId:Dr.id,resourceId:Ge.operation.resourceId,injectionTarget:"environment",required:Dr.required,requiresRedeploy:!0});Ge.log(`Resolved configuration ${W.configurationHash.slice(0,18)} for ${Object.keys(W.values).length} keys.`,{stream:"system"})}let kr=await Hg(L,{cwd:it,cliEntry:m,signal:Ge.signal,env:W?.values,onOutput:(dt,St)=>Ge.log(St,{stream:dt,step:"execute",secrets:[...HS,...Object.entries(W?.entries??{}).filter(([,nn])=>nn.kind==="secret").map(([nn])=>W.values[nn]).filter(Boolean)]})});if(kr.ok&&Ge.operation.resourceId&&W)for(let dt of Object.values(W.entries))Xi.setDependency({entryId:dt.id,resourceId:Ge.operation.resourceId,injectionTarget:"environment",required:dt.required,requiresRedeploy:!1,lastDeployedVersion:dt.version});return await un?.(kr.ok?"success":"failure",kr.ok?`Preview is ready at ${String(Je?.commitSha).slice(0,12)}`:`Preview deployment failed at ${String(Je?.commitSha).slice(0,12)}`),kr}catch(kr){throw await un?.("error",`Preview deployment could not complete at ${String(Je?.commitSha).slice(0,12)}`),kr}finally{if(Tt)Gs(Tt,{recursive:!0,force:!0})}}}),...al({store:Zr,executor:KS}),...dl({store:lr,secrets:mi,resolveAdapter:ef}),...pl(Qa,ti.drivers),...ml(hs,[new zo("aws","AWS regional execution requires an injected AwsRegionalTransport; topology and plans were preserved without provider mutation.")]),...Il({store:fi,cleanup:of}),...Cc(Uu,qu),..._l({store:Er,queue:nr,resolveSource:zS,resolveDestination:US,validateHealth:async(L,Ge)=>{if(!L.healthCheckId)return{healthy:!0,mode:"adapter"};let Ye=ct.getHealthCheck(L.healthCheckId);if(!Ye||Ye.projectId!==L.projectId)return{healthy:!1,error:"Configured restore health check was not found."};let Je=await new Fe(ct).runAndEvaluate(Ye);return{healthy:Je.result.status==="healthy",healthCheckId:Ye.id,healthResultId:Je.result.id,target:Ge}}}),...Fd({store:E.store,resolveDriver:e.releaseDriver??((L)=>({name:`${E.store.getResource(L.resourceId)?.provider??"provider"} release driver`,capability:()=>({strategy:L.strategy,supported:!1,explanation:"This dashboard process has no immutable activation driver configured for the target provider.",capacityMultiplier:1,costImpact:"none",rollback:"The previous release remains preserved; configure a release driver before retrying."}),activate:async()=>{throw Error("Immutable activation driver is not configured")},rollback:async()=>{throw Error("Immutable rollback driver is not configured")}})),resolveHealthGate:async(L,Ge)=>{let Ye=ct.listHealthChecks(Ge.projectId,Ge.environmentId).find((it)=>it.enabled&&it.name===L&&(!it.resourceId||it.resourceId===Ge.resourceId));if(!Ye)return{healthy:!1,message:`Named health gate ${L} was not found for this release.`};let Je=await new Fe(ct).runAndEvaluate(Ye);return{healthy:Je.result.status==="healthy",evidence:{healthCheckId:Ye.id,healthResultId:Je.result.id,status:Je.result.status,timings:Je.result.timings},message:Je.result.message}}})},{parallelism:e.queueParallelism??(Number(process.env.TS_CLOUD_QUEUE_PARALLELISM)||8),onError:(L)=>console.error("ts-cloud deployment queue worker failed:",L)}):void 0;if(Yd(E),Di(bt,ee(E,String(N)),z),Ut)Oi(E,Ut.users),$b(Le,E,Ut.users);let gr=Db({cwd:t,enabled:Ne,secret:It,authentication:Le,authorization:{store:E.store,organizationId:E.organization.id,projectId:E.project.id,defaultEnvironment:String(N)}}),Rr=new Ro,mf=setInterval(()=>Rr.sweep(),60000);mf.unref?.();let Dc=new Ec,Hu=new Ec(3,900000,900000),Oc=new Ec(8,900000,900000),gf=setInterval(()=>Dc.prune(),300000),ff=setInterval(()=>Hu.prune(),300000),hf=setInterval(()=>Oc.prune(),300000);if(gf.unref?.(),ff.unref?.(),hf.unref?.(),Ne){if(Ut?.generated)console.warn(`
677
677
  ts-cloud dashboard: created the first admin.
678
678
  username: ${Ut.generated.username}
679
679
  password: ${Ut.generated.password}
680
680
  Saved (hashed) to ${_b()}. This password is shown once.
681
- `)}else console.warn(" ts-cloud dashboard: authentication is DISABLED (TS_CLOUD_DASHBOARD_AUTH=0). Every request runs as an admin.");let no=r!=="127.0.0.1"&&r!=="localhost",Ku=(L)=>R_("sha256").update(`${It}:${L}`).digest("hex").slice(0,16),JS=bo({controlPlane:E.store,identities:Ct,sources:rt,applications:{drafts:ln,artifacts:Qs,registries:Zn}}),yf=(L)=>L.headers.get("user-agent")?.trim().slice(0,256)||void 0,$c=(L,Qe,Ze,He="local")=>Fe.createSession({identityId:L,authMethod:He,userAgent:yf(Qe),networkHint:Ku(Ze)}),Xe=(L)=>{let Qe=E.store.getActorByExternalId("user",`dashboard:${L.username.toLowerCase()}`),Ze=Qe?E.store.getMembershipForActor(E.organization.id,Qe.id):void 0;return{actor:Qe,membership:Ze,grants:Ze?E.store.listGrants(Ze.id):[]}},Ys=(L,Qe,Ze)=>{if(L.role==="admin")return!0;let He=E.store.getOperation(Qe),it=Xe(L);if(!He||!it.membership)return!1;let Tt=He.resourceId?{type:"resource",id:He.resourceId}:He.environmentId?{type:"environment",id:He.environmentId}:He.projectId?{type:"project",id:He.projectId}:{type:"organization"},W=E.store.resolveAuthorizationTarget(E.organization.id,Tt);return!!W&&w({membership:it.membership,grants:it.grants,capability:Ze,target:W}).allowed},rn=(L,Qe,Ze)=>{if(L.role==="admin")return!0;let He=Xe(L);if(!He.membership)return!1;let it=E.store.resolveAuthorizationTarget(E.organization.id,{type:"resource",id:Qe});return!!it&&w({membership:He.membership,grants:He.grants,capability:Ze,target:it}).allowed},Ya=(L,Qe,Ze)=>{if(L.role==="admin")return!0;let He=Xe(L);if(!He.membership)return!1;let it=E.store.resolveAuthorizationTarget(E.organization.id,{type:"environment",id:Qe});return!!it&&w({membership:He.membership,grants:He.grants,capability:Ze,target:it}).allowed},Nc=(L,Qe)=>{if(L.role==="admin")return!0;let Ze=Xe(L);if(!Ze.membership)return!1;let He=E.store.resolveAuthorizationTarget(E.organization.id,{type:"organization"});return!!He&&w({membership:Ze.membership,grants:Ze.grants,capability:Qe,target:He}).allowed},Zs=Bun.serve({hostname:r,port:o,idleTimeout:30,websocket:{open(L){if(!be){L.send(`The web terminal is disabled (TS_CLOUD_DASHBOARD_TERMINAL=0).\r
682
- `),L.close();return}let Qe=RS((Ze)=>L.send(Ze),{cwd:t,onExit:()=>{try{L.close()}catch{}}});Y.set(L,Qe),L.send(`Connected to ${r==="127.0.0.1"?"localhost":r} shell. This is a line-oriented shell (no full-screen apps).\r
683
- `)},message(L,Qe){Y.get(L)?.write(typeof Qe==="string"?Qe:new TextDecoder().decode(Qe))},close(L){Y.get(L)?.close(),Y.delete(L)}},async fetch(L,Qe){let Ze=Date.now(),He=L.clone(),it=L.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),Tt=!["GET","HEAD","OPTIONS"].includes(L.method.toUpperCase()),W=new URL(L.url),kr=await(async()=>{let dt=Qe??Zs,St=z_(r,dt.port??o),nn=await JS(L,Ku(dt.requestIP(L)?.address??"unknown"));if(nn)return nn;let Dr=W.searchParams.get("env"),De=q_(x,N,Dr),ur=H.get(De);if(!ur)ur=await Ce(De);try{if(!K_(L))return M({ok:!1,error:"Cross-site requests are not allowed."},403);let bs=/^\/api\/source\/webhooks\/([A-Za-z0-9_-]{16,200})$/.exec(W.pathname);if(bs&&L.method==="POST"){let T=await qd({sources:rt,controlPlane:E.store,endpointToken:bs[1],headers:L.headers,rawBody:new Uint8Array(await L.arrayBuffer())});return M({accepted:T.accepted,duplicate:T.duplicate,status:T.status,operationIds:T.operations.map((D)=>D.id),message:T.message},T.accepted?202:404)}let Xs=/^\/auth\/oidc\/([a-z0-9-]+)\/(start|callback)$/.exec(W.pathname);if(Xs&&L.method==="GET"){let[,T,D]=Xs;if(!St)return new Response(null,{status:302,headers:{location:"/login?sso_error=configuration"}});if(D==="start")try{let U=await go(Fe,T,St,W.searchParams.get("return")??void 0,e.oidcFetch);return new Response(null,{status:302,headers:{location:U.authorizationUrl,"cache-control":"no-store"}})}catch(U){return E.store.appendEvent({organizationId:E.organization.id,type:"auth.oidc.start_failed",level:"warning",payload:{provider:T,reason:U instanceof Error?U.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=start","cache-control":"no-store"}})}try{if(W.searchParams.has("error")){let Z=Fe.getOidcProviderBySlug(T),Q=W.searchParams.get("state");if(Z&&Q)Fe.consumeOidcTransaction(Z.id,Q);throw Error("OIDC provider returned an authorization error")}let U=await mo(Fe,{providerSlug:T,state:W.searchParams.get("state")??"",code:W.searchParams.get("code")??"",origin:St},e.oidcFetch),q=Nb(Fe,E,t,U.identity);Fe.recordLogin(q.identity.id);let G=$c(q.identity.id,L,dt.requestIP(L)?.address??"unknown","oidc");return st(),E.store.appendEvent({organizationId:E.organization.id,actorId:q.identity.actorId,type:"auth.login.succeeded",payload:{method:"oidc",provider:T,provisioned:q.provisioned}}),new Response(null,{status:302,headers:{location:U.returnPath,"cache-control":"no-store","set-cookie":Va(G.token,{secure:no,maxAgeMs:Ge})}})}catch(U){return E.store.appendEvent({organizationId:E.organization.id,type:"auth.oidc.callback_failed",level:"warning",payload:{provider:T,reason:U instanceof Error?U.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=callback","cache-control":"no-store"}})}}if(W.pathname==="/api/invitations/accept"&&L.method==="POST"){let T=await se(L),D=String(T.token??"").trim(),U=String(T.username??"").trim(),q=String(T.password??"");if(!D||!Tu(U)||q.length<12)return M({ok:!1,error:"Invitation token, valid username, and a password of at least 12 characters are required."},422);let G=E.store.inspectInvitationToken(D);if(!G||G.state!=="pending")return M({ok:!1,error:G?`Invitation is ${G.state}`:"Invitation is invalid"},G?409:404);let Z=Un(En(t),U),Q=Fe.getIdentityByUsername(U);if(Z&&!Yn(q,Q?.passwordHash??Z.passwordHash))return M({ok:!1,error:"That username already exists; enter its current password to continue."},401);let ie=Fe.getIdentityByEmail(G.email);if(ie&&ie.id!==Q?.id)return M({ok:!1,error:"This invitation belongs to an existing account. Sign in with that account or ask an owner to resend it."},409);let Ae=wc(t,{username:U,password:Z?void 0:q,name:typeof T.name==="string"?T.name:void 0,email:G.email,sites:Z?.sites??{}}),ke=S(E.store,Ae.user);try{let ot=E.store.acceptInvitation(D,ke.id),Oe=Q?Fe.setVerifiedEmail(Q.id,ot.invitation.email):Fe.createIdentity({actorId:ke.id,username:Ae.user.username,email:ot.invitation.email,emailVerified:!0,passwordHash:Ae.user.passwordHash}),et=$c(Oe.id,L,dt.requestIP(L)?.address??"unknown");return st(),M({ok:!0,user:Wa(Ae.user),organization:E.organization,membership:ot.membership},200,{"set-cookie":Va(et.token,{secure:no,maxAgeMs:Ge})})}catch(ot){if(!Z)Cg(t,Ae.user.username);let Oe=ot instanceof Error?ot.message:"Invitation could not be accepted.";return M({ok:!1,error:Oe},Oe.includes("expired")||Oe.includes("revoked")||Oe.includes("accepted")?409:404)}}if(W.pathname==="/api/auth/password-reset/request"&&L.method==="POST"){let T=await se(L),D=String(T.identifier??"").trim().toLowerCase(),U=dt.requestIP(L)?.address??"unknown",q=Hu.check(D,U),G=D.includes("@")?Fe.getIdentityByEmail(D):Fe.getIdentityByUsername(D);if(q.allowed)Hu.recordFailure(D,U);if(q.allowed&&G?.email&&G.emailVerifiedAt&&!G.disabledAt){Fe.revokeActionTokens(G.id,"password_reset");let Z=Fe.createActionToken(G.id,"password_reset"),Q=`${W.origin}/reset-password?token=${encodeURIComponent(Z.token)}`,ie=await Lr(h,{to:G.email,subject:"Reset your ts-cloud password",text:`Reset your ts-cloud password: ${Q}
681
+ `)}else console.warn(" ts-cloud dashboard: authentication is DISABLED (TS_CLOUD_DASHBOARD_AUTH=0). Every request runs as an admin.");let no=r!=="127.0.0.1"&&r!=="localhost",Ku=(L)=>R_("sha256").update(`${It}:${L}`).digest("hex").slice(0,16),JS=bo({controlPlane:E.store,identities:Ct,sources:rt,applications:{drafts:ln,artifacts:Qs,registries:Zn}}),yf=(L)=>L.headers.get("user-agent")?.trim().slice(0,256)||void 0,$c=(L,Ge,Ye,Je="local")=>Le.createSession({identityId:L,authMethod:Je,userAgent:yf(Ge),networkHint:Ku(Ye)}),Ze=(L)=>{let Ge=E.store.getActorByExternalId("user",`dashboard:${L.username.toLowerCase()}`),Ye=Ge?E.store.getMembershipForActor(E.organization.id,Ge.id):void 0;return{actor:Ge,membership:Ye,grants:Ye?E.store.listGrants(Ye.id):[]}},Ys=(L,Ge,Ye)=>{if(L.role==="admin")return!0;let Je=E.store.getOperation(Ge),it=Ze(L);if(!Je||!it.membership)return!1;let Tt=Je.resourceId?{type:"resource",id:Je.resourceId}:Je.environmentId?{type:"environment",id:Je.environmentId}:Je.projectId?{type:"project",id:Je.projectId}:{type:"organization"},W=E.store.resolveAuthorizationTarget(E.organization.id,Tt);return!!W&&w({membership:it.membership,grants:it.grants,capability:Ye,target:W}).allowed},rn=(L,Ge,Ye)=>{if(L.role==="admin")return!0;let Je=Ze(L);if(!Je.membership)return!1;let it=E.store.resolveAuthorizationTarget(E.organization.id,{type:"resource",id:Ge});return!!it&&w({membership:Je.membership,grants:Je.grants,capability:Ye,target:it}).allowed},Ya=(L,Ge,Ye)=>{if(L.role==="admin")return!0;let Je=Ze(L);if(!Je.membership)return!1;let it=E.store.resolveAuthorizationTarget(E.organization.id,{type:"environment",id:Ge});return!!it&&w({membership:Je.membership,grants:Je.grants,capability:Ye,target:it}).allowed},Nc=(L,Ge)=>{if(L.role==="admin")return!0;let Ye=Ze(L);if(!Ye.membership)return!1;let Je=E.store.resolveAuthorizationTarget(E.organization.id,{type:"organization"});return!!Je&&w({membership:Ye.membership,grants:Ye.grants,capability:Ge,target:Je}).allowed},Zs=Bun.serve({hostname:r,port:o,idleTimeout:30,websocket:{open(L){if(!be){L.send(`The web terminal is disabled (TS_CLOUD_DASHBOARD_TERMINAL=0).\r
682
+ `),L.close();return}let Ge=RS((Ye)=>L.send(Ye),{cwd:t,onExit:()=>{try{L.close()}catch{}}});Y.set(L,Ge),L.send(`Connected to ${r==="127.0.0.1"?"localhost":r} shell. This is a line-oriented shell (no full-screen apps).\r
683
+ `)},message(L,Ge){Y.get(L)?.write(typeof Ge==="string"?Ge:new TextDecoder().decode(Ge))},close(L){Y.get(L)?.close(),Y.delete(L)}},async fetch(L,Ge){let Ye=Date.now(),Je=L.clone(),it=L.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),Tt=!["GET","HEAD","OPTIONS"].includes(L.method.toUpperCase()),W=new URL(L.url),kr=await(async()=>{let dt=Ge??Zs,St=z_(r,dt.port??o),nn=await JS(L,Ku(dt.requestIP(L)?.address??"unknown"));if(nn)return nn;let Dr=W.searchParams.get("env"),De=q_(x,N,Dr),ur=H.get(De);if(!ur)ur=await Ce(De);try{if(!K_(L))return M({ok:!1,error:"Cross-site requests are not allowed."},403);let bs=/^\/api\/source\/webhooks\/([A-Za-z0-9_-]{16,200})$/.exec(W.pathname);if(bs&&L.method==="POST"){let T=await qd({sources:rt,controlPlane:E.store,endpointToken:bs[1],headers:L.headers,rawBody:new Uint8Array(await L.arrayBuffer())});return M({accepted:T.accepted,duplicate:T.duplicate,status:T.status,operationIds:T.operations.map((D)=>D.id),message:T.message},T.accepted?202:404)}let Xs=/^\/auth\/oidc\/([a-z0-9-]+)\/(start|callback)$/.exec(W.pathname);if(Xs&&L.method==="GET"){let[,T,D]=Xs;if(!St)return new Response(null,{status:302,headers:{location:"/login?sso_error=configuration"}});if(D==="start")try{let U=await go(Le,T,St,W.searchParams.get("return")??void 0,e.oidcFetch);return new Response(null,{status:302,headers:{location:U.authorizationUrl,"cache-control":"no-store"}})}catch(U){return E.store.appendEvent({organizationId:E.organization.id,type:"auth.oidc.start_failed",level:"warning",payload:{provider:T,reason:U instanceof Error?U.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=start","cache-control":"no-store"}})}try{if(W.searchParams.has("error")){let Z=Le.getOidcProviderBySlug(T),Q=W.searchParams.get("state");if(Z&&Q)Le.consumeOidcTransaction(Z.id,Q);throw Error("OIDC provider returned an authorization error")}let U=await mo(Le,{providerSlug:T,state:W.searchParams.get("state")??"",code:W.searchParams.get("code")??"",origin:St},e.oidcFetch),q=Nb(Le,E,t,U.identity);Le.recordLogin(q.identity.id);let G=$c(q.identity.id,L,dt.requestIP(L)?.address??"unknown","oidc");return st(),E.store.appendEvent({organizationId:E.organization.id,actorId:q.identity.actorId,type:"auth.login.succeeded",payload:{method:"oidc",provider:T,provisioned:q.provisioned}}),new Response(null,{status:302,headers:{location:U.returnPath,"cache-control":"no-store","set-cookie":Va(G.token,{secure:no,maxAgeMs:qe})}})}catch(U){return E.store.appendEvent({organizationId:E.organization.id,type:"auth.oidc.callback_failed",level:"warning",payload:{provider:T,reason:U instanceof Error?U.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=callback","cache-control":"no-store"}})}}if(W.pathname==="/api/invitations/accept"&&L.method==="POST"){let T=await se(L),D=String(T.token??"").trim(),U=String(T.username??"").trim(),q=String(T.password??"");if(!D||!Tu(U)||q.length<12)return M({ok:!1,error:"Invitation token, valid username, and a password of at least 12 characters are required."},422);let G=E.store.inspectInvitationToken(D);if(!G||G.state!=="pending")return M({ok:!1,error:G?`Invitation is ${G.state}`:"Invitation is invalid"},G?409:404);let Z=Un(En(t),U),Q=Le.getIdentityByUsername(U);if(Z&&!Yn(q,Q?.passwordHash??Z.passwordHash))return M({ok:!1,error:"That username already exists; enter its current password to continue."},401);let ie=Le.getIdentityByEmail(G.email);if(ie&&ie.id!==Q?.id)return M({ok:!1,error:"This invitation belongs to an existing account. Sign in with that account or ask an owner to resend it."},409);let Ae=wc(t,{username:U,password:Z?void 0:q,name:typeof T.name==="string"?T.name:void 0,email:G.email,sites:Z?.sites??{}}),ke=S(E.store,Ae.user);try{let ot=E.store.acceptInvitation(D,ke.id),Oe=Q?Le.setVerifiedEmail(Q.id,ot.invitation.email):Le.createIdentity({actorId:ke.id,username:Ae.user.username,email:ot.invitation.email,emailVerified:!0,passwordHash:Ae.user.passwordHash}),et=$c(Oe.id,L,dt.requestIP(L)?.address??"unknown");return st(),M({ok:!0,user:Wa(Ae.user),organization:E.organization,membership:ot.membership},200,{"set-cookie":Va(et.token,{secure:no,maxAgeMs:qe})})}catch(ot){if(!Z)Cg(t,Ae.user.username);let Oe=ot instanceof Error?ot.message:"Invitation could not be accepted.";return M({ok:!1,error:Oe},Oe.includes("expired")||Oe.includes("revoked")||Oe.includes("accepted")?409:404)}}if(W.pathname==="/api/auth/password-reset/request"&&L.method==="POST"){let T=await se(L),D=String(T.identifier??"").trim().toLowerCase(),U=dt.requestIP(L)?.address??"unknown",q=Hu.check(D,U),G=D.includes("@")?Le.getIdentityByEmail(D):Le.getIdentityByUsername(D);if(q.allowed)Hu.recordFailure(D,U);if(q.allowed&&G?.email&&G.emailVerifiedAt&&!G.disabledAt){Le.revokeActionTokens(G.id,"password_reset");let Z=Le.createActionToken(G.id,"password_reset"),Q=`${W.origin}/reset-password?token=${encodeURIComponent(Z.token)}`,ie=await Lr(h,{to:G.email,subject:"Reset your ts-cloud password",text:`Reset your ts-cloud password: ${Q}
684
684
 
685
- This link expires in one hour and can be used once.`});E.store.appendEvent({organizationId:E.organization.id,actorId:G.actorId,type:"auth.password_reset.requested",payload:{delivered:ie}})}return M({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(W.pathname==="/api/auth/password-reset/complete"&&L.method==="POST"){let T=await se(L),D=String(T.token??"").trim(),U=String(T.password??"");if(!D||U.length<12)return M({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let q=Fe.consumeActionToken(D,"password_reset"),G=ms(U),Z=Fe.updatePassword(q.identityId,G);return Du(t,Z.username,G),E.store.appendEvent({organizationId:E.organization.id,actorId:Z.actorId,type:"auth.password_reset.completed"}),M({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":_u({secure:no})})}catch(q){let G=q instanceof Error?q.message:"Password reset failed.";return M({ok:!1,error:G.replace("Action token","Reset link")},G.includes("consumed")||G.includes("expired")?409:404)}}if(W.pathname==="/api/login"&&L.method==="POST"){let T=await se(L),D=String(T.username??"").trim(),U=String(T.password??""),q=dt.requestIP(L)?.address??"unknown",G=Dc.check(D,q);if(!G.allowed)return M({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((G.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(G.retryAfterSeconds??60)});let Z=Un(En(t),D),Q=Fe.getIdentityByUsername(D),ie=Q?.passwordHash??Z?.passwordHash??F_;if(!(Yn(U,ie)&&!!Z&&!!Q&&!Q.disabledAt))return Dc.recordFailure(D,q),M({ok:!1,error:"Incorrect username or password."},401);if(jb(Fe,E,Q))return M({ok:!1,error:"Single sign-on is required for this account."},403);Dc.recordSuccess(D,q);let ke=Q,ot=ke.requiresPasswordUpgrade||Gv(ke.passwordHash);if(ot){let et=ms(U);ke=Fe.rehashPassword(ke.id,et),Du(t,ke.username,et)}if(Fe.recordLogin(ke.id),Fe.getMfaFactor(ke.id)?.state==="active"){let et=Fe.createMfaChallenge(ke.id,"login");return E.store.appendEvent({organizationId:E.organization.id,actorId:ke.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),M({ok:!0,mfaRequired:!0,challengeToken:et.token,passwordUpgraded:ot})}let Oe=$c(ke.id,L,q);return E.store.appendEvent({organizationId:E.organization.id,actorId:ke.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),M({ok:!0,user:Wa(Z),passwordUpgraded:ot},200,{"set-cookie":Va(Oe.token,{secure:no,maxAgeMs:Ge})})}if(W.pathname==="/api/auth/mfa/complete"&&L.method==="POST"){let T=await se(L),D=String(T.challengeToken??"").trim(),U=String(T.code??"").trim(),q=dt.requestIP(L)?.address??"unknown",Z=Fe.inspectMfaChallengeToken(D,"login")?.identityId??"unknown-mfa",Q=Oc.check(Z,q);if(!Q.allowed)return M({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(Q.retryAfterSeconds??60)});try{let ie=Fe.completeMfaChallenge(D,U,"login");Oc.recordSuccess(Z,q);let Ae=new Date().toISOString(),ke=Fe.createSession({identityId:ie.identity.id,userAgent:yf(L),networkHint:Ku(q),mfaAt:Ae,recentAuthAt:Ae});return E.store.appendEvent({organizationId:E.organization.id,actorId:ie.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:ie.method}}),M({ok:!0},200,{"set-cookie":Va(ke.token,{secure:no,maxAgeMs:Ge})})}catch{return Oc.recordFailure(Z,q),M({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(W.pathname==="/api/logout"&&L.method==="POST"){let T=gr.resolveSession(L);if(T)Fe.revokeSession(T.identityId,T.id);let D=_u({secure:no});if(L.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":D}});return M({ok:!0},200,{"set-cookie":D})}if(W.pathname==="/login"){let T=Fe.listOidcProviders(E.organization.id).map((D)=>({slug:D.slug,name:D.name}));return new Response(Mb(z?.mode==="serverless",T),{headers:{"content-type":"text/html; charset=utf-8"}})}if(W.pathname==="/forgot-password"||W.pathname==="/reset-password")return new Response(Bb(W.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(W.pathname==="/accept-invitation")return $S(vt,W.pathname);let Se=gr.resolveUser(L);if(!Se){if(!W.pathname.startsWith("/api/")&&L.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return M({ok:!1,error:"Sign in to continue."},401)}let jn=cr(Se,De);if(W.pathname==="/api/me"){let T=E.store.getActorByExternalId("user",`dashboard:${Se.username.toLowerCase()}`),D=T?E.store.getMembershipForActor(E.organization.id,T.id):void 0,U=E.store.resolveAuthorizationTarget(E.organization.id,D?.scope??{type:"project",id:E.project.id})??E.store.resolveAuthorizationTarget(E.organization.id,{type:"project",id:E.project.id});return M({ok:!0,user:Wa(Se),authEnabled:Be,organization:E.organization,membership:D,capabilities:Bt({membership:D,grants:D?E.store.listGrants(D.id):[],target:U})})}if(W.pathname.startsWith("/api/")){let T=await Ob(L,W.pathname),D=gr.check(L,W.pathname,Se,T);if(!D.ok)return M({ok:!1,error:D.error},D.status??403);if(Be&&Q_.has(`${L.method.toUpperCase()} ${W.pathname}`)){let U=gr.resolveSession(L);if(!U||!Fe.isRecentlyAuthenticated(U))return M({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(W.pathname==="/api/auth/security"&&L.method==="GET"){let T=Xe(Se),D=T.actor?Fe.getIdentityByActor(T.actor.id):void 0,U=gr.resolveSession(L);return M({identity:D?{username:D.username,email:D.email,emailVerifiedAt:D.emailVerifiedAt,requiresPasswordUpgrade:D.requiresPasswordUpgrade,lastLoginAt:D.lastLoginAt}:void 0,currentSessionId:U?.id,sessions:D?Fe.listSessions(D.id,{includeInactive:!0}):[],mfa:D?{factor:Fe.getMfaFactor(D.id),recoveryCodesRemaining:Fe.remainingRecoveryCodes(D.id)}:void 0})}if(W.pathname==="/api/auth/oidc/providers"&&L.method==="GET")return M({providers:Fe.listOidcProviders(E.organization.id,{includeDisabled:!0}),callbackOrigin:St,callbackPattern:St?`${St}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(W.pathname==="/api/auth/oidc/providers"&&L.method==="POST"){let T=await se(L),D=Xe(Se),U=D.actor?Fe.getIdentityByActor(D.actor.id):void 0,q=T.enforceSso===!0;if(q&&(!U?.emailVerifiedAt||Fe.remainingRecoveryCodes(U.id)<1))return M({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let G=Mu(T.defaultRole),Z=Fe.upsertOidcProvider({id:typeof T.id==="string"?T.id:void 0,organizationId:E.organization.id,slug:String(T.slug??""),name:String(T.name??""),issuer:String(T.issuer??""),clientId:String(T.clientId??""),clientSecret:typeof T.clientSecret==="string"&&T.clientSecret?T.clientSecret:void 0,scopes:Array.isArray(T.scopes)?T.scopes.map(String):void 0,allowedDomains:Array.isArray(T.allowedDomains)?T.allowedDomains.map(String):[],defaultRole:G&&G!=="owner"?G:void 0,enabled:T.enabled!==!1,enforceSso:q});return E.store.appendEvent({organizationId:E.organization.id,actorId:D.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:Z.id,issuer:Z.issuer,enabled:Z.enabled,enforceSso:Z.enforceSso}}),M({ok:!0,provider:Z})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"OIDC provider could not be saved."},422)}}if(W.pathname==="/api/auth/oidc/providers"&&L.method==="PATCH"){let T=await se(L),D=Fe.getOidcProvider(String(T.id??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"OIDC provider was not found."},404);let U=Xe(Se),q=Fe.setOidcProviderEnabled(D.id,T.enabled===!0);return E.store.appendEvent({organizationId:E.organization.id,actorId:U.actor?.id,type:q.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:D.id}}),M({ok:!0,provider:q})}if(W.pathname==="/api/automation"&&L.method==="GET"){let T=Ct.listServiceAccounts(E.organization.id,{includeDisabled:!0}).map((D)=>{let U=E.store.getMembershipForActor(E.organization.id,D.actorId),q=D.createdByActorId?E.store.getActor(D.createdByActorId):void 0,G=Ct.listTokens(D.id,{includeInactive:!0}).map((Z)=>({...Z,createdBy:Z.createdByActorId?E.store.getActor(Z.createdByActorId):void 0}));return{account:D,createdBy:q,membership:U,tokens:G}});return M({accounts:T,apiBaseUrl:`${W.origin}/api/v1`,openApiUrl:`${W.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(W.pathname==="/api/automation/service-accounts"&&L.method==="POST"){let T=await se(L),D=Xe(Se),U=Mu(T.roleTemplate),q=Pc(T);if(!D.actor||!U||U==="owner"||!q)return M({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let G=Ct.createServiceAccount({organizationId:E.organization.id,slug:String(T.slug??""),name:String(T.name??""),description:typeof T.description==="string"?T.description:void 0,roleTemplate:U,scope:q,createdByActorId:D.actor.id});return M({ok:!0,...G},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Service account could not be created."},422)}}if(W.pathname==="/api/automation/service-accounts"&&L.method==="PATCH"){let T=await se(L),D=Xe(Se),U=Ct.getServiceAccount(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Service account was not found."},404);return M({ok:!0,account:Ct.disableServiceAccount(U.id,D.actor?.id)})}if(W.pathname==="/api/automation/tokens"&&L.method==="POST"){let T=await se(L),D=Xe(Se),U=Ct.getServiceAccount(String(T.serviceAccountId??"")),q=Pc(T);if(!D.actor||!U||U.organizationId!==E.organization.id||!q||!Array.isArray(T.capabilities))return M({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let G=Ct.createToken({serviceAccountId:U.id,name:String(T.name??"API token"),capabilities:T.capabilities.map(String),scope:q,expiresAt:typeof T.expiresAt==="string"?T.expiresAt:void 0,createdByActorId:D.actor.id});return M({ok:!0,token:G.token,secret:G.secret,revealOnce:!0},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"API token could not be created."},422)}}if(W.pathname==="/api/automation/tokens/rotate"&&L.method==="POST"){let T=await se(L),D=Xe(Se),U=Ct.getToken(String(T.id??"")),q=U?Ct.getServiceAccount(U.serviceAccountId):void 0;if(!D.actor||!U||q?.organizationId!==E.organization.id)return M({ok:!1,error:"API token was not found."},404);try{let G=Ct.rotateToken(U.id,D.actor.id);return M({ok:!0,token:G.token,secret:G.secret,revealOnce:!0,overlap:!0},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"API token could not be rotated."},409)}}if(W.pathname==="/api/automation/tokens"&&L.method==="DELETE"){let T=await se(L),D=Xe(Se),U=Ct.getToken(String(T.id??"")),q=U?Ct.getServiceAccount(U.serviceAccountId):void 0;if(!U||q?.organizationId!==E.organization.id)return M({ok:!1,error:"API token was not found."},404);return M({ok:!0,token:Ct.revokeToken(U.id,D.actor?.id)})}if(W.pathname==="/api/onboarding"&&L.method==="GET"){let T=rt.listConnections(E.organization.id);return M({drafts:ln.list(E.project.id),artifacts:Qs.list(E.project.id),registries:Zn.list(E.organization.id),sourceConnections:T,repositories:T.flatMap((D)=>rt.listRepositories(D.id)),project:{id:E.project.id,slug:E.project.slug,name:E.project.name},environments:[...E.environments.values()].map((D)=>({id:D.id,slug:D.slug,name:D.name,kind:D.kind,region:D.region})),resources:E.store.listResources(E.project.id).filter((D)=>D.kind==="application").map((D)=>({id:D.id,slug:D.slug,name:D.name,environmentId:D.environmentId}))})}if(W.pathname==="/api/onboarding/detect"&&L.method==="POST"){let T=await se(L);try{if(T.source?.kind==="git"){let q=rt.getConnection(String(T.source.connectionId??"")),G=rt.getRepository(String(T.source.repositoryId??""));if(!q||q.organizationId!==E.organization.id||!G||G.connectionId!==q.id)throw Error("Authorized Git repository was not found");let Z=typeof T.source.deployKeyId==="string"?rt.getDeployKey(T.source.deployKeyId):void 0;if(Z&&Z.connectionId!==q.id)throw Error("Deploy key does not belong to this connection");let Q=Gg(rr(Lu(),"ts-cloud-onboarding-git-"));try{let ie=await Io({remote:G.cloneUrl,destination:rr(Q,"checkout"),ref:String(T.source.ref??G.defaultBranch),sparsePaths:Array.isArray(T.source.sparsePaths)?T.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:E.project.id,connectionId:q.id,repositoryId:G.id,repositoryFullName:G.fullName,defaultBranch:G.defaultBranch,monorepoRoot:String(T.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:T.source.submodules===!0,cloneDepth:1,deployKeyId:Z?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:rt.getCredential(q.id),deployKey:Z?{...Z,privateKey:rt.getDeployPrivateKey(Z.id)}:void 0,timeoutMs:120000});return M({ok:!0,commitSha:ie.commitSha,candidates:va(tp(ie.directory))})}finally{Gs(Q,{recursive:!0,force:!0})}}if(Array.isArray(T.files)){if(T.files.length>1e4)throw Error("Detection file-count limit exceeded");let q=T.files.map((G)=>({path:String(G.path??""),size:Number(G.size??0),content:typeof G.content==="string"?G.content.slice(0,262144):void 0}));return M({ok:!0,candidates:va(q)})}let D=__(t,String(T.root??".")),U=P_(t,D);if(U===".."||U.startsWith(`..${T_}`))throw Error("Detection root must stay inside the project");return M({ok:!0,candidates:va(tp(D))})}catch(D){return M({ok:!1,error:D instanceof Error?D.message:"Application detection failed."},422)}}if(W.pathname==="/api/onboarding/plan"&&L.method==="POST"){let T=await se(L);try{return M({ok:!0,plan:Vn(T.draft,Array.isArray(T.suppliedSecretNames)?T.suppliedSecretNames.map(String):[])})}catch(D){return M({ok:!1,error:D instanceof Error?D.message:"Application plan could not be generated."},422)}}if(W.pathname==="/api/onboarding/drafts"&&L.method==="POST"){let T=await se(L),D=Xe(Se);try{return M({ok:!0,draft:ln.create({organizationId:E.organization.id,projectId:E.project.id,name:String(T.name??T.draft?.name??"Application draft"),draft:{...T.draft,projectId:E.project.id},step:T.step,suppliedSecretNames:Array.isArray(T.suppliedSecretNames)?T.suppliedSecretNames.map(String):[],actorId:D.actor?.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Application draft could not be saved."},422)}}if(W.pathname==="/api/onboarding/drafts"&&L.method==="PATCH"){let T=await se(L),D=Xe(Se),U=ln.get(String(T.id??""));if(!U||U.projectId!==E.project.id)return M({ok:!1,error:"Application draft was not found."},404);try{return M({ok:!0,draft:ln.update(U.id,Number(T.version),{draft:{...T.draft,projectId:E.project.id},step:T.step,suppliedSecretNames:Array.isArray(T.suppliedSecretNames)?T.suppliedSecretNames.map(String):void 0,actorId:D.actor?.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Application draft could not be updated."},409)}}if(W.pathname==="/api/onboarding/artifacts"&&L.method==="POST"){let T=Xe(Se);if(Number(L.headers.get("content-length")??0)>104857600)return M({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let U=new Uint8Array(await L.arrayBuffer());return M({ok:!0,artifact:Qs.create({organizationId:E.organization.id,projectId:E.project.id,filename:L.headers.get("x-artifact-filename")??"application.zip",bytes:U,actorId:T.actor?.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Artifact could not be inspected."},422)}}if(W.pathname==="/api/onboarding/registries"&&L.method==="POST"){let T=await se(L),D=Xe(Se);try{return M({ok:!0,registry:Zn.create({organizationId:E.organization.id,provider:T.provider,name:String(T.name??"Container registry"),host:String(T.host??""),credential:T.token||T.password?{username:typeof T.username==="string"?T.username:void 0,password:typeof T.password==="string"?T.password:void 0,token:typeof T.token==="string"?T.token:void 0}:void 0,credentialExpiresAt:typeof T.credentialExpiresAt==="string"?T.credentialExpiresAt:void 0,actorId:D.actor?.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Registry connection could not be created."},422)}}if(W.pathname==="/api/onboarding/registries"&&L.method==="PATCH"){let T=await se(L),D=Xe(Se),U=Zn.get(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Registry connection was not found."},404);try{if(T.action==="test")return M({ok:!0,registry:await Zn.test(U.id,{image:typeof T.image==="string"?T.image:void 0})});if(T.action==="rotate")return M({ok:!0,registry:Zn.rotate(U.id,{username:typeof T.username==="string"?T.username:void 0,password:typeof T.password==="string"?T.password:void 0,token:typeof T.token==="string"?T.token:void 0},{expiresAt:typeof T.expiresAt==="string"?T.expiresAt:void 0,actorId:D.actor?.id})});return M({ok:!1,error:"Registry action must be test or rotate."},422)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Registry connection could not be updated."},422)}}if(W.pathname==="/api/onboarding/registries"&&L.method==="DELETE"){let T=await se(L),D=Xe(Se),U=Zn.get(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Registry connection was not found."},404);let q=ln.list(E.project.id).filter((G)=>G.input.source.kind==="image"&&G.input.source.registryConnectionId===U.id||G.input.build.kind==="prebuilt_image"&&G.input.build.registryConnectionId===U.id);if(T.preview===!0)return M({ok:!0,preview:!0,affectedDrafts:q});return M({ok:!0,registry:Zn.disconnect(U.id,D.actor?.id),affectedDrafts:q})}if(W.pathname==="/api/onboarding/apply"&&L.method==="POST"){let T=await se(L),D=Xe(Se);try{let U=Fc({controlPlane:E.store,drafts:ln,draftId:String(T.id??""),expectedVersion:Number(T.version),confirmEnvironment:String(T.confirmEnvironment??""),actorId:D.actor?.id});return M({ok:!0,resource:U.resource,operation:U.operation,plan:U.plan},202)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Application plan could not be applied."},422)}}if(W.pathname==="/api/sources"&&L.method==="GET"){let T=rt.listConnections(E.organization.id);return M({connections:T,bindings:rt.listBindings({projectId:E.project.id}),repositories:T.flatMap((D)=>rt.listRepositories(D.id)),deployKeys:T.flatMap((D)=>rt.listDeployKeys(D.id)),webhooks:T.flatMap((D)=>rt.listWebhooks(D.id)).map((D)=>({...D,deliveries:rt.listDeliveries(D.id,20)})),project:{id:E.project.id,slug:E.project.slug},environment:ee(E,String(De)),resources:E.store.listResources(E.project.id,ee(E,String(De)).environmentId).filter((D)=>D.kind==="application").map((D)=>({id:D.id,slug:D.slug,name:D.name}))})}if(W.pathname==="/api/sources/connections"&&L.method==="POST"){let T=await se(L),D=Xe(Se),U=String(T.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(U))return M({ok:!1,error:"A supported Git provider is required."},422);try{let q=U==="github"&&(T.privateKey||T.appId)?{appId:typeof T.appId==="string"?T.appId:void 0,installationId:typeof T.installationId==="string"?T.installationId:void 0,privateKey:typeof T.privateKey==="string"?T.privateKey:void 0}:U!=="generic_ssh"&&T.token?{token:typeof T.token==="string"?T.token:void 0,username:typeof T.username==="string"?T.username:void 0}:void 0,G={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},Z,Q,ie;if(E.store.database.transaction(()=>{if(Z=rt.createConnection({organizationId:E.organization.id,provider:U,name:String(T.name??U),host:String(T.host??G[U]??""),owner:typeof T.owner==="string"?T.owner:void 0,authKind:T.authKind,credential:q,grantedScopes:Array.isArray(T.grantedScopes)?T.grantedScopes.map(String):[],credentialExpiresAt:typeof T.credentialExpiresAt==="string"?T.credentialExpiresAt:void 0,createdByActorId:D.actor?.id}),typeof T.repositoryUrl==="string"&&typeof T.repositoryFullName==="string")Q=rt.upsertRepository({connectionId:Z.id,providerRepositoryId:`manual:${T.repositoryFullName}`,fullName:T.repositoryFullName,cloneUrl:T.repositoryUrl,defaultBranch:String(T.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"manual"}});if(U==="generic_ssh")ie=rt.createDeployKey({connectionId:Z.id,name:String(T.deployKeyName??"Repository deploy key"),publicKey:String(T.publicKey??""),privateKey:String(T.deployPrivateKey??""),host:String(T.sshHost??""),hostKey:String(T.hostKey??""),actorId:D.actor?.id})})(),T.test===!0)Z=await So(rt,Z.id,Q?.id);return M({ok:!0,connection:Z,repository:Q,deployKey:ie},201)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source connection could not be created."},422)}}if(W.pathname==="/api/sources/connections"&&L.method==="PATCH"){let T=await se(L),D=Xe(Se),U=rt.getConnection(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{if(T.action==="test")return M({ok:!0,connection:await So(rt,U.id,typeof T.repositoryId==="string"?T.repositoryId:void 0)});if(T.action==="rotate")return M({ok:!0,connection:rt.rotateCredential(U.id,{token:typeof T.token==="string"?T.token:void 0,username:typeof T.username==="string"?T.username:void 0,appId:typeof T.appId==="string"?T.appId:void 0,installationId:typeof T.installationId==="string"?T.installationId:void 0,privateKey:typeof T.privateKey==="string"?T.privateKey:void 0},{expiresAt:typeof T.expiresAt==="string"?T.expiresAt:void 0,actorId:D.actor?.id})});return M({ok:!1,error:"Connection action must be test or rotate."},422)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source connection could not be updated."},422)}}if(W.pathname==="/api/sources/connections"&&L.method==="DELETE"){let T=await se(L),D=Xe(Se),U=rt.getConnection(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);let q=rt.listBindings({connectionId:U.id,status:"active"});if(T.preview===!0)return M({ok:!0,preview:!0,affectedBindings:q});return M({ok:!0,...rt.disconnectConnection(U.id,D.actor?.id)})}if(W.pathname==="/api/sources/deploy-keys"&&L.method==="POST"){let T=await se(L),D=Xe(Se),U=rt.getConnection(String(T.connectionId??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M({ok:!0,deployKey:rt.createDeployKey({connectionId:U.id,name:String(T.name??"Repository deploy key"),publicKey:String(T.publicKey??""),privateKey:String(T.privateKey??""),host:String(T.host??""),hostKey:String(T.hostKey??""),actorId:D.actor?.id})},201)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Deploy key could not be stored."},422)}}if(W.pathname==="/api/sources/deploy-keys"&&L.method==="DELETE"){let T=await se(L),D=Xe(Se),U=rt.getDeployKey(String(T.id??"")),q=U?rt.getConnection(U.connectionId):void 0;if(!U||!q||q.organizationId!==E.organization.id)return M({ok:!1,error:"Deploy key was not found."},404);let G=rt.listBindings({connectionId:q.id}).filter((Z)=>Z.deployKeyId===U.id);if(T.preview===!0)return M({ok:!0,preview:!0,affectedBindings:G});return M({ok:!0,...rt.revokeDeployKey(U.id,D.actor?.id)})}if(W.pathname==="/api/sources/repositories/sync"&&L.method==="POST"){let T=await se(L),D=rt.getConnection(String(T.connectionId??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M({ok:!0,repositories:await Ti(rt,String(T.connectionId??""),{search:typeof T.search==="string"?T.search:void 0})})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Repositories could not be synchronized."},422)}}if(W.pathname==="/api/sources/references"&&L.method==="GET"){let T=rt.getConnection(String(W.searchParams.get("connectionId")??""));if(!T||T.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M(await wi(rt,{connectionId:String(W.searchParams.get("connectionId")??""),repository:String(W.searchParams.get("repository")??""),repositoryId:W.searchParams.get("repositoryId")??void 0,deployKeyId:W.searchParams.get("deployKeyId")??void 0,type:W.searchParams.get("type")==="tags"?"tags":"branches",cursor:W.searchParams.get("cursor")??void 0}))}catch(D){return M({ok:!1,error:D instanceof Error?D.message:"References could not be listed."},422)}}if(W.pathname==="/api/sources/bindings"&&L.method==="POST"){let T=await se(L),D=Xe(Se),U=ee(E,String(De)),q=rt.getConnection(String(T.connectionId??""));if(!q||q.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M({ok:!0,binding:rt.createBinding({projectId:E.project.id,environmentId:U.environmentId,resourceId:typeof T.resourceId==="string"?T.resourceId:void 0,connectionId:String(T.connectionId??""),repositoryId:typeof T.repositoryId==="string"?T.repositoryId:void 0,repositoryFullName:String(T.repositoryFullName??""),defaultBranch:String(T.defaultBranch??"main"),branchRule:typeof T.branchRule==="string"?T.branchRule:void 0,tagRule:typeof T.tagRule==="string"?T.tagRule:void 0,monorepoRoot:String(T.monorepoRoot??"."),includePaths:Array.isArray(T.includePaths)?T.includePaths.map(String):[],excludePaths:Array.isArray(T.excludePaths)?T.excludePaths.map(String):[],submodules:T.submodules===!0,cloneDepth:T.cloneDepth?Number(T.cloneDepth):void 0,deployKeyId:typeof T.deployKeyId==="string"&&T.deployKeyId?T.deployKeyId:void 0,autoDeploy:T.autoDeploy!==!1,pullRequestPreviews:T.pullRequestPreviews!==!1,actorId:D.actor?.id})},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Source binding could not be created."},422)}}if(W.pathname==="/api/sources/bindings"&&L.method==="PATCH"){let T=await se(L),D=Xe(Se),U=rt.getBinding(String(T.id??""));if(!U||U.projectId!==E.project.id)return M({ok:!1,error:"Source binding was not found."},404);try{return M({ok:!0,binding:rt.updateBinding(U.id,Number(T.version),{defaultBranch:T.defaultBranch,branchRule:T.branchRule,tagRule:T.tagRule,monorepoRoot:T.monorepoRoot,includePaths:T.includePaths,excludePaths:T.excludePaths,submodules:T.submodules,cloneDepth:T.cloneDepth,deployKeyId:T.deployKeyId,autoDeploy:T.autoDeploy,pullRequestPreviews:T.pullRequestPreviews,status:T.status,disabledReason:T.disabledReason,actorId:D.actor?.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source binding could not be updated."},409)}}if(W.pathname==="/api/sources/webhooks"&&L.method==="POST"){let T=await se(L),D=rt.getConnection(String(T.connectionId??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{let U=rt.createWebhook({connectionId:String(T.connectionId??""),repositoryId:typeof T.repositoryId==="string"?T.repositoryId:void 0,repositoryFullName:String(T.repositoryFullName??""),events:Array.isArray(T.events)?T.events.map(String):void 0,secret:typeof T.secret==="string"?T.secret:void 0}),q=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||St,G=q?Vt(q,U.webhook):void 0,Z=T.reconcile!==!1&&q?await Mr(rt,U.webhook.id,q):U.webhook;return M({ok:!0,webhook:Z,endpoint:G,endpointRevealOnce:!0},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Source webhook could not be created."},422)}}if(W.pathname==="/api/sources/webhooks"&&L.method==="PATCH"){let T=await se(L),D=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||St,U=rt.getWebhook(String(T.id??"")),q=U?rt.getConnection(U.connectionId):void 0;if(!U||!q||q.organizationId!==E.organization.id)return M({ok:!1,error:"Source webhook was not found."},404);if(!D)return M({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return M({ok:!0,webhook:await Mr(rt,String(T.id??""),D)})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Source webhook could not be reconciled."},422)}}if(W.pathname==="/api/sources/webhooks"&&L.method==="DELETE"){let T=await se(L),D=rt.getWebhook(String(T.id??"")),U=D?rt.getConnection(D.connectionId):void 0;if(!D||!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source webhook was not found."},404);try{return M({ok:!0,webhook:await Vd(rt,String(T.id??""))})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source webhook could not be removed."},422)}}if(W.pathname==="/api/security/posture"&&L.method==="GET"){let T=ee(E,String(De)),D=bt.listFindings({...T,limit:500});return M({scope:T,summary:bt.summary(T.organizationId,T.projectId,T.environmentId),findings:D,scans:bt.listScanRuns({...T,limit:100}),policies:bt.listPolicies(T.organizationId).filter((U)=>!U.environmentId||U.environmentId===T.environmentId),waivers:D.flatMap((U)=>bt.listWaivers(U.id)),decisions:bt.listDecisions(T.environmentId,50),actors:E.store.listMemberships(E.organization.id).map((U)=>E.store.getActor(U.actorId)).filter(Boolean)})}if(W.pathname==="/api/security/export"&&L.method==="GET")return M(bt.exportPosture(E.organization.id));if(W.pathname==="/api/security/scan"&&L.method==="POST"){let T=ee(E,String(De)),D=await new ut(bt).run(new Qr,{...T,artifactRoot:t}),U=Di(bt,T,ur??{});return M({ok:!0,source:D,host:U,summary:bt.summary(T.organizationId,T.projectId,T.environmentId)})}if(W.pathname==="/api/security/review"&&L.method==="POST")try{let T=ee(E,String(De));return M({ok:!0,...Pi(bt,{scope:T,desiredConfigHash:E.project.desiredConfigHash})})}catch(T){return M({ok:!1,error:T instanceof Error?T.message:"Security change review failed."},409)}if(W.pathname==="/api/security/policies"&&L.method==="POST"){let T=await se(L),D=Xe(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{let U=bt.createPolicy({organizationId:E.organization.id,environmentId:T.environmentId===null?void 0:String(T.environmentId??ee(E,String(De)).environmentId),name:String(T.name??""),scannerFailMode:T.scannerFailMode==="open"?"open":"closed",requiredScanners:Array.isArray(T.requiredScanners)?T.requiredScanners.map(String):[],rules:Array.isArray(T.rules)?T.rules.map((q)=>({minimumSeverity:String(q.minimumSeverity),action:String(q.action),scannerId:q.scannerId?String(q.scannerId):void 0})):[],actorId:D.actor.id});return M({ok:!0,policy:U},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Security policy could not be created."},422)}}if(W.pathname==="/api/security/policies"&&L.method==="PATCH"){let T=await se(L),D=Xe(Se),U=bt.getPolicy(String(T.id??""));if(!D.actor||!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Security policy was not found."},404);try{return M({ok:!0,policy:bt.updatePolicy(U.id,Number(T.version),{name:typeof T.name==="string"?T.name:void 0,scannerFailMode:T.scannerFailMode==="open"||T.scannerFailMode==="closed"?T.scannerFailMode:void 0,requiredScanners:Array.isArray(T.requiredScanners)?T.requiredScanners.map(String):void 0,rules:Array.isArray(T.rules)?T.rules.map((q)=>({minimumSeverity:String(q.minimumSeverity),action:String(q.action),scannerId:q.scannerId?String(q.scannerId):void 0})):void 0,enabled:typeof T.enabled==="boolean"?T.enabled:void 0,actorId:D.actor.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Security policy could not be updated."},409)}}if(W.pathname==="/api/security/waivers"&&L.method==="POST"){let T=await se(L),D=Xe(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{return M({ok:!0,waiver:bt.createWaiver({findingId:String(T.findingId??""),policyId:typeof T.policyId==="string"?T.policyId:void 0,reason:String(T.reason??""),referenceUrl:typeof T.referenceUrl==="string"?T.referenceUrl:void 0,expiresAt:String(T.expiresAt??""),actorId:D.actor.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Security waiver could not be created."},422)}}if(W.pathname==="/api/security/waivers"&&L.method==="DELETE"){let T=await se(L),D=Xe(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{return M({ok:!0,waiver:bt.revokeWaiver(String(T.id??""),D.actor.id)})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Security waiver could not be revoked."},404)}}if(W.pathname==="/api/security/findings"&&L.method==="PATCH"){let T=await se(L),D=Xe(Se),U=bt.getFinding(String(T.id??""));if(!D.actor||!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Security finding was not found."},404);try{let q=T.action==="acknowledge"?bt.acknowledgeFinding(U.id,D.actor.id):bt.assignFinding(U.id,typeof T.ownerActorId==="string"&&T.ownerActorId?T.ownerActorId:void 0,D.actor.id);return M({ok:!0,finding:q})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Security finding could not be updated."},422)}}if(W.pathname==="/api/security/comments"&&L.method==="POST"){let T=await se(L),D=Xe(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{return M({ok:!0,comment:bt.addComment({findingId:String(T.findingId??""),actorId:D.actor.id,body:String(T.body??""),referenceUrl:typeof T.referenceUrl==="string"?T.referenceUrl:void 0})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Comment could not be saved."},422)}}if(W.pathname==="/api/auth/sessions"&&L.method==="GET"){let T=gr.resolveSession(L);return M({currentSessionId:T?.id,sessions:T?Fe.listSessions(T.identityId,{includeInactive:!0}):[]})}if(W.pathname==="/api/auth/sessions"&&L.method==="DELETE"){let T=await se(L),D=gr.resolveSession(L);if(!D)return M({ok:!1,error:"Sign in again to manage sessions."},401);let U=String(T.id??""),q=Fe.revokeSession(D.identityId,U),G=U===D.id&&q?{"set-cookie":_u({secure:no})}:void 0;return M({ok:q,signedOut:U===D.id&&q},q?200:404,G)}if(W.pathname==="/api/auth/sessions/revoke-others"&&L.method==="POST"){let T=gr.resolveSession(L);if(!T)return M({ok:!1,error:"Sign in again to manage sessions."},401);return M({ok:!0,revoked:Fe.revokeOtherSessions(T.identityId,T.id)})}if(W.pathname==="/api/auth/password/change"&&L.method==="POST"){let T=await se(L),D=String(T.currentPassword??""),U=String(T.password??""),q=Xe(Se),G=q.actor?Fe.getIdentityByActor(q.actor.id):void 0;if(!G||!Yn(D,G.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);if(U.length<12)return M({ok:!1,error:"New password must be at least 12 characters."},422);if(Yn(U,G.passwordHash))return M({ok:!1,error:"Choose a different password."},409);let Z=ms(U),Q=Fe.updatePassword(G.id,Z);Du(t,Q.username,Z);let ie=$c(Q.id,L,dt.requestIP(L)?.address??"unknown");return E.store.appendEvent({organizationId:E.organization.id,actorId:Q.actorId,type:"auth.password.changed"}),M({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":Va(ie.token,{secure:no,maxAgeMs:Ge})})}if(W.pathname==="/api/auth/mfa/enroll"&&L.method==="POST"){let T=await se(L),D=gr.resolveSession(L),U=Xe(Se),q=U.actor?Fe.getIdentityByActor(U.actor.id):void 0;if(!D||!q)return M({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Yn(String(T.password??""),q.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);try{let G=Fe.beginTotpEnrollment(q.id,{issuer:E.organization.name});return E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.mfa.enrollment.started"}),M({factor:G.factor,secret:G.secret,uri:G.uri})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"MFA enrollment failed."},409)}}if(W.pathname==="/api/auth/mfa/verify"&&L.method==="POST"){let T=await se(L),D=gr.resolveSession(L),U=Xe(Se),q=U.actor?Fe.getIdentityByActor(U.actor.id):void 0;if(!D||!q)return M({ok:!1,error:"Sign in again before enabling MFA."},401);try{let G=Fe.verifyTotpEnrollment(q.id,String(T.code??""));return Fe.markSessionStepUp(D.id,!0),E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:G.recoveryCodes.length}}),M(G)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"MFA enrollment failed."},422)}}if(W.pathname==="/api/auth/mfa"&&L.method==="DELETE"){let T=await se(L),D=gr.resolveSession(L),U=Xe(Se),q=U.actor?Fe.getIdentityByActor(U.actor.id):void 0;if(!D||!q||!Yn(String(T.password??""),q.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);let G=Fe.verifyMfaCode(q.id,String(T.code??""));if(!G.valid||!G.method)return M({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return Fe.disableMfa(q.id),Fe.revokeOtherSessions(q.id,D.id),Fe.markSessionStepUp(D.id),E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.mfa.disabled",payload:{method:G.method}}),M({ok:!0})}if(W.pathname==="/api/auth/step-up"&&L.method==="POST"){let T=await se(L),D=gr.resolveSession(L),U=Xe(Se),q=U.actor?Fe.getIdentityByActor(U.actor.id):void 0;if(!D||!q||!Yn(String(T.password??""),q.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);let G=Fe.getMfaFactor(q.id);if(G?.state==="active"){if(!Fe.verifyMfaCode(q.id,String(T.code??"")).valid)return M({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let Z=Fe.markSessionStepUp(D.id,G?.state==="active");return E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.step_up.succeeded",payload:{mfa:G?.state==="active"}}),M({ok:!0,recentAuthAt:Z.recentAuthAt})}if(W.pathname==="/api/terminal"){if(!be)return M({ok:!1,error:"The web terminal is disabled."},403);if(dt.upgrade(L))return;return Fu("WebSocket upgrade failed",400)}if(W.pathname==="/api/health"){let T=E.store.health();return M({ok:!0,cwd:t,environment:De,environments:x,uiRoot:await dr(Se,De),liveData:me.size>0,terminal:be,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:T.schemaVersion,supportedSchemaVersion:T.supportedSchemaVersion,integrity:T.integrity,pendingRetryableOperations:T.pendingRetryableOperations}})}if(W.pathname==="/api/control-plane/operations"){let T=W.searchParams.get("state"),D=T&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(T)?T:void 0;return M({operations:E.store.listOperations({projectId:E.project.id,state:D,kind:W.searchParams.get("kind")??void 0,limit:Number(W.searchParams.get("limit"))||100})})}if(W.pathname==="/api/queue"&&L.method==="GET"){let T=W.searchParams.get("state"),D=T&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(T)?T:void 0,U=nr.list({projectId:E.project.id,state:D,limit:Number(W.searchParams.get("limit"))||250}).filter((q)=>Ys(Se,q.operation.id,"deployments:read")).map((q)=>{let G=q.operation.resourceId?E.store.getResource(q.operation.resourceId):void 0,Z=q.operation.environmentId?E.store.listEnvironments(E.project.id).find((Ae)=>Ae.id===q.operation.environmentId):void 0,Q=q.operation.actorId?E.store.getActor(q.operation.actorId):void 0,ie=q.operation.input;return{...q,target:G?{id:G.id,name:G.name,slug:G.slug,kind:G.kind}:Z?{id:Z.id,name:Z.name,slug:Z.slug,kind:"environment"}:{id:E.project.id,name:E.project.name,slug:E.project.slug,kind:"project"},actor:Q?{id:Q.id,name:Q.displayName,kind:Q.kind}:void 0,commit:ie.revision??ie.source?.commitSha??null}});return M({operations:U,concurrency:nr.limits})}if(W.pathname==="/api/queue/logs"&&L.method==="GET"){let T=String(W.searchParams.get("id")??"");if(!Ys(Se,T,"deployments:read"))return M({ok:!1,error:"Operation was not found in this scope."},404);let D=nr.logs(T,{after:Number(W.searchParams.get("after"))||0,limit:Number(W.searchParams.get("limit"))||500});return M({entries:D,cursor:D.at(-1)?.sequence??(Number(W.searchParams.get("after"))||0),operation:E.store.getOperation(T)})}if(W.pathname==="/api/queue/stream"&&L.method==="GET"){let T=String(W.searchParams.get("id")??"");if(!Ys(Se,T,"deployments:read"))return M({ok:!1,error:"Operation was not found in this scope."},404);let D=L.headers.get("last-event-id")?.trim(),U=Number(D||W.searchParams.get("after")||0),q=new TextEncoder,G,Z=!1,Q=new ReadableStream({start(ie){let Ae=()=>{if(Z)return;let ke=gr.resolveUser(L);if(!ke||!Ys(ke,T,"deployments:read")){if(Z=!0,G)clearInterval(G);ie.close();return}let ot=nr.logs(T,{after:U,limit:500});for(let et of ot)U=et.sequence,ie.enqueue(q.encode(`id: ${et.sequence}
685
+ This link expires in one hour and can be used once.`});E.store.appendEvent({organizationId:E.organization.id,actorId:G.actorId,type:"auth.password_reset.requested",payload:{delivered:ie}})}return M({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(W.pathname==="/api/auth/password-reset/complete"&&L.method==="POST"){let T=await se(L),D=String(T.token??"").trim(),U=String(T.password??"");if(!D||U.length<12)return M({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let q=Le.consumeActionToken(D,"password_reset"),G=ms(U),Z=Le.updatePassword(q.identityId,G);return Du(t,Z.username,G),E.store.appendEvent({organizationId:E.organization.id,actorId:Z.actorId,type:"auth.password_reset.completed"}),M({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":_u({secure:no})})}catch(q){let G=q instanceof Error?q.message:"Password reset failed.";return M({ok:!1,error:G.replace("Action token","Reset link")},G.includes("consumed")||G.includes("expired")?409:404)}}if(W.pathname==="/api/login"&&L.method==="POST"){let T=await se(L),D=String(T.username??"").trim(),U=String(T.password??""),q=dt.requestIP(L)?.address??"unknown",G=Dc.check(D,q);if(!G.allowed)return M({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((G.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(G.retryAfterSeconds??60)});let Z=Un(En(t),D),Q=Le.getIdentityByUsername(D),ie=Q?.passwordHash??Z?.passwordHash??F_;if(!(Yn(U,ie)&&!!Z&&!!Q&&!Q.disabledAt))return Dc.recordFailure(D,q),M({ok:!1,error:"Incorrect username or password."},401);if(jb(Le,E,Q))return M({ok:!1,error:"Single sign-on is required for this account."},403);Dc.recordSuccess(D,q);let ke=Q,ot=ke.requiresPasswordUpgrade||Gv(ke.passwordHash);if(ot){let et=ms(U);ke=Le.rehashPassword(ke.id,et),Du(t,ke.username,et)}if(Le.recordLogin(ke.id),Le.getMfaFactor(ke.id)?.state==="active"){let et=Le.createMfaChallenge(ke.id,"login");return E.store.appendEvent({organizationId:E.organization.id,actorId:ke.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),M({ok:!0,mfaRequired:!0,challengeToken:et.token,passwordUpgraded:ot})}let Oe=$c(ke.id,L,q);return E.store.appendEvent({organizationId:E.organization.id,actorId:ke.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),M({ok:!0,user:Wa(Z),passwordUpgraded:ot},200,{"set-cookie":Va(Oe.token,{secure:no,maxAgeMs:qe})})}if(W.pathname==="/api/auth/mfa/complete"&&L.method==="POST"){let T=await se(L),D=String(T.challengeToken??"").trim(),U=String(T.code??"").trim(),q=dt.requestIP(L)?.address??"unknown",Z=Le.inspectMfaChallengeToken(D,"login")?.identityId??"unknown-mfa",Q=Oc.check(Z,q);if(!Q.allowed)return M({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(Q.retryAfterSeconds??60)});try{let ie=Le.completeMfaChallenge(D,U,"login");Oc.recordSuccess(Z,q);let Ae=new Date().toISOString(),ke=Le.createSession({identityId:ie.identity.id,userAgent:yf(L),networkHint:Ku(q),mfaAt:Ae,recentAuthAt:Ae});return E.store.appendEvent({organizationId:E.organization.id,actorId:ie.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:ie.method}}),M({ok:!0},200,{"set-cookie":Va(ke.token,{secure:no,maxAgeMs:qe})})}catch{return Oc.recordFailure(Z,q),M({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(W.pathname==="/api/logout"&&L.method==="POST"){let T=gr.resolveSession(L);if(T)Le.revokeSession(T.identityId,T.id);let D=_u({secure:no});if(L.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":D}});return M({ok:!0},200,{"set-cookie":D})}if(W.pathname==="/login"){let T=Le.listOidcProviders(E.organization.id).map((D)=>({slug:D.slug,name:D.name}));return new Response(Mb(z?.mode==="serverless",T),{headers:{"content-type":"text/html; charset=utf-8"}})}if(W.pathname==="/forgot-password"||W.pathname==="/reset-password")return new Response(Bb(W.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(W.pathname==="/accept-invitation")return $S(vt,W.pathname);let Se=gr.resolveUser(L);if(!Se){if(!W.pathname.startsWith("/api/")&&L.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return M({ok:!1,error:"Sign in to continue."},401)}let jn=cr(Se,De);if(W.pathname==="/api/me"){let T=E.store.getActorByExternalId("user",`dashboard:${Se.username.toLowerCase()}`),D=T?E.store.getMembershipForActor(E.organization.id,T.id):void 0,U=E.store.resolveAuthorizationTarget(E.organization.id,D?.scope??{type:"project",id:E.project.id})??E.store.resolveAuthorizationTarget(E.organization.id,{type:"project",id:E.project.id});return M({ok:!0,user:Wa(Se),authEnabled:Ne,organization:E.organization,membership:D,capabilities:Bt({membership:D,grants:D?E.store.listGrants(D.id):[],target:U})})}if(W.pathname.startsWith("/api/")){let T=await Ob(L,W.pathname),D=gr.check(L,W.pathname,Se,T);if(!D.ok)return M({ok:!1,error:D.error},D.status??403);if(Ne&&Q_.has(`${L.method.toUpperCase()} ${W.pathname}`)){let U=gr.resolveSession(L);if(!U||!Le.isRecentlyAuthenticated(U))return M({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(W.pathname==="/api/auth/security"&&L.method==="GET"){let T=Ze(Se),D=T.actor?Le.getIdentityByActor(T.actor.id):void 0,U=gr.resolveSession(L);return M({identity:D?{username:D.username,email:D.email,emailVerifiedAt:D.emailVerifiedAt,requiresPasswordUpgrade:D.requiresPasswordUpgrade,lastLoginAt:D.lastLoginAt}:void 0,currentSessionId:U?.id,sessions:D?Le.listSessions(D.id,{includeInactive:!0}):[],mfa:D?{factor:Le.getMfaFactor(D.id),recoveryCodesRemaining:Le.remainingRecoveryCodes(D.id)}:void 0})}if(W.pathname==="/api/auth/oidc/providers"&&L.method==="GET")return M({providers:Le.listOidcProviders(E.organization.id,{includeDisabled:!0}),callbackOrigin:St,callbackPattern:St?`${St}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(W.pathname==="/api/auth/oidc/providers"&&L.method==="POST"){let T=await se(L),D=Ze(Se),U=D.actor?Le.getIdentityByActor(D.actor.id):void 0,q=T.enforceSso===!0;if(q&&(!U?.emailVerifiedAt||Le.remainingRecoveryCodes(U.id)<1))return M({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let G=Mu(T.defaultRole),Z=Le.upsertOidcProvider({id:typeof T.id==="string"?T.id:void 0,organizationId:E.organization.id,slug:String(T.slug??""),name:String(T.name??""),issuer:String(T.issuer??""),clientId:String(T.clientId??""),clientSecret:typeof T.clientSecret==="string"&&T.clientSecret?T.clientSecret:void 0,scopes:Array.isArray(T.scopes)?T.scopes.map(String):void 0,allowedDomains:Array.isArray(T.allowedDomains)?T.allowedDomains.map(String):[],defaultRole:G&&G!=="owner"?G:void 0,enabled:T.enabled!==!1,enforceSso:q});return E.store.appendEvent({organizationId:E.organization.id,actorId:D.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:Z.id,issuer:Z.issuer,enabled:Z.enabled,enforceSso:Z.enforceSso}}),M({ok:!0,provider:Z})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"OIDC provider could not be saved."},422)}}if(W.pathname==="/api/auth/oidc/providers"&&L.method==="PATCH"){let T=await se(L),D=Le.getOidcProvider(String(T.id??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"OIDC provider was not found."},404);let U=Ze(Se),q=Le.setOidcProviderEnabled(D.id,T.enabled===!0);return E.store.appendEvent({organizationId:E.organization.id,actorId:U.actor?.id,type:q.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:D.id}}),M({ok:!0,provider:q})}if(W.pathname==="/api/automation"&&L.method==="GET"){let T=Ct.listServiceAccounts(E.organization.id,{includeDisabled:!0}).map((D)=>{let U=E.store.getMembershipForActor(E.organization.id,D.actorId),q=D.createdByActorId?E.store.getActor(D.createdByActorId):void 0,G=Ct.listTokens(D.id,{includeInactive:!0}).map((Z)=>({...Z,createdBy:Z.createdByActorId?E.store.getActor(Z.createdByActorId):void 0}));return{account:D,createdBy:q,membership:U,tokens:G}});return M({accounts:T,apiBaseUrl:`${W.origin}/api/v1`,openApiUrl:`${W.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(W.pathname==="/api/automation/service-accounts"&&L.method==="POST"){let T=await se(L),D=Ze(Se),U=Mu(T.roleTemplate),q=Pc(T);if(!D.actor||!U||U==="owner"||!q)return M({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let G=Ct.createServiceAccount({organizationId:E.organization.id,slug:String(T.slug??""),name:String(T.name??""),description:typeof T.description==="string"?T.description:void 0,roleTemplate:U,scope:q,createdByActorId:D.actor.id});return M({ok:!0,...G},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Service account could not be created."},422)}}if(W.pathname==="/api/automation/service-accounts"&&L.method==="PATCH"){let T=await se(L),D=Ze(Se),U=Ct.getServiceAccount(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Service account was not found."},404);return M({ok:!0,account:Ct.disableServiceAccount(U.id,D.actor?.id)})}if(W.pathname==="/api/automation/tokens"&&L.method==="POST"){let T=await se(L),D=Ze(Se),U=Ct.getServiceAccount(String(T.serviceAccountId??"")),q=Pc(T);if(!D.actor||!U||U.organizationId!==E.organization.id||!q||!Array.isArray(T.capabilities))return M({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let G=Ct.createToken({serviceAccountId:U.id,name:String(T.name??"API token"),capabilities:T.capabilities.map(String),scope:q,expiresAt:typeof T.expiresAt==="string"?T.expiresAt:void 0,createdByActorId:D.actor.id});return M({ok:!0,token:G.token,secret:G.secret,revealOnce:!0},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"API token could not be created."},422)}}if(W.pathname==="/api/automation/tokens/rotate"&&L.method==="POST"){let T=await se(L),D=Ze(Se),U=Ct.getToken(String(T.id??"")),q=U?Ct.getServiceAccount(U.serviceAccountId):void 0;if(!D.actor||!U||q?.organizationId!==E.organization.id)return M({ok:!1,error:"API token was not found."},404);try{let G=Ct.rotateToken(U.id,D.actor.id);return M({ok:!0,token:G.token,secret:G.secret,revealOnce:!0,overlap:!0},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"API token could not be rotated."},409)}}if(W.pathname==="/api/automation/tokens"&&L.method==="DELETE"){let T=await se(L),D=Ze(Se),U=Ct.getToken(String(T.id??"")),q=U?Ct.getServiceAccount(U.serviceAccountId):void 0;if(!U||q?.organizationId!==E.organization.id)return M({ok:!1,error:"API token was not found."},404);return M({ok:!0,token:Ct.revokeToken(U.id,D.actor?.id)})}if(W.pathname==="/api/onboarding"&&L.method==="GET"){let T=rt.listConnections(E.organization.id);return M({drafts:ln.list(E.project.id),artifacts:Qs.list(E.project.id),registries:Zn.list(E.organization.id),sourceConnections:T,repositories:T.flatMap((D)=>rt.listRepositories(D.id)),project:{id:E.project.id,slug:E.project.slug,name:E.project.name},environments:[...E.environments.values()].map((D)=>({id:D.id,slug:D.slug,name:D.name,kind:D.kind,region:D.region})),resources:E.store.listResources(E.project.id).filter((D)=>D.kind==="application").map((D)=>({id:D.id,slug:D.slug,name:D.name,environmentId:D.environmentId}))})}if(W.pathname==="/api/onboarding/detect"&&L.method==="POST"){let T=await se(L);try{if(T.source?.kind==="git"){let q=rt.getConnection(String(T.source.connectionId??"")),G=rt.getRepository(String(T.source.repositoryId??""));if(!q||q.organizationId!==E.organization.id||!G||G.connectionId!==q.id)throw Error("Authorized Git repository was not found");let Z=typeof T.source.deployKeyId==="string"?rt.getDeployKey(T.source.deployKeyId):void 0;if(Z&&Z.connectionId!==q.id)throw Error("Deploy key does not belong to this connection");let Q=Gg(rr(Lu(),"ts-cloud-onboarding-git-"));try{let ie=await Io({remote:G.cloneUrl,destination:rr(Q,"checkout"),ref:String(T.source.ref??G.defaultBranch),sparsePaths:Array.isArray(T.source.sparsePaths)?T.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:E.project.id,connectionId:q.id,repositoryId:G.id,repositoryFullName:G.fullName,defaultBranch:G.defaultBranch,monorepoRoot:String(T.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:T.source.submodules===!0,cloneDepth:1,deployKeyId:Z?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:rt.getCredential(q.id),deployKey:Z?{...Z,privateKey:rt.getDeployPrivateKey(Z.id)}:void 0,timeoutMs:120000});return M({ok:!0,commitSha:ie.commitSha,candidates:va(tp(ie.directory))})}finally{Gs(Q,{recursive:!0,force:!0})}}if(Array.isArray(T.files)){if(T.files.length>1e4)throw Error("Detection file-count limit exceeded");let q=T.files.map((G)=>({path:String(G.path??""),size:Number(G.size??0),content:typeof G.content==="string"?G.content.slice(0,262144):void 0}));return M({ok:!0,candidates:va(q)})}let D=__(t,String(T.root??".")),U=P_(t,D);if(U===".."||U.startsWith(`..${T_}`))throw Error("Detection root must stay inside the project");return M({ok:!0,candidates:va(tp(D))})}catch(D){return M({ok:!1,error:D instanceof Error?D.message:"Application detection failed."},422)}}if(W.pathname==="/api/onboarding/plan"&&L.method==="POST"){let T=await se(L);try{return M({ok:!0,plan:Vn(T.draft,Array.isArray(T.suppliedSecretNames)?T.suppliedSecretNames.map(String):[])})}catch(D){return M({ok:!1,error:D instanceof Error?D.message:"Application plan could not be generated."},422)}}if(W.pathname==="/api/onboarding/drafts"&&L.method==="POST"){let T=await se(L),D=Ze(Se);try{return M({ok:!0,draft:ln.create({organizationId:E.organization.id,projectId:E.project.id,name:String(T.name??T.draft?.name??"Application draft"),draft:{...T.draft,projectId:E.project.id},step:T.step,suppliedSecretNames:Array.isArray(T.suppliedSecretNames)?T.suppliedSecretNames.map(String):[],actorId:D.actor?.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Application draft could not be saved."},422)}}if(W.pathname==="/api/onboarding/drafts"&&L.method==="PATCH"){let T=await se(L),D=Ze(Se),U=ln.get(String(T.id??""));if(!U||U.projectId!==E.project.id)return M({ok:!1,error:"Application draft was not found."},404);try{return M({ok:!0,draft:ln.update(U.id,Number(T.version),{draft:{...T.draft,projectId:E.project.id},step:T.step,suppliedSecretNames:Array.isArray(T.suppliedSecretNames)?T.suppliedSecretNames.map(String):void 0,actorId:D.actor?.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Application draft could not be updated."},409)}}if(W.pathname==="/api/onboarding/artifacts"&&L.method==="POST"){let T=Ze(Se);if(Number(L.headers.get("content-length")??0)>104857600)return M({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let U=new Uint8Array(await L.arrayBuffer());return M({ok:!0,artifact:Qs.create({organizationId:E.organization.id,projectId:E.project.id,filename:L.headers.get("x-artifact-filename")??"application.zip",bytes:U,actorId:T.actor?.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Artifact could not be inspected."},422)}}if(W.pathname==="/api/onboarding/registries"&&L.method==="POST"){let T=await se(L),D=Ze(Se);try{return M({ok:!0,registry:Zn.create({organizationId:E.organization.id,provider:T.provider,name:String(T.name??"Container registry"),host:String(T.host??""),credential:T.token||T.password?{username:typeof T.username==="string"?T.username:void 0,password:typeof T.password==="string"?T.password:void 0,token:typeof T.token==="string"?T.token:void 0}:void 0,credentialExpiresAt:typeof T.credentialExpiresAt==="string"?T.credentialExpiresAt:void 0,actorId:D.actor?.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Registry connection could not be created."},422)}}if(W.pathname==="/api/onboarding/registries"&&L.method==="PATCH"){let T=await se(L),D=Ze(Se),U=Zn.get(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Registry connection was not found."},404);try{if(T.action==="test")return M({ok:!0,registry:await Zn.test(U.id,{image:typeof T.image==="string"?T.image:void 0})});if(T.action==="rotate")return M({ok:!0,registry:Zn.rotate(U.id,{username:typeof T.username==="string"?T.username:void 0,password:typeof T.password==="string"?T.password:void 0,token:typeof T.token==="string"?T.token:void 0},{expiresAt:typeof T.expiresAt==="string"?T.expiresAt:void 0,actorId:D.actor?.id})});return M({ok:!1,error:"Registry action must be test or rotate."},422)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Registry connection could not be updated."},422)}}if(W.pathname==="/api/onboarding/registries"&&L.method==="DELETE"){let T=await se(L),D=Ze(Se),U=Zn.get(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Registry connection was not found."},404);let q=ln.list(E.project.id).filter((G)=>G.input.source.kind==="image"&&G.input.source.registryConnectionId===U.id||G.input.build.kind==="prebuilt_image"&&G.input.build.registryConnectionId===U.id);if(T.preview===!0)return M({ok:!0,preview:!0,affectedDrafts:q});return M({ok:!0,registry:Zn.disconnect(U.id,D.actor?.id),affectedDrafts:q})}if(W.pathname==="/api/onboarding/apply"&&L.method==="POST"){let T=await se(L),D=Ze(Se);try{let U=Fc({controlPlane:E.store,drafts:ln,draftId:String(T.id??""),expectedVersion:Number(T.version),confirmEnvironment:String(T.confirmEnvironment??""),actorId:D.actor?.id});return M({ok:!0,resource:U.resource,operation:U.operation,plan:U.plan},202)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Application plan could not be applied."},422)}}if(W.pathname==="/api/sources"&&L.method==="GET"){let T=rt.listConnections(E.organization.id);return M({connections:T,bindings:rt.listBindings({projectId:E.project.id}),repositories:T.flatMap((D)=>rt.listRepositories(D.id)),deployKeys:T.flatMap((D)=>rt.listDeployKeys(D.id)),webhooks:T.flatMap((D)=>rt.listWebhooks(D.id)).map((D)=>({...D,deliveries:rt.listDeliveries(D.id,20)})),project:{id:E.project.id,slug:E.project.slug},environment:ee(E,String(De)),resources:E.store.listResources(E.project.id,ee(E,String(De)).environmentId).filter((D)=>D.kind==="application").map((D)=>({id:D.id,slug:D.slug,name:D.name}))})}if(W.pathname==="/api/sources/connections"&&L.method==="POST"){let T=await se(L),D=Ze(Se),U=String(T.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(U))return M({ok:!1,error:"A supported Git provider is required."},422);try{let q=U==="github"&&(T.privateKey||T.appId)?{appId:typeof T.appId==="string"?T.appId:void 0,installationId:typeof T.installationId==="string"?T.installationId:void 0,privateKey:typeof T.privateKey==="string"?T.privateKey:void 0}:U!=="generic_ssh"&&T.token?{token:typeof T.token==="string"?T.token:void 0,username:typeof T.username==="string"?T.username:void 0}:void 0,G={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},Z,Q,ie;if(E.store.database.transaction(()=>{if(Z=rt.createConnection({organizationId:E.organization.id,provider:U,name:String(T.name??U),host:String(T.host??G[U]??""),owner:typeof T.owner==="string"?T.owner:void 0,authKind:T.authKind,credential:q,grantedScopes:Array.isArray(T.grantedScopes)?T.grantedScopes.map(String):[],credentialExpiresAt:typeof T.credentialExpiresAt==="string"?T.credentialExpiresAt:void 0,createdByActorId:D.actor?.id}),typeof T.repositoryUrl==="string"&&typeof T.repositoryFullName==="string")Q=rt.upsertRepository({connectionId:Z.id,providerRepositoryId:`manual:${T.repositoryFullName}`,fullName:T.repositoryFullName,cloneUrl:T.repositoryUrl,defaultBranch:String(T.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"manual"}});if(U==="generic_ssh")ie=rt.createDeployKey({connectionId:Z.id,name:String(T.deployKeyName??"Repository deploy key"),publicKey:String(T.publicKey??""),privateKey:String(T.deployPrivateKey??""),host:String(T.sshHost??""),hostKey:String(T.hostKey??""),actorId:D.actor?.id})})(),T.test===!0)Z=await So(rt,Z.id,Q?.id);return M({ok:!0,connection:Z,repository:Q,deployKey:ie},201)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source connection could not be created."},422)}}if(W.pathname==="/api/sources/connections"&&L.method==="PATCH"){let T=await se(L),D=Ze(Se),U=rt.getConnection(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{if(T.action==="test")return M({ok:!0,connection:await So(rt,U.id,typeof T.repositoryId==="string"?T.repositoryId:void 0)});if(T.action==="rotate")return M({ok:!0,connection:rt.rotateCredential(U.id,{token:typeof T.token==="string"?T.token:void 0,username:typeof T.username==="string"?T.username:void 0,appId:typeof T.appId==="string"?T.appId:void 0,installationId:typeof T.installationId==="string"?T.installationId:void 0,privateKey:typeof T.privateKey==="string"?T.privateKey:void 0},{expiresAt:typeof T.expiresAt==="string"?T.expiresAt:void 0,actorId:D.actor?.id})});return M({ok:!1,error:"Connection action must be test or rotate."},422)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source connection could not be updated."},422)}}if(W.pathname==="/api/sources/connections"&&L.method==="DELETE"){let T=await se(L),D=Ze(Se),U=rt.getConnection(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);let q=rt.listBindings({connectionId:U.id,status:"active"});if(T.preview===!0)return M({ok:!0,preview:!0,affectedBindings:q});return M({ok:!0,...rt.disconnectConnection(U.id,D.actor?.id)})}if(W.pathname==="/api/sources/deploy-keys"&&L.method==="POST"){let T=await se(L),D=Ze(Se),U=rt.getConnection(String(T.connectionId??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M({ok:!0,deployKey:rt.createDeployKey({connectionId:U.id,name:String(T.name??"Repository deploy key"),publicKey:String(T.publicKey??""),privateKey:String(T.privateKey??""),host:String(T.host??""),hostKey:String(T.hostKey??""),actorId:D.actor?.id})},201)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Deploy key could not be stored."},422)}}if(W.pathname==="/api/sources/deploy-keys"&&L.method==="DELETE"){let T=await se(L),D=Ze(Se),U=rt.getDeployKey(String(T.id??"")),q=U?rt.getConnection(U.connectionId):void 0;if(!U||!q||q.organizationId!==E.organization.id)return M({ok:!1,error:"Deploy key was not found."},404);let G=rt.listBindings({connectionId:q.id}).filter((Z)=>Z.deployKeyId===U.id);if(T.preview===!0)return M({ok:!0,preview:!0,affectedBindings:G});return M({ok:!0,...rt.revokeDeployKey(U.id,D.actor?.id)})}if(W.pathname==="/api/sources/repositories/sync"&&L.method==="POST"){let T=await se(L),D=rt.getConnection(String(T.connectionId??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M({ok:!0,repositories:await Ti(rt,String(T.connectionId??""),{search:typeof T.search==="string"?T.search:void 0})})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Repositories could not be synchronized."},422)}}if(W.pathname==="/api/sources/references"&&L.method==="GET"){let T=rt.getConnection(String(W.searchParams.get("connectionId")??""));if(!T||T.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M(await wi(rt,{connectionId:String(W.searchParams.get("connectionId")??""),repository:String(W.searchParams.get("repository")??""),repositoryId:W.searchParams.get("repositoryId")??void 0,deployKeyId:W.searchParams.get("deployKeyId")??void 0,type:W.searchParams.get("type")==="tags"?"tags":"branches",cursor:W.searchParams.get("cursor")??void 0}))}catch(D){return M({ok:!1,error:D instanceof Error?D.message:"References could not be listed."},422)}}if(W.pathname==="/api/sources/bindings"&&L.method==="POST"){let T=await se(L),D=Ze(Se),U=ee(E,String(De)),q=rt.getConnection(String(T.connectionId??""));if(!q||q.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{return M({ok:!0,binding:rt.createBinding({projectId:E.project.id,environmentId:U.environmentId,resourceId:typeof T.resourceId==="string"?T.resourceId:void 0,connectionId:String(T.connectionId??""),repositoryId:typeof T.repositoryId==="string"?T.repositoryId:void 0,repositoryFullName:String(T.repositoryFullName??""),defaultBranch:String(T.defaultBranch??"main"),branchRule:typeof T.branchRule==="string"?T.branchRule:void 0,tagRule:typeof T.tagRule==="string"?T.tagRule:void 0,monorepoRoot:String(T.monorepoRoot??"."),includePaths:Array.isArray(T.includePaths)?T.includePaths.map(String):[],excludePaths:Array.isArray(T.excludePaths)?T.excludePaths.map(String):[],submodules:T.submodules===!0,cloneDepth:T.cloneDepth?Number(T.cloneDepth):void 0,deployKeyId:typeof T.deployKeyId==="string"&&T.deployKeyId?T.deployKeyId:void 0,autoDeploy:T.autoDeploy!==!1,pullRequestPreviews:T.pullRequestPreviews!==!1,actorId:D.actor?.id})},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Source binding could not be created."},422)}}if(W.pathname==="/api/sources/bindings"&&L.method==="PATCH"){let T=await se(L),D=Ze(Se),U=rt.getBinding(String(T.id??""));if(!U||U.projectId!==E.project.id)return M({ok:!1,error:"Source binding was not found."},404);try{return M({ok:!0,binding:rt.updateBinding(U.id,Number(T.version),{defaultBranch:T.defaultBranch,branchRule:T.branchRule,tagRule:T.tagRule,monorepoRoot:T.monorepoRoot,includePaths:T.includePaths,excludePaths:T.excludePaths,submodules:T.submodules,cloneDepth:T.cloneDepth,deployKeyId:T.deployKeyId,autoDeploy:T.autoDeploy,pullRequestPreviews:T.pullRequestPreviews,status:T.status,disabledReason:T.disabledReason,actorId:D.actor?.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source binding could not be updated."},409)}}if(W.pathname==="/api/sources/webhooks"&&L.method==="POST"){let T=await se(L),D=rt.getConnection(String(T.connectionId??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Source connection was not found."},404);try{let U=rt.createWebhook({connectionId:String(T.connectionId??""),repositoryId:typeof T.repositoryId==="string"?T.repositoryId:void 0,repositoryFullName:String(T.repositoryFullName??""),events:Array.isArray(T.events)?T.events.map(String):void 0,secret:typeof T.secret==="string"?T.secret:void 0}),q=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||St,G=q?Vt(q,U.webhook):void 0,Z=T.reconcile!==!1&&q?await Mr(rt,U.webhook.id,q):U.webhook;return M({ok:!0,webhook:Z,endpoint:G,endpointRevealOnce:!0},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Source webhook could not be created."},422)}}if(W.pathname==="/api/sources/webhooks"&&L.method==="PATCH"){let T=await se(L),D=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||St,U=rt.getWebhook(String(T.id??"")),q=U?rt.getConnection(U.connectionId):void 0;if(!U||!q||q.organizationId!==E.organization.id)return M({ok:!1,error:"Source webhook was not found."},404);if(!D)return M({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return M({ok:!0,webhook:await Mr(rt,String(T.id??""),D)})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Source webhook could not be reconciled."},422)}}if(W.pathname==="/api/sources/webhooks"&&L.method==="DELETE"){let T=await se(L),D=rt.getWebhook(String(T.id??"")),U=D?rt.getConnection(D.connectionId):void 0;if(!D||!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Source webhook was not found."},404);try{return M({ok:!0,webhook:await Vd(rt,String(T.id??""))})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Source webhook could not be removed."},422)}}if(W.pathname==="/api/security/posture"&&L.method==="GET"){let T=ee(E,String(De)),D=bt.listFindings({...T,limit:500});return M({scope:T,summary:bt.summary(T.organizationId,T.projectId,T.environmentId),findings:D,scans:bt.listScanRuns({...T,limit:100}),policies:bt.listPolicies(T.organizationId).filter((U)=>!U.environmentId||U.environmentId===T.environmentId),waivers:D.flatMap((U)=>bt.listWaivers(U.id)),decisions:bt.listDecisions(T.environmentId,50),actors:E.store.listMemberships(E.organization.id).map((U)=>E.store.getActor(U.actorId)).filter(Boolean)})}if(W.pathname==="/api/security/export"&&L.method==="GET")return M(bt.exportPosture(E.organization.id));if(W.pathname==="/api/security/scan"&&L.method==="POST"){let T=ee(E,String(De)),D=await new ut(bt).run(new Qr,{...T,artifactRoot:t}),U=Di(bt,T,ur??{});return M({ok:!0,source:D,host:U,summary:bt.summary(T.organizationId,T.projectId,T.environmentId)})}if(W.pathname==="/api/security/review"&&L.method==="POST")try{let T=ee(E,String(De));return M({ok:!0,...Pi(bt,{scope:T,desiredConfigHash:E.project.desiredConfigHash})})}catch(T){return M({ok:!1,error:T instanceof Error?T.message:"Security change review failed."},409)}if(W.pathname==="/api/security/policies"&&L.method==="POST"){let T=await se(L),D=Ze(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{let U=bt.createPolicy({organizationId:E.organization.id,environmentId:T.environmentId===null?void 0:String(T.environmentId??ee(E,String(De)).environmentId),name:String(T.name??""),scannerFailMode:T.scannerFailMode==="open"?"open":"closed",requiredScanners:Array.isArray(T.requiredScanners)?T.requiredScanners.map(String):[],rules:Array.isArray(T.rules)?T.rules.map((q)=>({minimumSeverity:String(q.minimumSeverity),action:String(q.action),scannerId:q.scannerId?String(q.scannerId):void 0})):[],actorId:D.actor.id});return M({ok:!0,policy:U},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Security policy could not be created."},422)}}if(W.pathname==="/api/security/policies"&&L.method==="PATCH"){let T=await se(L),D=Ze(Se),U=bt.getPolicy(String(T.id??""));if(!D.actor||!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Security policy was not found."},404);try{return M({ok:!0,policy:bt.updatePolicy(U.id,Number(T.version),{name:typeof T.name==="string"?T.name:void 0,scannerFailMode:T.scannerFailMode==="open"||T.scannerFailMode==="closed"?T.scannerFailMode:void 0,requiredScanners:Array.isArray(T.requiredScanners)?T.requiredScanners.map(String):void 0,rules:Array.isArray(T.rules)?T.rules.map((q)=>({minimumSeverity:String(q.minimumSeverity),action:String(q.action),scannerId:q.scannerId?String(q.scannerId):void 0})):void 0,enabled:typeof T.enabled==="boolean"?T.enabled:void 0,actorId:D.actor.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Security policy could not be updated."},409)}}if(W.pathname==="/api/security/waivers"&&L.method==="POST"){let T=await se(L),D=Ze(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{return M({ok:!0,waiver:bt.createWaiver({findingId:String(T.findingId??""),policyId:typeof T.policyId==="string"?T.policyId:void 0,reason:String(T.reason??""),referenceUrl:typeof T.referenceUrl==="string"?T.referenceUrl:void 0,expiresAt:String(T.expiresAt??""),actorId:D.actor.id})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Security waiver could not be created."},422)}}if(W.pathname==="/api/security/waivers"&&L.method==="DELETE"){let T=await se(L),D=Ze(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{return M({ok:!0,waiver:bt.revokeWaiver(String(T.id??""),D.actor.id)})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Security waiver could not be revoked."},404)}}if(W.pathname==="/api/security/findings"&&L.method==="PATCH"){let T=await se(L),D=Ze(Se),U=bt.getFinding(String(T.id??""));if(!D.actor||!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Security finding was not found."},404);try{let q=T.action==="acknowledge"?bt.acknowledgeFinding(U.id,D.actor.id):bt.assignFinding(U.id,typeof T.ownerActorId==="string"&&T.ownerActorId?T.ownerActorId:void 0,D.actor.id);return M({ok:!0,finding:q})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Security finding could not be updated."},422)}}if(W.pathname==="/api/security/comments"&&L.method==="POST"){let T=await se(L),D=Ze(Se);if(!D.actor)return M({ok:!1,error:"An organization actor is required."},403);try{return M({ok:!0,comment:bt.addComment({findingId:String(T.findingId??""),actorId:D.actor.id,body:String(T.body??""),referenceUrl:typeof T.referenceUrl==="string"?T.referenceUrl:void 0})},201)}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Comment could not be saved."},422)}}if(W.pathname==="/api/auth/sessions"&&L.method==="GET"){let T=gr.resolveSession(L);return M({currentSessionId:T?.id,sessions:T?Le.listSessions(T.identityId,{includeInactive:!0}):[]})}if(W.pathname==="/api/auth/sessions"&&L.method==="DELETE"){let T=await se(L),D=gr.resolveSession(L);if(!D)return M({ok:!1,error:"Sign in again to manage sessions."},401);let U=String(T.id??""),q=Le.revokeSession(D.identityId,U),G=U===D.id&&q?{"set-cookie":_u({secure:no})}:void 0;return M({ok:q,signedOut:U===D.id&&q},q?200:404,G)}if(W.pathname==="/api/auth/sessions/revoke-others"&&L.method==="POST"){let T=gr.resolveSession(L);if(!T)return M({ok:!1,error:"Sign in again to manage sessions."},401);return M({ok:!0,revoked:Le.revokeOtherSessions(T.identityId,T.id)})}if(W.pathname==="/api/auth/password/change"&&L.method==="POST"){let T=await se(L),D=String(T.currentPassword??""),U=String(T.password??""),q=Ze(Se),G=q.actor?Le.getIdentityByActor(q.actor.id):void 0;if(!G||!Yn(D,G.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);if(U.length<12)return M({ok:!1,error:"New password must be at least 12 characters."},422);if(Yn(U,G.passwordHash))return M({ok:!1,error:"Choose a different password."},409);let Z=ms(U),Q=Le.updatePassword(G.id,Z);Du(t,Q.username,Z);let ie=$c(Q.id,L,dt.requestIP(L)?.address??"unknown");return E.store.appendEvent({organizationId:E.organization.id,actorId:Q.actorId,type:"auth.password.changed"}),M({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":Va(ie.token,{secure:no,maxAgeMs:qe})})}if(W.pathname==="/api/auth/mfa/enroll"&&L.method==="POST"){let T=await se(L),D=gr.resolveSession(L),U=Ze(Se),q=U.actor?Le.getIdentityByActor(U.actor.id):void 0;if(!D||!q)return M({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Yn(String(T.password??""),q.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);try{let G=Le.beginTotpEnrollment(q.id,{issuer:E.organization.name});return E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.mfa.enrollment.started"}),M({factor:G.factor,secret:G.secret,uri:G.uri})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"MFA enrollment failed."},409)}}if(W.pathname==="/api/auth/mfa/verify"&&L.method==="POST"){let T=await se(L),D=gr.resolveSession(L),U=Ze(Se),q=U.actor?Le.getIdentityByActor(U.actor.id):void 0;if(!D||!q)return M({ok:!1,error:"Sign in again before enabling MFA."},401);try{let G=Le.verifyTotpEnrollment(q.id,String(T.code??""));return Le.markSessionStepUp(D.id,!0),E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:G.recoveryCodes.length}}),M(G)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"MFA enrollment failed."},422)}}if(W.pathname==="/api/auth/mfa"&&L.method==="DELETE"){let T=await se(L),D=gr.resolveSession(L),U=Ze(Se),q=U.actor?Le.getIdentityByActor(U.actor.id):void 0;if(!D||!q||!Yn(String(T.password??""),q.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);let G=Le.verifyMfaCode(q.id,String(T.code??""));if(!G.valid||!G.method)return M({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return Le.disableMfa(q.id),Le.revokeOtherSessions(q.id,D.id),Le.markSessionStepUp(D.id),E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.mfa.disabled",payload:{method:G.method}}),M({ok:!0})}if(W.pathname==="/api/auth/step-up"&&L.method==="POST"){let T=await se(L),D=gr.resolveSession(L),U=Ze(Se),q=U.actor?Le.getIdentityByActor(U.actor.id):void 0;if(!D||!q||!Yn(String(T.password??""),q.passwordHash))return M({ok:!1,error:"Current password is incorrect."},401);let G=Le.getMfaFactor(q.id);if(G?.state==="active"){if(!Le.verifyMfaCode(q.id,String(T.code??"")).valid)return M({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let Z=Le.markSessionStepUp(D.id,G?.state==="active");return E.store.appendEvent({organizationId:E.organization.id,actorId:q.actorId,type:"auth.step_up.succeeded",payload:{mfa:G?.state==="active"}}),M({ok:!0,recentAuthAt:Z.recentAuthAt})}if(W.pathname==="/api/terminal"){if(!be)return M({ok:!1,error:"The web terminal is disabled."},403);if(dt.upgrade(L))return;return Fu("WebSocket upgrade failed",400)}if(W.pathname==="/api/health"){let T=E.store.health();return M({ok:!0,cwd:t,environment:De,environments:x,uiRoot:await dr(Se,De),liveData:me.size>0,terminal:be,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:T.schemaVersion,supportedSchemaVersion:T.supportedSchemaVersion,integrity:T.integrity,pendingRetryableOperations:T.pendingRetryableOperations}})}if(W.pathname==="/api/control-plane/operations"){let T=W.searchParams.get("state"),D=T&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(T)?T:void 0;return M({operations:E.store.listOperations({projectId:E.project.id,state:D,kind:W.searchParams.get("kind")??void 0,limit:Number(W.searchParams.get("limit"))||100})})}if(W.pathname==="/api/queue"&&L.method==="GET"){let T=W.searchParams.get("state"),D=T&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(T)?T:void 0,U=nr.list({projectId:E.project.id,state:D,limit:Number(W.searchParams.get("limit"))||250}).filter((q)=>Ys(Se,q.operation.id,"deployments:read")).map((q)=>{let G=q.operation.resourceId?E.store.getResource(q.operation.resourceId):void 0,Z=q.operation.environmentId?E.store.listEnvironments(E.project.id).find((Ae)=>Ae.id===q.operation.environmentId):void 0,Q=q.operation.actorId?E.store.getActor(q.operation.actorId):void 0,ie=q.operation.input;return{...q,target:G?{id:G.id,name:G.name,slug:G.slug,kind:G.kind}:Z?{id:Z.id,name:Z.name,slug:Z.slug,kind:"environment"}:{id:E.project.id,name:E.project.name,slug:E.project.slug,kind:"project"},actor:Q?{id:Q.id,name:Q.displayName,kind:Q.kind}:void 0,commit:ie.revision??ie.source?.commitSha??null}});return M({operations:U,concurrency:nr.limits})}if(W.pathname==="/api/queue/logs"&&L.method==="GET"){let T=String(W.searchParams.get("id")??"");if(!Ys(Se,T,"deployments:read"))return M({ok:!1,error:"Operation was not found in this scope."},404);let D=nr.logs(T,{after:Number(W.searchParams.get("after"))||0,limit:Number(W.searchParams.get("limit"))||500});return M({entries:D,cursor:D.at(-1)?.sequence??(Number(W.searchParams.get("after"))||0),operation:E.store.getOperation(T)})}if(W.pathname==="/api/queue/stream"&&L.method==="GET"){let T=String(W.searchParams.get("id")??"");if(!Ys(Se,T,"deployments:read"))return M({ok:!1,error:"Operation was not found in this scope."},404);let D=L.headers.get("last-event-id")?.trim(),U=Number(D||W.searchParams.get("after")||0),q=new TextEncoder,G,Z=!1,Q=new ReadableStream({start(ie){let Ae=()=>{if(Z)return;let ke=gr.resolveUser(L);if(!ke||!Ys(ke,T,"deployments:read")){if(Z=!0,G)clearInterval(G);ie.close();return}let ot=nr.logs(T,{after:U,limit:500});for(let et of ot)U=et.sequence,ie.enqueue(q.encode(`id: ${et.sequence}
686
686
  event: log
687
687
  data: ${JSON.stringify(et)}
688
688
 
689
689
  `));let Oe=E.store.getOperation(T);if(Oe&&["succeeded","failed","cancelled","timed_out"].includes(Oe.state)&&nr.logs(T,{after:U,limit:1}).length===0){if(Z=!0,G)clearInterval(G);ie.enqueue(q.encode(`event: complete
690
690
  data: ${JSON.stringify({state:Oe.state,cursor:U})}
691
691
 
692
- `)),ie.close()}};if(Ae(),!Z)G=setInterval(Ae,500);L.signal.addEventListener("abort",()=>{if(Z=!0,G)clearInterval(G);try{ie.close()}catch{}},{once:!0})},cancel(){if(Z=!0,G)clearInterval(G)}});return new Response(Q,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no"}})}if(W.pathname==="/api/queue/cancel"&&L.method==="POST"){let T=await se(L),D=String(T.id??"");if(!Ys(Se,D,"deployments:cancel"))return M({ok:!1,error:"Operation was not found or cannot be cancelled in this scope."},404);let U=S(E.store,Se);try{return M({ok:!0,operation:nr.requestCancellation(D,U.id)})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Cancellation failed."},409)}}if(W.pathname==="/api/queue/retry"&&L.method==="POST"){let T=await se(L),D=String(T.id??"");if(!Ys(Se,D,"deployments:create"))return M({ok:!1,error:"Operation was not found or cannot be retried in this scope."},404);let U=S(E.store,Se);try{return M({ok:!0,operation:nr.retry(D,String(T.errorClass??"manual"),{delayMs:Number(T.delayMs)||0,actorId:U.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Retry failed."},409)}}if(W.pathname==="/api/queue/settings"&&L.method==="GET")return M({concurrency:nr.limits});if(W.pathname==="/api/queue/settings"&&L.method==="PATCH"){let T=await se(L);if(T.confirm!=="update queue limits")return M({ok:!1,error:'Type "update queue limits" to confirm production concurrency changes.'},409);let D=S(E.store,Se);return M({ok:!0,concurrency:nr.configureConcurrency(T.concurrency??{},{organizationId:E.organization.id,actorId:D.id})})}if(W.pathname==="/api/queue/history"&&L.method==="DELETE"){let T=await se(L);if(T.confirm!=="clear completed")return M({ok:!1,error:'Type "clear completed" to confirm retained history cleanup.'},409);let D=S(E.store,Se);return M({ok:!0,deleted:nr.clearCompleted({projectId:E.project.id,before:typeof T.before==="string"?T.before:void 0,actorId:D.id})})}if(W.pathname==="/api/previews"&&L.method==="GET"){let T=wr.previews.listInstances({projectId:E.project.id}).filter((q)=>rn(Se,q.resourceId,"deployments:read")),D=wr.previews.listDefinitions(E.project.id).filter((q)=>rn(Se,q.resourceId,"project:read")),U=E.store.listResources(E.project.id).filter((q)=>q.kind==="application"&&rn(Se,q.id,"project:read")).map((q)=>({id:q.id,slug:q.slug,name:q.name,environmentId:q.environmentId}));return M({previews:T,definitions:D,resources:U,environments:[...E.environments.values()]})}if(W.pathname==="/api/releases"&&L.method==="GET"){let T=[...E.environments.values()],D=E.store.listResources(E.project.id).filter((G)=>rn(Se,G.id,"deployments:read")),U=new Set(D.map((G)=>G.id)),q=$n.releases.list({projectId:E.project.id}).filter((G)=>U.has(G.resourceId)).map((G)=>{let Z=D.find((Ae)=>Ae.id===G.resourceId),Q=T.find((Ae)=>Ae.id===G.environmentId),ie=G.previousReleaseId?$n.releases.get(G.previousReleaseId):void 0;return{...G,resource:Z?{id:Z.id,name:Z.name,slug:Z.slug,provider:Z.provider}:void 0,environment:Q?{id:Q.id,name:Q.name,slug:Q.slug,kind:Q.kind}:void 0,artifact:$n.releases.getArtifact(G.artifactId),transitions:$n.releases.transitions(G.id),approvals:$n.releases.approvals(G.id),previous:ie,comparison:ie?$n.releases.compare(ie.id,G.id):void 0,capabilities:$r({kind:G.kind,provider:Z?.provider,hasHealthGate:!!G.healthGate,replicas:Number(G.manifest?.replicas)||1})}});return M({releases:q,resources:D.map((G)=>({id:G.id,name:G.name,slug:G.slug,environmentId:G.environmentId,provider:G.provider})),environments:T})}if(W.pathname==="/api/releases/action"&&L.method==="POST"){let T=await se(L),D=$n.releases.get(String(T.id??"")),U=String(T.action??"");if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Release was not found in this scope."},404);let q=S(E.store,Se);try{if(U==="activate")return M({ok:!0,operation:$n.enqueueActivation(D,{actorId:q.id})});if(U==="rollback"){let G=E.store.getResource(D.resourceId);if(T.confirm!==G?.slug)return M({ok:!1,error:`Type "${G?.slug??""}" to confirm rollback.`},409);return M({ok:!0,operation:$n.enqueueRollback(D,{actorId:q.id,targetReleaseId:typeof T.targetReleaseId==="string"?T.targetReleaseId:void 0})})}if(U==="approve"){let G=E.store.listEnvironments(D.projectId).find((Z)=>Z.id===D.environmentId);if(T.confirm!==G?.slug)return M({ok:!1,error:`Type "${G?.slug??""}" to confirm the environment gate.`},409);return M({ok:!0,release:$n.releases.approve(D.id,{actorId:q.id,decision:T.decision==="rejected"?"rejected":"approved",comment:typeof T.comment==="string"?T.comment:void 0})})}if(U==="pin")return M({ok:!0,release:$n.releases.pin(D.id,T.pinned!==!1,typeof T.reason==="string"?T.reason:void 0)});if(U==="promote"){let G=E.store.getResource(String(T.targetResourceId??"")),Z=G?E.store.listEnvironments(D.projectId).find((Q)=>Q.id===G.environmentId):void 0;if(!G||!Z||!rn(Se,G.id,"deployments:create"))return M({ok:!1,error:"Promotion target was not found in this scope."},404);if(T.confirm!==Z.slug)return M({ok:!1,error:`Type "${Z.slug}" to confirm promotion.`},409);return M({ok:!0,release:$n.releases.promote(D.id,{targetEnvironmentId:Z.id,targetResourceId:G.id,config:T.config&&typeof T.config==="object"?T.config:{},strategy:typeof T.strategy==="string"?T.strategy:void 0,actorId:q.id,approvalRequired:T.approvalRequired===!0})})}return M({ok:!1,error:"Unsupported release action."},422)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Release action failed."},409)}}if(W.pathname==="/api/compose"&&L.method==="GET"){let T=ro.applications.list({projectId:E.project.id}).filter((D)=>rn(Se,D.resourceId,"applications:read")).map((D)=>({...D,services:ro.applications.services(D.id)}));return M({applications:T,templates:yr(),environments:[...E.environments.values()]})}if(W.pathname==="/api/compose/preview"&&L.method==="POST"){let T=await se(L),D=String(T.environmentId??"");if(!Ya(Se,D,"applications:manage"))return M({ok:!1,error:"Environment was not found in this scope."},404);try{return M({ok:!0,result:ro.applications.preview(String(T.source??""),{name:String(T.name??""),slug:typeof T.slug==="string"?T.slug:void 0,projectId:E.project.id,environmentId:D})})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Compose could not be parsed."},422)}}if((W.pathname==="/api/compose/import"||W.pathname==="/api/compose/template")&&L.method==="POST"){let T=await se(L),D=String(T.environmentId??"");if(!Ya(Se,D,"applications:manage"))return M({ok:!1,error:"Environment was not found in this scope."},404);let U=S(E.store,Se);try{let q=W.pathname.endsWith("/template")?ro.applications.fromTemplate(String(T.templateId??""),T.inputs&&typeof T.inputs==="object"?T.inputs:{},{name:String(T.name??""),projectId:E.project.id,environmentId:D,version:typeof T.templateVersion==="string"?T.templateVersion:void 0,createdByActorId:U.id}):ro.applications.import(String(T.source??""),{name:String(T.name??""),slug:typeof T.slug==="string"?T.slug:void 0,projectId:E.project.id,environmentId:D,createdByActorId:U.id});return M({ok:!0,application:q.application,diagnostics:q.parsed.diagnostics})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Compose application could not be saved."},422)}}if(W.pathname==="/api/compose/action"&&L.method==="POST"){let T=await se(L),D=ro.applications.get(String(T.id??"")),U=String(T.action??""),q=U==="delete"||U==="stop"?"deployments:cancel":"deployments:create";if(!D||!rn(Se,D.resourceId,q))return M({ok:!1,error:"Compose application was not found in this scope."},404);try{let G=S(E.store,Se);return M({ok:!0,operation:ro.enqueue(D,U,{actorId:G.id,service:typeof T.service==="string"?T.service:void 0,replicas:Number.isFinite(Number(T.replicas))?Number(T.replicas):void 0,removeVolumes:T.removeVolumes===!0,confirmation:typeof T.confirm==="string"?T.confirm:void 0})})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Compose operation could not be queued."},409)}}if((W.pathname==="/api/compose/logs"||W.pathname==="/api/compose/shell")&&L.method==="POST"){let T=await se(L),D=ro.applications.get(String(T.id??"")),U=W.pathname.endsWith("/shell"),q=U?"runtime:terminal":"runtime:logs";if(!D||!rn(Se,D.resourceId,q))return M({ok:!1,error:"Compose service was not found in this scope."},404);let G=String(T.service??"");if(!D.manifest.spec.services[G])return M({ok:!1,error:"Compose service was not found."},404);if(U&&T.confirm!==G)return M({ok:!1,error:`Type "${G}" to run a service command.`},409);let Z=E.store.listEnvironments(D.projectId).find((ie)=>ie.id===D.environmentId)?.slug;if(!Z)return M({ok:!1,error:"Compose environment was not found."},404);let Q=U?Ic(D.manifest,G,Array.isArray(T.command)?T.command.map(String):["sh"]):yc(D.manifest,G,Number(T.lines)||200);return M(await kc(h,Z,Q))}if(W.pathname==="/api/previews/definitions"&&L.method==="POST"){let T=await se(L),D=String(T.resourceId??"");if(!rn(Se,D,"config:write"))return M({ok:!1,error:"Application was not found in this scope."},404);let U=S(E.store,Se);try{return M({ok:!0,definition:wr.previews.createDefinition({...T,projectId:E.project.id,resourceId:D,baseEnvironmentId:String(T.baseEnvironmentId??""),domainPattern:String(T.domainPattern??""),createdByActorId:U.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Preview policy could not be created."},409)}}if(W.pathname==="/api/previews/deploy"&&L.method==="POST"){let T=await se(L),D=wr.previews.getDefinition(String(T.definitionId??""));if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Preview policy was not found in this scope."},404);let U=S(E.store,Se);try{let q=wr.previews.upsert({definitionId:D.id,sourceProvider:"dashboard",repository:"dashboard",branch:String(T.branch??""),pullRequestNumber:Number(T.pullRequestNumber)||void 0,commitSha:String(T.commitSha??""),createdByActorId:U.id});return M({ok:!0,preview:q.preview,operation:wr.enqueueDeploy(q.preview,{created:q.created,actorId:U.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Preview could not be queued."},409)}}if(W.pathname==="/api/previews/destroy"&&L.method==="POST"){let T=await se(L),D=wr.previews.getInstance(String(T.id??""));if(!D||!rn(Se,D.resourceId,"deployments:cancel"))return M({ok:!1,error:"Preview was not found in this scope."},404);if(T.confirm!==D.name)return M({ok:!1,error:`Type "${D.name}" to confirm tagged teardown.`},409);let U=S(E.store,Se);return M({ok:!0,operation:wr.enqueueDestroy(D,"dashboard",U.id)})}if(W.pathname==="/api/previews/extend"&&L.method==="POST"){let T=await se(L),D=wr.previews.getInstance(String(T.id??""));if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Preview was not found in this scope."},404);return M({ok:!0,preview:wr.previews.extend(D.id,Number(T.hours))})}if(W.pathname==="/api/previews/rebuild"&&L.method==="POST"){let T=await se(L),D=wr.previews.getInstance(String(T.id??""));if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Preview was not found in this scope."},404);let U=S(E.store,Se);return M({ok:!0,operation:wr.enqueueDeploy(D,{actorId:U.id,reason:"manual_rebuild"})})}if(W.pathname==="/api/previews/cleanup"&&L.method==="POST"){let T=await se(L);if(!T.dryRun&&T.confirm!=="cleanup previews")return M({ok:!1,error:'Type "cleanup previews" to confirm teardown.'},409);let D=S(E.store,Se);return M({ok:!0,...wr.cleanup({dryRun:T.dryRun===!0,maxAgeHours:Number(T.maxAgeHours)||void 0,keepCount:Number(T.keepCount)||void 0,actorId:D.id})})}if(W.pathname==="/api/control-plane/events")return M({events:E.store.listEvents({organizationId:E.organization.id,projectId:E.project.id,operationId:W.searchParams.get("operationId")??void 0,correlationId:W.searchParams.get("correlationId")??void 0,afterSequence:Number(W.searchParams.get("afterSequence"))||void 0,limit:Number(W.searchParams.get("limit"))||200})});if(W.pathname==="/api/search"){let T=String(W.searchParams.get("q")??"").trim().slice(0,128),D=jn.role==="member"?new Set(Object.keys(jn.sites)):void 0,U=T?ys(E.store,{projectId:E.project.id,query:T,allowedResourceSlugs:D,limit:Number(W.searchParams.get("limit"))||20}):[];return M({query:T,results:U,stale:!1})}if(W.pathname==="/api/search/preferences"&&L.method==="GET"){let T=`dashboard:${Se.username.toLowerCase()}`;return M({savedFilters:E.store.listSavedFilters(T),navigation:E.store.listNavigation(T)})}if(W.pathname==="/api/search/preferences"&&L.method==="POST"){let T=`dashboard:${Se.username.toLowerCase()}`,D=await se(L),U=String(D.action??"");if(U==="save-filter")return M({savedFilter:E.store.saveFilter(T,String(D.name??""),String(D.routeId??""),D.query??{})});if(U==="favorite")return M({navigation:E.store.setFavorite(T,String(D.entityType??""),String(D.entityId??""),D.favorite!==!1)});if(U==="visit")return M({navigation:E.store.recordNavigation(T,String(D.entityType??""),String(D.entityId??""))});return M({ok:!1,error:"Unknown search preference action."},422)}if(W.pathname==="/api/search/preferences"&&L.method==="DELETE"){let T=`dashboard:${Se.username.toLowerCase()}`,D=await se(L);return M({ok:E.store.deleteSavedFilter(T,String(D.id??""))})}if(W.pathname==="/api/organization"&&L.method==="GET"){let T=E.store.listMemberships(E.organization.id,{includeRevoked:!0}).map((D)=>{let U=E.store.getActor(D.actorId);return{...D,actor:U?{id:U.id,displayName:U.displayName,externalId:U.externalId,disabledAt:U.disabledAt}:void 0,grants:E.store.listGrants(D.id)}});return M({organization:E.organization,project:E.project,environments:E.store.listEnvironments(E.project.id),resources:E.store.listResources(E.project.id).map((D)=>({id:D.id,environmentId:D.environmentId,kind:D.kind,slug:D.slug,name:D.name})),memberships:T,invitations:E.store.listInvitations(E.organization.id)})}if(W.pathname==="/api/organization/invitations"&&L.method==="GET")return M({invitations:E.store.listInvitations(E.organization.id)});if(W.pathname==="/api/organization/invitations"&&L.method==="POST"){let T=await se(L),D=Mu(T.roleTemplate),U=Pc(T);if(!D||!U)return M({ok:!1,error:"Choose a valid role template and resource scope."},422);let q=Xe(Se);if(!q.actor||!q.membership)return M({ok:!1,error:"Your organization membership is unavailable."},403);if(D==="owner"&&(!Yn(String(T.password??""),Se.passwordHash)||q.membership.roleTemplate!=="owner"))return M({ok:!1,error:"Owner invitations require an owner to re-enter their password."},401);try{let G=E.store.createInvitation({organizationId:E.organization.id,email:String(T.email??""),roleTemplate:D,scope:U,invitedByActorId:q.actor.id,expiresInMs:Number(T.expiresInMs)||void 0}),Z=`${W.origin}/accept-invitation?token=${encodeURIComponent(G.token)}`,Q=await Lr(h,{to:G.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${Z}
692
+ `)),ie.close()}};if(Ae(),!Z)G=setInterval(Ae,500);L.signal.addEventListener("abort",()=>{if(Z=!0,G)clearInterval(G);try{ie.close()}catch{}},{once:!0})},cancel(){if(Z=!0,G)clearInterval(G)}});return new Response(Q,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no"}})}if(W.pathname==="/api/queue/cancel"&&L.method==="POST"){let T=await se(L),D=String(T.id??"");if(!Ys(Se,D,"deployments:cancel"))return M({ok:!1,error:"Operation was not found or cannot be cancelled in this scope."},404);let U=S(E.store,Se);try{return M({ok:!0,operation:nr.requestCancellation(D,U.id)})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Cancellation failed."},409)}}if(W.pathname==="/api/queue/retry"&&L.method==="POST"){let T=await se(L),D=String(T.id??"");if(!Ys(Se,D,"deployments:create"))return M({ok:!1,error:"Operation was not found or cannot be retried in this scope."},404);let U=S(E.store,Se);try{return M({ok:!0,operation:nr.retry(D,String(T.errorClass??"manual"),{delayMs:Number(T.delayMs)||0,actorId:U.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Retry failed."},409)}}if(W.pathname==="/api/queue/settings"&&L.method==="GET")return M({concurrency:nr.limits});if(W.pathname==="/api/queue/settings"&&L.method==="PATCH"){let T=await se(L);if(T.confirm!=="update queue limits")return M({ok:!1,error:'Type "update queue limits" to confirm production concurrency changes.'},409);let D=S(E.store,Se);return M({ok:!0,concurrency:nr.configureConcurrency(T.concurrency??{},{organizationId:E.organization.id,actorId:D.id})})}if(W.pathname==="/api/queue/history"&&L.method==="DELETE"){let T=await se(L);if(T.confirm!=="clear completed")return M({ok:!1,error:'Type "clear completed" to confirm retained history cleanup.'},409);let D=S(E.store,Se);return M({ok:!0,deleted:nr.clearCompleted({projectId:E.project.id,before:typeof T.before==="string"?T.before:void 0,actorId:D.id})})}if(W.pathname==="/api/previews"&&L.method==="GET"){let T=wr.previews.listInstances({projectId:E.project.id}).filter((q)=>rn(Se,q.resourceId,"deployments:read")),D=wr.previews.listDefinitions(E.project.id).filter((q)=>rn(Se,q.resourceId,"project:read")),U=E.store.listResources(E.project.id).filter((q)=>q.kind==="application"&&rn(Se,q.id,"project:read")).map((q)=>({id:q.id,slug:q.slug,name:q.name,environmentId:q.environmentId}));return M({previews:T,definitions:D,resources:U,environments:[...E.environments.values()]})}if(W.pathname==="/api/releases"&&L.method==="GET"){let T=[...E.environments.values()],D=E.store.listResources(E.project.id).filter((G)=>rn(Se,G.id,"deployments:read")),U=new Set(D.map((G)=>G.id)),q=$n.releases.list({projectId:E.project.id}).filter((G)=>U.has(G.resourceId)).map((G)=>{let Z=D.find((Ae)=>Ae.id===G.resourceId),Q=T.find((Ae)=>Ae.id===G.environmentId),ie=G.previousReleaseId?$n.releases.get(G.previousReleaseId):void 0;return{...G,resource:Z?{id:Z.id,name:Z.name,slug:Z.slug,provider:Z.provider}:void 0,environment:Q?{id:Q.id,name:Q.name,slug:Q.slug,kind:Q.kind}:void 0,artifact:$n.releases.getArtifact(G.artifactId),transitions:$n.releases.transitions(G.id),approvals:$n.releases.approvals(G.id),previous:ie,comparison:ie?$n.releases.compare(ie.id,G.id):void 0,capabilities:$r({kind:G.kind,provider:Z?.provider,hasHealthGate:!!G.healthGate,replicas:Number(G.manifest?.replicas)||1})}});return M({releases:q,resources:D.map((G)=>({id:G.id,name:G.name,slug:G.slug,environmentId:G.environmentId,provider:G.provider})),environments:T})}if(W.pathname==="/api/releases/action"&&L.method==="POST"){let T=await se(L),D=$n.releases.get(String(T.id??"")),U=String(T.action??"");if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Release was not found in this scope."},404);let q=S(E.store,Se);try{if(U==="activate")return M({ok:!0,operation:$n.enqueueActivation(D,{actorId:q.id})});if(U==="rollback"){let G=E.store.getResource(D.resourceId);if(T.confirm!==G?.slug)return M({ok:!1,error:`Type "${G?.slug??""}" to confirm rollback.`},409);return M({ok:!0,operation:$n.enqueueRollback(D,{actorId:q.id,targetReleaseId:typeof T.targetReleaseId==="string"?T.targetReleaseId:void 0})})}if(U==="approve"){let G=E.store.listEnvironments(D.projectId).find((Z)=>Z.id===D.environmentId);if(T.confirm!==G?.slug)return M({ok:!1,error:`Type "${G?.slug??""}" to confirm the environment gate.`},409);return M({ok:!0,release:$n.releases.approve(D.id,{actorId:q.id,decision:T.decision==="rejected"?"rejected":"approved",comment:typeof T.comment==="string"?T.comment:void 0})})}if(U==="pin")return M({ok:!0,release:$n.releases.pin(D.id,T.pinned!==!1,typeof T.reason==="string"?T.reason:void 0)});if(U==="promote"){let G=E.store.getResource(String(T.targetResourceId??"")),Z=G?E.store.listEnvironments(D.projectId).find((Q)=>Q.id===G.environmentId):void 0;if(!G||!Z||!rn(Se,G.id,"deployments:create"))return M({ok:!1,error:"Promotion target was not found in this scope."},404);if(T.confirm!==Z.slug)return M({ok:!1,error:`Type "${Z.slug}" to confirm promotion.`},409);return M({ok:!0,release:$n.releases.promote(D.id,{targetEnvironmentId:Z.id,targetResourceId:G.id,config:T.config&&typeof T.config==="object"?T.config:{},strategy:typeof T.strategy==="string"?T.strategy:void 0,actorId:q.id,approvalRequired:T.approvalRequired===!0})})}return M({ok:!1,error:"Unsupported release action."},422)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Release action failed."},409)}}if(W.pathname==="/api/compose"&&L.method==="GET"){let T=ro.applications.list({projectId:E.project.id}).filter((D)=>rn(Se,D.resourceId,"applications:read")).map((D)=>({...D,services:ro.applications.services(D.id)}));return M({applications:T,templates:yr(),environments:[...E.environments.values()]})}if(W.pathname==="/api/compose/preview"&&L.method==="POST"){let T=await se(L),D=String(T.environmentId??"");if(!Ya(Se,D,"applications:manage"))return M({ok:!1,error:"Environment was not found in this scope."},404);try{return M({ok:!0,result:ro.applications.preview(String(T.source??""),{name:String(T.name??""),slug:typeof T.slug==="string"?T.slug:void 0,projectId:E.project.id,environmentId:D})})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Compose could not be parsed."},422)}}if((W.pathname==="/api/compose/import"||W.pathname==="/api/compose/template")&&L.method==="POST"){let T=await se(L),D=String(T.environmentId??"");if(!Ya(Se,D,"applications:manage"))return M({ok:!1,error:"Environment was not found in this scope."},404);let U=S(E.store,Se);try{let q=W.pathname.endsWith("/template")?ro.applications.fromTemplate(String(T.templateId??""),T.inputs&&typeof T.inputs==="object"?T.inputs:{},{name:String(T.name??""),projectId:E.project.id,environmentId:D,version:typeof T.templateVersion==="string"?T.templateVersion:void 0,createdByActorId:U.id}):ro.applications.import(String(T.source??""),{name:String(T.name??""),slug:typeof T.slug==="string"?T.slug:void 0,projectId:E.project.id,environmentId:D,createdByActorId:U.id});return M({ok:!0,application:q.application,diagnostics:q.parsed.diagnostics})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Compose application could not be saved."},422)}}if(W.pathname==="/api/compose/action"&&L.method==="POST"){let T=await se(L),D=ro.applications.get(String(T.id??"")),U=String(T.action??""),q=U==="delete"||U==="stop"?"deployments:cancel":"deployments:create";if(!D||!rn(Se,D.resourceId,q))return M({ok:!1,error:"Compose application was not found in this scope."},404);try{let G=S(E.store,Se);return M({ok:!0,operation:ro.enqueue(D,U,{actorId:G.id,service:typeof T.service==="string"?T.service:void 0,replicas:Number.isFinite(Number(T.replicas))?Number(T.replicas):void 0,removeVolumes:T.removeVolumes===!0,confirmation:typeof T.confirm==="string"?T.confirm:void 0})})}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Compose operation could not be queued."},409)}}if((W.pathname==="/api/compose/logs"||W.pathname==="/api/compose/shell")&&L.method==="POST"){let T=await se(L),D=ro.applications.get(String(T.id??"")),U=W.pathname.endsWith("/shell"),q=U?"runtime:terminal":"runtime:logs";if(!D||!rn(Se,D.resourceId,q))return M({ok:!1,error:"Compose service was not found in this scope."},404);let G=String(T.service??"");if(!D.manifest.spec.services[G])return M({ok:!1,error:"Compose service was not found."},404);if(U&&T.confirm!==G)return M({ok:!1,error:`Type "${G}" to run a service command.`},409);let Z=E.store.listEnvironments(D.projectId).find((ie)=>ie.id===D.environmentId)?.slug;if(!Z)return M({ok:!1,error:"Compose environment was not found."},404);let Q=U?Ic(D.manifest,G,Array.isArray(T.command)?T.command.map(String):["sh"]):yc(D.manifest,G,Number(T.lines)||200);return M(await kc(h,Z,Q))}if(W.pathname==="/api/previews/definitions"&&L.method==="POST"){let T=await se(L),D=String(T.resourceId??"");if(!rn(Se,D,"config:write"))return M({ok:!1,error:"Application was not found in this scope."},404);let U=S(E.store,Se);try{return M({ok:!0,definition:wr.previews.createDefinition({...T,projectId:E.project.id,resourceId:D,baseEnvironmentId:String(T.baseEnvironmentId??""),domainPattern:String(T.domainPattern??""),createdByActorId:U.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Preview policy could not be created."},409)}}if(W.pathname==="/api/previews/deploy"&&L.method==="POST"){let T=await se(L),D=wr.previews.getDefinition(String(T.definitionId??""));if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Preview policy was not found in this scope."},404);let U=S(E.store,Se);try{let q=wr.previews.upsert({definitionId:D.id,sourceProvider:"dashboard",repository:"dashboard",branch:String(T.branch??""),pullRequestNumber:Number(T.pullRequestNumber)||void 0,commitSha:String(T.commitSha??""),createdByActorId:U.id});return M({ok:!0,preview:q.preview,operation:wr.enqueueDeploy(q.preview,{created:q.created,actorId:U.id})})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Preview could not be queued."},409)}}if(W.pathname==="/api/previews/destroy"&&L.method==="POST"){let T=await se(L),D=wr.previews.getInstance(String(T.id??""));if(!D||!rn(Se,D.resourceId,"deployments:cancel"))return M({ok:!1,error:"Preview was not found in this scope."},404);if(T.confirm!==D.name)return M({ok:!1,error:`Type "${D.name}" to confirm tagged teardown.`},409);let U=S(E.store,Se);return M({ok:!0,operation:wr.enqueueDestroy(D,"dashboard",U.id)})}if(W.pathname==="/api/previews/extend"&&L.method==="POST"){let T=await se(L),D=wr.previews.getInstance(String(T.id??""));if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Preview was not found in this scope."},404);return M({ok:!0,preview:wr.previews.extend(D.id,Number(T.hours))})}if(W.pathname==="/api/previews/rebuild"&&L.method==="POST"){let T=await se(L),D=wr.previews.getInstance(String(T.id??""));if(!D||!rn(Se,D.resourceId,"deployments:create"))return M({ok:!1,error:"Preview was not found in this scope."},404);let U=S(E.store,Se);return M({ok:!0,operation:wr.enqueueDeploy(D,{actorId:U.id,reason:"manual_rebuild"})})}if(W.pathname==="/api/previews/cleanup"&&L.method==="POST"){let T=await se(L);if(!T.dryRun&&T.confirm!=="cleanup previews")return M({ok:!1,error:'Type "cleanup previews" to confirm teardown.'},409);let D=S(E.store,Se);return M({ok:!0,...wr.cleanup({dryRun:T.dryRun===!0,maxAgeHours:Number(T.maxAgeHours)||void 0,keepCount:Number(T.keepCount)||void 0,actorId:D.id})})}if(W.pathname==="/api/control-plane/events")return M({events:E.store.listEvents({organizationId:E.organization.id,projectId:E.project.id,operationId:W.searchParams.get("operationId")??void 0,correlationId:W.searchParams.get("correlationId")??void 0,afterSequence:Number(W.searchParams.get("afterSequence"))||void 0,limit:Number(W.searchParams.get("limit"))||200})});if(W.pathname==="/api/search"){let T=String(W.searchParams.get("q")??"").trim().slice(0,128),D=jn.role==="member"?new Set(Object.keys(jn.sites)):void 0,U=T?ys(E.store,{projectId:E.project.id,query:T,allowedResourceSlugs:D,limit:Number(W.searchParams.get("limit"))||20}):[];return M({query:T,results:U,stale:!1})}if(W.pathname==="/api/search/preferences"&&L.method==="GET"){let T=`dashboard:${Se.username.toLowerCase()}`;return M({savedFilters:E.store.listSavedFilters(T),navigation:E.store.listNavigation(T)})}if(W.pathname==="/api/search/preferences"&&L.method==="POST"){let T=`dashboard:${Se.username.toLowerCase()}`,D=await se(L),U=String(D.action??"");if(U==="save-filter")return M({savedFilter:E.store.saveFilter(T,String(D.name??""),String(D.routeId??""),D.query??{})});if(U==="favorite")return M({navigation:E.store.setFavorite(T,String(D.entityType??""),String(D.entityId??""),D.favorite!==!1)});if(U==="visit")return M({navigation:E.store.recordNavigation(T,String(D.entityType??""),String(D.entityId??""))});return M({ok:!1,error:"Unknown search preference action."},422)}if(W.pathname==="/api/search/preferences"&&L.method==="DELETE"){let T=`dashboard:${Se.username.toLowerCase()}`,D=await se(L);return M({ok:E.store.deleteSavedFilter(T,String(D.id??""))})}if(W.pathname==="/api/organization"&&L.method==="GET"){let T=E.store.listMemberships(E.organization.id,{includeRevoked:!0}).map((D)=>{let U=E.store.getActor(D.actorId);return{...D,actor:U?{id:U.id,displayName:U.displayName,externalId:U.externalId,disabledAt:U.disabledAt}:void 0,grants:E.store.listGrants(D.id)}});return M({organization:E.organization,project:E.project,environments:E.store.listEnvironments(E.project.id),resources:E.store.listResources(E.project.id).map((D)=>({id:D.id,environmentId:D.environmentId,kind:D.kind,slug:D.slug,name:D.name})),memberships:T,invitations:E.store.listInvitations(E.organization.id)})}if(W.pathname==="/api/organization/invitations"&&L.method==="GET")return M({invitations:E.store.listInvitations(E.organization.id)});if(W.pathname==="/api/organization/invitations"&&L.method==="POST"){let T=await se(L),D=Mu(T.roleTemplate),U=Pc(T);if(!D||!U)return M({ok:!1,error:"Choose a valid role template and resource scope."},422);let q=Ze(Se);if(!q.actor||!q.membership)return M({ok:!1,error:"Your organization membership is unavailable."},403);if(D==="owner"&&(!Yn(String(T.password??""),Se.passwordHash)||q.membership.roleTemplate!=="owner"))return M({ok:!1,error:"Owner invitations require an owner to re-enter their password."},401);try{let G=E.store.createInvitation({organizationId:E.organization.id,email:String(T.email??""),roleTemplate:D,scope:U,invitedByActorId:q.actor.id,expiresInMs:Number(T.expiresInMs)||void 0}),Z=`${W.origin}/accept-invitation?token=${encodeURIComponent(G.token)}`,Q=await Lr(h,{to:G.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${Z}
693
693
 
694
- This link expires ${G.invitation.expiresAt} and can be used once.`});return M({invitation:G.invitation,token:G.token,acceptUrl:Z,delivered:Q},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Invitation could not be created."},422)}}if(W.pathname==="/api/organization/invitations"&&L.method==="DELETE"){let T=await se(L),D=Xe(Se);try{return M({invitation:E.store.revokeInvitation(String(T.id??""),D.actor?.id)})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Invitation could not be revoked."},409)}}if(W.pathname==="/api/organization/invitations/resend"&&L.method==="POST"){let T=await se(L),D=Xe(Se);try{let U=E.store.reissueInvitation(String(T.id??""),D.actor?.id),q=`${W.origin}/accept-invitation?token=${encodeURIComponent(U.token)}`,G=await Lr(h,{to:U.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${q}
694
+ This link expires ${G.invitation.expiresAt} and can be used once.`});return M({invitation:G.invitation,token:G.token,acceptUrl:Z,delivered:Q},201)}catch(G){return M({ok:!1,error:G instanceof Error?G.message:"Invitation could not be created."},422)}}if(W.pathname==="/api/organization/invitations"&&L.method==="DELETE"){let T=await se(L),D=Ze(Se);try{return M({invitation:E.store.revokeInvitation(String(T.id??""),D.actor?.id)})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Invitation could not be revoked."},409)}}if(W.pathname==="/api/organization/invitations/resend"&&L.method==="POST"){let T=await se(L),D=Ze(Se);try{let U=E.store.reissueInvitation(String(T.id??""),D.actor?.id),q=`${W.origin}/accept-invitation?token=${encodeURIComponent(U.token)}`,G=await Lr(h,{to:U.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${q}
695
695
 
696
- This replacement link expires ${U.invitation.expiresAt} and can be used once.`});return M({invitation:U.invitation,token:U.token,acceptUrl:q,delivered:G})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Invitation could not be resent."},409)}}if(W.pathname==="/api/organization/memberships"&&L.method==="PATCH"){let T=await se(L),D=E.store.getMembership(String(T.id??"")),U=Mu(T.roleTemplate),q=Pc(T);if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Membership was not found."},404);if(!U||!q)return M({ok:!1,error:"Choose a valid role template and resource scope."},422);let G=Xe(Se);if((D.roleTemplate==="owner"||U==="owner")&&(!Yn(String(T.password??""),Se.passwordHash)||G.membership?.roleTemplate!=="owner"))return M({ok:!1,error:"Ownership changes require an owner to re-enter their password."},401);let Q=E.store.resolveAuthorizationTarget(E.organization.id,q)??E.store.resolveAuthorizationTarget(E.organization.id,{type:"project",id:E.project.id}),ie=E.store.listGrants(D.id),Ae=Bt({membership:D,grants:ie,target:Q}),ke={...D,roleTemplate:U,scope:q},ot=Bt({membership:ke,grants:ie,target:Q}),Oe={gained:ot.filter((et)=>!Ae.includes(et)),lost:Ae.filter((et)=>!ot.includes(et))};if(T.preview===!0)return M({membership:D,proposed:{roleTemplate:U,scope:q},accessDiff:Oe});if(String(T.confirm??"")!==D.id)return M({ok:!1,error:`Confirm this change with membership ID ${D.id}.`,accessDiff:Oe},409);try{return M({membership:E.store.updateMembership({id:D.id,roleTemplate:U,scope:q,actorId:G.actor?.id}),accessDiff:Oe})}catch(et){return M({ok:!1,error:et instanceof Error?et.message:"Membership could not be updated."},409)}}if(W.pathname==="/api/organization/memberships"&&L.method==="DELETE"){let T=await se(L),D=E.store.getMembership(String(T.id??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Membership was not found."},404);if(String(T.confirm??"")!==D.id)return M({ok:!1,error:`Confirm removal with membership ID ${D.id}.`},409);let U=Xe(Se);if(D.roleTemplate==="owner"&&(U.membership?.roleTemplate!=="owner"||!Yn(String(T.password??""),Se.passwordHash)))return M({ok:!1,error:"Removing an owner requires an owner to re-enter their current password."},401);try{return M({membership:E.store.revokeMembership(D.id,U.actor?.id)})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Membership could not be removed."},409)}}if(W.pathname==="/api/organization/grants"&&L.method==="POST"){let T=await se(L),D=String(T.capability??""),U=T.effect==="deny"?"deny":T.effect==="allow"?"allow":void 0,q=Pc(T),G=Xe(Se);if(!U||!q||!ae.includes(D))return M({ok:!1,error:"Choose a valid capability, effect, and resource scope."},422);try{return M({grant:E.store.upsertGrant({organizationId:E.organization.id,membershipId:String(T.membershipId??""),effect:U,capability:D,scope:q,actorId:G.actor?.id})},201)}catch(Z){return M({ok:!1,error:Z instanceof Error?Z.message:"Grant could not be created."},422)}}if(W.pathname==="/api/organization/grants"&&L.method==="DELETE"){let T=await se(L),D=Xe(Se),U=E.store.getGrant(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Grant was not found."},404);return M({ok:E.store.removeGrant(U.id,D.actor?.id)})}if(W.pathname==="/api/tags"&&L.method==="GET")return M({tags:E.store.listTags(E.project.id),assignments:E.store.listResourceTags(E.project.id)});if(W.pathname==="/api/tags"&&L.method==="POST"){let T=await se(L),D=E.store.upsertTag(E.project.id,String(T.name??""),String(T.color??"#5a8be0"));if(T.resourceId)E.store.assignTag(String(T.resourceId),D.id);return M({tag:D},201)}if(W.pathname==="/api/tags"&&L.method==="DELETE"){let T=await se(L);return E.store.removeTag(String(T.resourceId??""),String(T.tagId??"")),M({ok:!0})}if(W.pathname==="/"&&!OS(W.pathname,jn))return new Response(null,{status:302,headers:{location:`/server/sites?env=${encodeURIComponent(De)}`}});if(W.pathname==="/"&&ur?.mode==="serverless")return new Response(null,{status:302,headers:{location:`/serverless?env=${encodeURIComponent(De)}`}});let jc=Pl(W.pathname);if(jc)return new Response(null,{status:308,headers:{location:`${jc}?env=${encodeURIComponent(De)}`}});if(W.pathname==="/api/env"&&L.method==="POST"){let T=await se(L),D=String(T.env??"");if(!x.includes(D))return M({ok:!1,error:`Unknown environment '${D}'.`,environments:x},404);return M({ok:!0,environment:D,environments:x,href:`?env=${encodeURIComponent(D)}`})}if(W.pathname==="/api/config"){let T={...Fi(h),environment:De,environments:x};return M(Kb(T,jn))}if(W.pathname==="/api/ssh-keys"&&L.method==="GET")return M({configPath:F,keys:gs(Ga(h))});if(W.pathname==="/api/ssh-keys"&&L.method==="POST"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=await pi(F,"utf8"),U=Ga(h),q=Yv({configText:D,name:String(T.name??""),publicKey:String(T.publicKey??""),existingKeys:U});return await Ws(F,q),_S(h,[...U,{name:String(T.name??"").trim(),publicKey:String(T.publicKey??"").trim().replace(/\s+/g," ")}]),M({ok:!0,configPath:F,keys:gs(Ga(h))})}if(W.pathname==="/api/ssh-keys"&&L.method==="DELETE"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??W.searchParams.get("name")??""),U=await pi(F,"utf8"),q=Ga(h),G=Zv({configText:U,name:D,existingKeys:q});return await Ws(F,G),_S(h,q.filter((Z)=>Z.name!==D.trim())),M({ok:!0,configPath:F,keys:gs(Ga(h))})}if(W.pathname==="/api/firewall"&&L.method==="GET")return M({configPath:F,alwaysOpen:[22,80,443],ports:Ug(h)});if(W.pathname==="/api/firewall"&&L.method==="POST"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=Number(T.port);if(!Rc(D))return M({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let U=Ug(h),q=await pi(F,"utf8");try{await Ws(F,tS(q,D,U))}catch(Q){return M({ok:!1,error:Q?.message??String(Q)},422)}let G=Vs([...U,D]);TS(h,G);let Z=T.apply===!1?null:await kc(h,De,`ufw allow ${D}/tcp`).catch((Q)=>({ok:!1,error:String(Q?.message??Q)}));return M({ok:!0,configPath:F,ports:G,apply:Z})}if(W.pathname==="/api/firewall"&&L.method==="DELETE"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=Number(T.port??W.searchParams.get("port"));if(!Rc(D))return M({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let U=Ug(h),q=await pi(F,"utf8");await Ws(F,rS(q,D,U));let G=Vs(U.filter((Q)=>Q!==D));TS(h,G);let Z=T.apply===!1?null:await kc(h,De,`ufw delete allow ${D}/tcp`).catch((Q)=>({ok:!1,error:String(Q?.message??Q)}));return M({ok:!0,configPath:F,ports:G,apply:Z})}if(W.pathname==="/api/sites"&&L.method==="POST"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??"").trim(),U=String(T.root??"").trim();if(!D||!U)return M({ok:!1,error:"Site name and root are required."},422);let q={deploy:T.deploy==="bucket"?"bucket":"server",root:U,path:String(T.path??"").trim()||void 0,domain:String(T.domain??"").trim()||void 0,build:String(T.build??"").trim()||void 0,start:String(T.start??"").trim()||void 0,port:T.port?Number(T.port):void 0,type:String(T.type??"").trim()||void 0};if(q.port!==void 0&&(!Number.isInteger(q.port)||q.port<1||q.port>65535))return M({ok:!1,error:"Port must be a number between 1 and 65535."},422);let G=await pi(F,"utf8"),Z=jr({configText:G,name:D,root:q.root,domain:q.domain,path:q.path,deploy:q.deploy,build:q.build,start:q.start,port:q.port,type:q.type});return await Ws(F,Z),H_(h,D,Object.fromEntries(Object.entries(q).filter(([,Q])=>Q!==void 0))),ur=await Ks(h,De),H.set(De,ur),M({ok:!0,configPath:F,site:D,data:ur})}if(W.pathname==="/api/sites"&&L.method==="DELETE"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??W.searchParams.get("name")??"").trim();if(!D||!h.sites?.[D])return M({ok:!1,error:`Site '${D}' was not found.`},404);let U=await pi(F,"utf8");return await Ws(F,zr({configText:U,name:D})),delete h.sites[D],ur=await Ks(h,De),H.set(De,ur),M({ok:!0,configPath:F,site:D,data:ur})}if(W.pathname==="/api/sites"&&L.method==="PATCH"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??"").trim(),U=h.sites?.[D];if(!D||!U)return M({ok:!1,error:`Site '${D}' was not found.`},404);if(jn.role==="member"){let Z=Yb(T);if(!Z.ok)return M({ok:!1,error:Z.error},403);let Q=Zb({siteName:D,body:T,sites:h.sites??{},ownSites:Object.keys(jn.sites)});if(!Q.ok)return M({ok:!1,error:Q.error},409)}if(T.port!==void 0&&T.port!==null&&T.port!==""&&(!Number.isInteger(Number(T.port))||Number(T.port)<1||Number(T.port)>65535))return M({ok:!1,error:"Port must be a number between 1 and 65535."},422);if(typeof T.domain==="string"&&T.domain.trim()&&!Xo(T.domain.trim()))return M({ok:!1,error:`Domain '${T.domain.trim()}' is not a valid hostname.`},422);let q=await pi(F,"utf8"),G=(Z,Q)=>{q=_i({configText:q,siteName:D,key:Z,valueText:Q})};if(T.ssl!==void 0)G("ssl",Cl(T.ssl)),U.ssl=T.ssl;if(T.env!==void 0&&T.env&&typeof T.env==="object")G("env",El(T.env)),U.env=T.env;if(T.aliases!==void 0&&Array.isArray(T.aliases)){let Z=T.aliases.map((Q)=>String(Q));G("aliases",vl(Z)),U.aliases=Z.map((Q)=>Q.trim().toLowerCase()).filter(Boolean)}if(T.redirects!==void 0&&T.redirects&&typeof T.redirects==="object")G("redirects",Tl(T.redirects)),U.redirects=T.redirects;for(let Z of["domain","path","build","start","type","root","php"])if(typeof T[Z]==="string"&&T[Z].trim())G(Z,bl(String(T[Z]).trim())),U[Z]=String(T[Z]).trim();if(T.port!==void 0&&T.port!==null&&T.port!=="")G("port",String(Number(T.port))),U.port=Number(T.port);return await Ws(F,q),ur=await Ks(h,De),H.set(De,ur),M({ok:!0,configPath:F,site:D,data:ur})}if(W.pathname==="/api/sites/deploy"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim();if(!D||!h.sites?.[D])return M({ok:!1,error:`Site '${D}' was not found.`},404);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to deploy this site.`},409);let U=ee(E,String(De));await new ut(bt).run(new Qr,{...U,artifactRoot:t}),Di(bt,U,ur??{});let q=Pi(bt,{scope:U,desiredConfigHash:E.project.desiredConfigHash});if(q.decision.outcome==="block")return M({ok:!1,error:`Deployment blocked by security policy: ${q.decision.explanation}`,securityReview:q},409);let G={id:`deploy:${D}`,label:`Deploy ${D}`,description:`Deploy the ${D} site for ${De}.`,command:["deploy","--env",De,"--site",D,"--yes"],mutates:!0},Z=await we({controlPlane:E,environment:De,actor:Se,kind:"dashboard.site.deploy",resourceSlug:D,input:{site:D},execute:()=>Hg(G,{cwd:t,cliEntry:m})});return M({...Z.result,controlPlaneOperation:Z.operation,securityReview:q})}if(W.pathname==="/api/actions")return M(Yr(De));if(W.pathname==="/api/server/operations")return M(Ou(h,ur));if(W.pathname==="/api/runtime/workloads"&&L.method==="GET"){let T=await te(h,De);return M(T)}if(W.pathname==="/api/runtime/logs"&&L.method==="GET"){let T=String(W.searchParams.get("workload")??"");if(!T)return M({ok:!1,error:"A workload query parameter is required."},422);let D=Math.min(1000,Math.max(1,Number(W.searchParams.get("limit"))||200));try{return M(await new le(h,De).logs(T,{limit:D}))}catch(U){return M({ok:!1,error:String(U?.message??U)},404)}}if(W.pathname==="/api/runtime/log-sessions"&&L.method==="POST"){let T=await se(L),D=String(T.workloadId??"");if(!D)return M({ok:!1,error:"A workloadId is required."},422);let U=await te(h,De),q=U.workloads.find((Q)=>Q.id===D);if(!q)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);if(!q.capabilities.logs.supported)return M({ok:!1,error:q.capabilities.logs.reason??"Logs are unsupported for this workload."},409);let G=new le(h,De,{inventory:async()=>U}),Z=Rr.create("logs",D);return(async()=>{let Q=new Date(Date.now()-Math.min(3600000,Math.max(1000,Number(T.sinceMs)||60000)));try{for(let ie=0;ie<200&&!Rr.signal(Z.id)?.aborted;ie++){let Ae=await G.logs(D,{limit:Math.min(500,Math.max(1,Number(T.limit)||200)),since:Q});for(let ke of Ae.lines)if(Rr.append(Z.id,`${ke.timestamp?`${ke.timestamp} `:""}${ke.message}
697
- `),ke.timestamp)Q=new Date(Math.max(Q.getTime(),new Date(ke.timestamp).getTime()+1));await Bun.sleep(3000)}if(!Rr.signal(Z.id)?.aborted)Rr.close(Z.id,"complete")}catch(ie){Rr.append(Z.id,ie instanceof Error?ie.message:String(ie),"stderr"),Rr.close(Z.id,"failed",ie instanceof Error?ie.message:String(ie))}})(),M({ok:!0,session:Z,streamUrl:`/api/runtime/log-stream?id=${encodeURIComponent(Z.id)}&workload=${encodeURIComponent(D)}`},201)}if((W.pathname==="/api/runtime/log-stream"||W.pathname==="/api/runtime/exec-stream")&&L.method==="GET"){let T=String(W.searchParams.get("id")??""),D=String(W.searchParams.get("workload")??""),U=Number(L.headers.get("last-event-id")??W.searchParams.get("after")??0)||0,q=Rr.read(T,D,U),G=W.pathname.includes("exec")?"exec":"logs";if(!q||q.kind!==G)return M({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return M_(Rr,q,U,L.signal)}if((W.pathname==="/api/runtime/log-sessions"||W.pathname==="/api/runtime/exec-sessions")&&L.method==="DELETE"){let T=await se(L),D=Rr.cancel(String(T.id??""),String(T.workloadId??""));if(!D)return M({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return M({ok:!0,session:D})}if(W.pathname==="/api/runtime/exec-sessions"&&L.method==="POST"){let T=await se(L),D=String(T.workloadId??""),U=await te(h,De),q=U.workloads.find((ie)=>ie.id===D);if(!q)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);let G=gr.resolveSession(L),Z=new le(h,De,{inventory:async()=>U}),Q=Rr.create("exec",D);return we({controlPlane:E,environment:De,actor:Se,kind:"runtime.exec",resourceSlug:q.links.service,input:{workloadId:D,provider:q.provider,preset:T.preset?String(T.preset):null,freeForm:!!String(T.command??"").trim()},execute:()=>Z.exec({workloadId:D,preset:["process","sockets","filesystem"].includes(String(T.preset))?String(T.preset):void 0,command:typeof T.command==="string"?T.command:void 0,confirm:String(T.confirm??""),recentAuth:!Be||!!G&&Fe.isRecentlyAuthenticated(G)})}).then(({result:ie,operation:Ae})=>{if(Rr.append(Q.id,`operation ${Ae.id}
698
- `,"system"),ie.stdout)Rr.append(Q.id,ie.stdout,"stdout");if(ie.stderr)Rr.append(Q.id,ie.stderr,"stderr");Rr.close(Q.id,ie.ok?"complete":"failed",ie.error)}).catch((ie)=>{let Ae=ie instanceof Error?ie.message:String(ie);Rr.append(Q.id,Ae,"stderr"),Rr.close(Q.id,"failed",Ae)}),M({ok:!0,session:Q,streamUrl:`/api/runtime/exec-stream?id=${encodeURIComponent(Q.id)}&workload=${encodeURIComponent(D)}`},202)}if(W.pathname==="/api/runtime/files/read"&&L.method==="POST"){let T=await se(L),D=await te(h,De),U=gr.resolveSession(L),q=await new le(h,De,{inventory:async()=>D}).readFile({workloadId:String(T.workloadId??""),path:String(T.path??""),confirm:String(T.confirm??""),recentAuth:!Be||!!U&&Fe.isRecentlyAuthenticated(U)});return M(q,q.ok?200:409)}if(W.pathname==="/api/runtime/files/write"&&L.method==="POST"){let T=await se(L),D=await te(h,De),U=String(T.workloadId??""),q=D.workloads.find((ie)=>ie.id===U);if(!q)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);let G=gr.resolveSession(L),Z=new le(h,De,{inventory:async()=>D}),Q=await we({controlPlane:E,environment:De,actor:Se,kind:"runtime.file.write",resourceSlug:q.links.service,input:{workloadId:U,provider:q.provider,path:String(T.path??""),bytes:Buffer.from(String(T.contentBase64??""),"base64").byteLength},execute:()=>Z.writeFile({workloadId:U,path:String(T.path??""),contentBase64:String(T.contentBase64??""),confirm:String(T.confirm??""),recentAuth:!Be||!!G&&Fe.isRecentlyAuthenticated(G)})});return M({...Q.result,controlPlaneOperation:Q.operation},Q.result.ok?200:409)}if(W.pathname==="/api/runtime/operations"&&L.method==="POST"){let T=await se(L),D=String(T.workloadId??""),U=String(T.action??"");if(!D||!["start","stop","restart","redeploy","scale","inspect"].includes(U))return M({ok:!1,error:"A valid workloadId and lifecycle action are required."},422);let q=await te(h,De),G=q.workloads.find((Ae)=>Ae.id===D);if(!G)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);let Z=gr.resolveSession(L),Q=new le(h,De,{inventory:async()=>q}),ie=await we({controlPlane:E,environment:De,actor:Se,kind:`runtime.${U}`,resourceSlug:G.links.service,input:{workloadId:D,provider:G.provider,action:U,replicas:T.replicas==null?null:Number(T.replicas)},execute:()=>Q.run({workloadId:D,action:U,replicas:T.replicas==null?void 0:Number(T.replicas),confirm:String(T.confirm??""),recentAuth:!Be||!!Z&&Fe.isRecentlyAuthenticated(Z)})});return M({...ie.result,controlPlaneOperation:ie.operation},ie.result.ok?200:409)}if(W.pathname.startsWith("/api/protection")){let T=Se.role==="admin"||Nc(Se,"security:read"),D=Se.role==="admin"||Nc(Se,"security:manage");if(!T)return M({ok:!1,error:"Protection controls require security:read."},403);let{ProtectionControlStore:U,describePosture:q}=await import("./protection/index.js"),G=new U(E.store),Z=()=>{if(!D)throw Error("Changing protection controls requires security:manage.")};if(W.pathname==="/api/protection"&&L.method==="GET"){let Q=G.current();return M({ok:!0,posture:q(Q),controls:Q,raw:G.raw()})}if(W.pathname==="/api/protection/attack-mode"&&L.method==="POST"){Z();let Q=await se(L);if(Q.enabled===!1)return M({ok:!0,disabled:G.disableAttackMode()});return M({ok:!0,control:G.enableAttackMode({hours:Q.hours==null?void 0:Number(Q.hours),reason:String(Q.reason??"Enabled from the dashboard."),actorId:Xe(Se).actor?.id})})}if(W.pathname==="/api/protection/pause"&&L.method==="POST"){Z();let Q=await se(L);if(Q.enabled===!1)return M({ok:!0,resumed:G.resumeMitigations()});return M({ok:!0,control:G.pauseMitigations({hours:Q.hours==null?void 0:Number(Q.hours),reason:String(Q.reason??""),actorId:Xe(Se).actor?.id})})}if(W.pathname==="/api/protection/ip-rules"&&L.method==="GET")return M({ok:!0,ipRules:G.current().ipRules});if(W.pathname==="/api/protection/ip-rules"&&(L.method==="POST"||L.method==="DELETE")){Z();let Q=await se(L),ie=Q.list==="allow"?"allow":"block",Ae=L.method==="POST"?G.addIpRule(ie,String(Q.cidr??"")):G.removeIpRule(ie,String(Q.cidr??""));return M({ok:!0,ipRules:Ae})}return M({ok:!1,error:"Protection endpoint was not found."},404)}if(W.pathname.startsWith("/api/spend/")||W.pathname==="/api/usage"){let T=await qS(),{store:D,service:U,gate:q}=T,G=Se.role==="admin"||Nc(Se,"billing:read"),Z=Se.role==="admin"||Nc(Se,"billing:manage");if(!G)return M({ok:!1,error:"Spend data requires the billing:read capability."},403);let Q=E.environments.get(De),ie={organizationId:E.organization.id,projectId:E.project.id,environmentId:Q?.id},Ae=()=>{if(!Z)throw Error("Changing a budget requires the billing:manage capability.")};if(W.pathname==="/api/usage"&&L.method==="GET")return M({ok:!0,...U.usageReport({organizationId:ie.organizationId,projectId:ie.projectId,period:W.searchParams.get("period")??"monthly",timezone:W.searchParams.get("timezone")??void 0})});if(W.pathname==="/api/spend/budgets"&&L.method==="GET")return M({ok:!0,budgets:D.listBudgets({organizationId:ie.organizationId,projectId:ie.projectId}).map((ke)=>({...ke,status:U.status(ke)}))});if(W.pathname==="/api/spend/budgets"&&L.method==="POST"){Ae();let ke=await se(L),ot=String(ke.scope??"project"),Oe=D.createBudget({organizationId:ie.organizationId,projectId:ot==="organization"?void 0:ie.projectId,environmentId:ot==="environment"?ie.environmentId:void 0,name:String(ke.name??"").trim(),period:ke.period??"monthly",timezone:ke.timezone?String(ke.timezone):void 0,softLimitCents:ke.softLimitCents==null?void 0:Math.round(Number(ke.softLimitCents)),hardLimitCents:ke.hardLimitCents==null?void 0:Math.round(Number(ke.hardLimitCents)),graceSeconds:ke.graceSeconds==null?void 0:Number(ke.graceSeconds),dryRun:ke.dryRun!==!1});return M({ok:!0,budget:Oe})}if(W.pathname==="/api/spend/budgets"&&L.method==="PATCH"){Ae();let ke=await se(L),ot=String(ke.id??""),Oe=D.getBudget(ot);if(!Oe||Oe.organizationId!==ie.organizationId)return M({ok:!1,error:"Budget was not found."},404);return M({ok:!0,budget:D.updateBudget(ot,{softLimitCents:ke.softLimitCents==null?Oe.softLimitCents:Math.round(Number(ke.softLimitCents)),hardLimitCents:ke.hardLimitCents==null?Oe.hardLimitCents:Math.round(Number(ke.hardLimitCents)),enabled:ke.enabled==null?Oe.enabled:ke.enabled===!0,dryRun:ke.dryRun==null?Oe.dryRun:ke.dryRun===!0},ke.expectedVersion==null?void 0:Number(ke.expectedVersion))})}if(W.pathname==="/api/spend/budgets"&&L.method==="DELETE"){Ae();let ke=await se(L),ot=String(ke.id??""),Oe=D.getBudget(ot);if(!Oe||Oe.organizationId!==ie.organizationId)return M({ok:!1,error:"Budget was not found."},404);let et=q.closeBudget(ot);return D.deleteBudget(ot),M({ok:!0,deleted:!0,lifted:et})}if(W.pathname==="/api/spend/check"&&L.method==="POST"){Ae();let ke=await se(L),{SpendRunner:ot}=await import("./spend/index.js"),Oe=new ot({controlPlane:E.store,store:D,alerts:ct});if(ke.apply!==!0){let Ne=D.budgetsForScope(ie.organizationId,ie.projectId,ie.environmentId);return M({ok:!0,applied:!1,preview:Ne.map((Ye)=>U.status(Ye))})}let et=await Oe.run({...ie,environmentKind:Q?.kind});return M({ok:!0,applied:!0,result:et})}if(W.pathname==="/api/spend/enforcement"&&L.method==="GET")return M({ok:!0,enforcement:q.listUnder({organizationId:ie.organizationId})});if(W.pathname==="/api/spend/release"&&L.method==="POST"){Ae();let ke=await se(L),ot=q.close(String(ke.budgetId??""),ke.action);return M({ok:ot,released:ot,note:ot?"The next spend cycle re-applies this if spend is still over the threshold.":"That action was not in force."})}if(W.pathname==="/api/spend/anomalies"&&L.method==="GET")return M({ok:!0,anomalies:D.listAnomalies({organizationId:ie.organizationId,projectId:ie.projectId,unacknowledgedOnly:W.searchParams.get("unacknowledged")==="true"})});if(W.pathname==="/api/spend/anomalies/acknowledge"&&L.method==="POST"){Ae();let ke=await se(L);return M({ok:!0,acknowledged:D.acknowledgeAnomaly(String(ke.id??""))})}return M({ok:!1,error:"Spend endpoint was not found."},404)}if(W.pathname.startsWith("/api/health/")||W.pathname.startsWith("/api/alerts")||W.pathname.startsWith("/api/notifications/")){let T=E.environments.get(De),D=E.store.listResources(E.project.id,T?.id),U=Se.role==="admin"||!!T&&Ya(Se,T.id,"runtime:read")?D:D.filter((Q)=>rn(Se,Q.id,"runtime:read")),q=(Q)=>!Q||U.some((ie)=>ie.id===Q),G=(Q)=>{if(!Q)return;let ie=D.find((Ae)=>Ae.id===Q||Ae.slug===Q);if(!ie)throw Error("Alert resource was not found.");if(!q(ie.id))throw Error("Alert resource is outside your authorized scope.");return ie.id},Z=Xe(Se).actor;if(W.pathname==="/api/health/checks"&&L.method==="GET")return M({ok:!0,checks:ct.listHealthChecks(E.project.id,T?.id).filter((Q)=>q(Q.resourceId)).map((Q)=>({...Q,results:ct.listHealthResults(Q.id,20)}))});if(W.pathname==="/api/health/checks"&&L.method==="POST"){let Q=await se(L),ie=String(Q.kind??"http");if(ie==="command"&&Se.role!=="admin")return M({ok:!1,error:"Command health checks require an administrator."},403);let Ae={method:String(Q.config?.method??"GET").toUpperCase().slice(0,10),path:Q.config?.path?String(Q.config.path).slice(0,500):void 0,port:Q.config?.port==null?void 0:Number(Q.config.port),command:Array.isArray(Q.config?.command)?Q.config.command.map(String).slice(0,20):void 0,expectedStatuses:Array.isArray(Q.config?.expectedStatuses)?Q.config.expectedStatuses.map(Number).filter(Number.isInteger).slice(0,20):void 0,expectedBody:Q.config?.expectedBody?String(Q.config.expectedBody).slice(0,500):void 0};return M({ok:!0,check:ct.createHealthCheck({projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource),name:String(Q.name??""),kind:ie,target:String(Q.target??""),config:Ae,intervalSeconds:Number(Q.intervalSeconds)||60,timeoutSeconds:Number(Q.timeoutSeconds)||10,failureThreshold:Number(Q.failureThreshold)||3,recoveryThreshold:Number(Q.recoveryThreshold)||2,regions:Array.isArray(Q.regions)?Q.regions.map(String):["local"],enabled:Q.enabled!==!1})},201)}if(W.pathname==="/api/health/checks"&&L.method==="PATCH"){let Q=await se(L),ie=ct.getHealthCheck(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Health check was not found."},404);return M({ok:!0,check:ct.setHealthCheckEnabled(ie.id,Q.enabled!==!1)})}if(W.pathname==="/api/health/checks/test"&&L.method==="POST"){let Q=await se(L),ie=ct.getHealthCheck(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Health check was not found."},404);return M({ok:!0,productionIncidentCreated:!1,result:await new Me(ct).probe(ie)})}if(W.pathname==="/api/health/checks/run"&&L.method==="POST"){let Q=await se(L),ie=ct.getHealthCheck(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Health check was not found."},404);let Ae=await new Me(ct).runAndEvaluate(ie),ke=[];for(let ot of Ae.evaluations.filter((Oe)=>Oe.notify&&Oe.alert)){let Oe=Nn.enqueue(E.organization.id,ot.alert,ot.transition);ke.push(...await Nn.deliverAll(Oe))}return M({ok:!0,...Ae,deliveries:ke})}if(W.pathname==="/api/alerts/rules"&&L.method==="GET")return M({ok:!0,rules:ct.listRules(E.project.id,T?.id).filter((Q)=>q(Q.resourceId))});if(W.pathname==="/api/alerts/rules"&&L.method==="POST"){let Q=await se(L),ie=Q.healthCheckId?ct.getHealthCheck(String(Q.healthCheckId)):void 0;if(Q.healthCheckId&&(!ie||!q(ie.resourceId)))return M({ok:!1,error:"Health check was not found."},404);return M({ok:!0,rule:ct.createRule({projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource)??ie?.resourceId,healthCheckId:ie?.id,name:String(Q.name??""),signal:String(Q.signal??(ie?"health":"")),operator:String(Q.operator??(ie?"unhealthy":"gt")),threshold:Q.threshold==null?void 0:Number(Q.threshold),recoveryThreshold:Q.recoveryThreshold==null?void 0:Number(Q.recoveryThreshold),windowMs:Number(Q.windowMs)||300000,consecutive:Number(Q.consecutive)||ie?.failureThreshold||3,recoveryConsecutive:Number(Q.recoveryConsecutive)||ie?.recoveryThreshold||2,noDataPolicy:["ignore","pending","firing"].includes(String(Q.noDataPolicy))?Q.noDataPolicy:"pending",severity:["info","warning","critical"].includes(String(Q.severity))?Q.severity:"warning",groupBy:Array.isArray(Q.groupBy)?Q.groupBy.map(String):[],labels:Q.labels&&typeof Q.labels==="object"?Q.labels:{},enabled:Q.enabled!==!1})},201)}if(W.pathname==="/api/alerts/rules"&&L.method==="PATCH"){let Q=await se(L),ie=ct.getRule(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Alert rule was not found."},404);return M({ok:!0,rule:ct.setRuleEnabled(ie.id,Q.enabled!==!1)})}if(W.pathname==="/api/alerts/evaluate"&&L.method==="POST")return M({ok:!0,...await af(T?.id)});if(W.pathname==="/api/alerts"&&L.method==="GET")return M({ok:!0,alerts:ct.listAlerts(E.project.id,{environmentId:T?.id,states:W.searchParams.getAll("state").length?W.searchParams.getAll("state"):void 0,limit:Number(W.searchParams.get("limit"))||200}).filter((Q)=>q(Q.resourceId)).map((Q)=>({...Q,deliveries:ct.listDeliveries({alertId:Q.id,limit:50})}))});if(W.pathname==="/api/alerts/action"&&L.method==="POST"){let Q=await se(L),ie=ct.getAlert(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Alert was not found."},404);let Ae=String(Q.action??"");if(Ae==="acknowledge")return M({ok:!0,alert:ct.acknowledge(ie.id,Z?.id??"")});if(Ae==="assign")return M({ok:!0,alert:ct.assign(ie.id,Q.ownerActorId==="me"?Z?.id:Q.ownerActorId?String(Q.ownerActorId):void 0,Z?.id)});if(Ae==="silence"){if(Se.role!=="admin")return M({ok:!1,error:"Silencing production alerts requires an administrator."},403);let ke=gr.resolveSession(L);if(Be&&(!ke||!Fe.isRecentlyAuthenticated(ke)))return M({ok:!1,error:"Recent authentication is required to silence alerts.",stepUpRequired:!0},401);return M({ok:!0,alert:ct.silenceAlert(ie.id,String(Q.until??""),Z?.id)})}return M({ok:!1,error:"Action must be acknowledge, assign, or silence."},422)}if(W.pathname==="/api/alerts/silences"&&L.method==="POST"){let Q=await se(L);return M({ok:!0,id:ct.createSilence({projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource),matcher:Q.matcher,reason:String(Q.reason??""),startsAt:String(Q.startsAt??new Date().toISOString()),endsAt:String(Q.endsAt??""),timezone:String(Q.timezone??"UTC"),actorId:Z?.id})},201)}if(W.pathname==="/api/notifications/channels"&&L.method==="GET")return M({ok:!0,channels:ct.listChannels(E.organization.id)});if(W.pathname==="/api/notifications/channels"&&L.method==="POST"){let Q=await se(L),ie=String(Q.kind??""),Ae=ie==="email"?{to:Q.config?.to,from:Q.config?.from}:ie==="telegram"?{chatId:String(Q.config?.chatId??"")}:{};return M({ok:!0,channel:ct.createChannel({organizationId:E.organization.id,name:String(Q.name??""),kind:ie,config:Ae,credential:Q.credential?String(Q.credential):void 0,actorId:Z?.id})},201)}if(W.pathname==="/api/notifications/channels"&&L.method==="PATCH"){let Q=await se(L),ie=String(Q.id??"");if(Q.credential)return M({ok:!0,channel:ct.rotateChannel(ie,String(Q.credential))});let Ae=String(Q.status??"paused");if(!["active","paused","disabled"].includes(Ae))return M({ok:!1,error:"Channel status must be active, paused, or disabled."},422);return M({ok:!0,channel:ct.setChannelStatus(ie,Ae)})}if(W.pathname==="/api/notifications/channels/test"&&L.method==="POST"){let Q=await se(L);return M({ok:!0,productionIncidentCreated:!1,result:await Nn.testChannel(String(Q.id??""))})}if(W.pathname==="/api/notifications/routes"&&L.method==="GET")return M({ok:!0,routes:ct.listRoutes(E.organization.id)});if(W.pathname==="/api/notifications/routes"&&L.method==="POST"){let Q=await se(L),ie=Array.isArray(Q.channelIds)?Q.channelIds.map(String):[];if(ie.some((Ae)=>ct.getChannel(Ae)?.organizationId!==E.organization.id))return M({ok:!1,error:"Route contains an unavailable channel."},422);return M({ok:!0,route:ct.createRoute({organizationId:E.organization.id,name:String(Q.name??""),priority:Number(Q.priority)||0,matcher:Q.matcher&&typeof Q.matcher==="object"?Q.matcher:{},channelIds:ie,quietHours:Q.quietHours,groupWaitSeconds:Number(Q.groupWaitSeconds)||30,reminderSeconds:Q.reminderSeconds==null?void 0:Number(Q.reminderSeconds),escalation:Array.isArray(Q.escalation)?Q.escalation:[],template:Q.template?String(Q.template):void 0,rateLimitPerMinute:Number(Q.rateLimitPerMinute)||60,enabled:Q.enabled!==!1})},201)}if(W.pathname==="/api/notifications/routes"&&L.method==="PATCH"){let Q=await se(L),ie=ct.getRoute(String(Q.id??""));if(!ie||ie.organizationId!==E.organization.id)return M({ok:!1,error:"Notification route was not found."},404);return M({ok:!0,route:ct.setRouteEnabled(ie.id,Q.enabled!==!1)})}if(W.pathname==="/api/notifications/routes/preview"&&L.method==="POST"){let Q=await se(L),Ae=(Q.alertId?ct.getAlert(String(Q.alertId)):void 0)??{id:"preview",ruleId:"preview",projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource),dedupKey:"preview",groupKey:String(Q.groupKey??"default"),state:"firing",severity:["info","warning","critical"].includes(String(Q.severity))?Q.severity:"warning",title:String(Q.title??"Rule preview"),evidence:{},failureCount:1,recoveryCount:0,occurrenceCount:1,firstSeenAt:new Date().toISOString(),lastSeenAt:new Date().toISOString(),firingAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return M({ok:!0,productionIncidentCreated:!1,matches:Nn.preview(E.organization.id,Ae,String(Q.eventType??"firing")).map((ke)=>({route:ke.route,channels:ke.channels,quiet:ke.quiet}))})}if(W.pathname==="/api/notifications/deliveries"&&L.method==="GET")return M({ok:!0,deliveries:ct.listDeliveries({alertId:W.searchParams.get("alertId")??void 0,states:W.searchParams.getAll("state"),limit:Number(W.searchParams.get("limit"))||200})});if(W.pathname==="/api/notifications/deliveries/retry"&&L.method==="POST"){let Q=await se(L),ie=ct.getDelivery(String(Q.id??""));if(!ie)return M({ok:!1,error:"Delivery was not found."},404);return ct.updateDelivery(ie.id,{state:"retrying",attempt:Math.max(0,ie.attempt-1),nextAttemptAt:new Date().toISOString()}),M({ok:!0,delivery:await Nn.deliver(ie.id)})}}if(W.pathname.startsWith("/api/jobs")||W.pathname.startsWith("/api/workers")){let T=E.environments.get(De),D=E.store.listResources(E.project.id,T?.id),q=Se.role==="admin"||!!T&&Ya(Se,T.id,"automation:read")?D:D.filter((Ne)=>rn(Se,Ne.id,"automation:read")),G=(Ne)=>!Ne||q.some((Ye)=>Ye.id===Ne),Z=Xe(Se).actor,Q=H.get(De)??z,ie=Ou(h,Q),Ae=ie.filter((Ne)=>!Ne.danger&&["scheduler","backup","worker"].includes(Ne.group)),ke=O(h),ot=()=>{let Ne=gr.resolveSession(L);return!Be||!!Ne&&Fe.isRecentlyAuthenticated(Ne)},Oe=(Ne)=>{if(!Ne||typeof Ne!=="object"||Array.isArray(Ne))return{};let Ye=Object.entries(Ne).slice(0,50);if(Ye.some(([,yt])=>typeof yt!=="string"||!/^(?:secret|ssm|arn|env):\/\//.test(yt)))throw Error("Job payload values must be secret or environment references, never inline values.");return Object.fromEntries(Ye)},et=(Ne,Ye,yt)=>E.store.appendEvent({organizationId:E.organization.id,projectId:E.project.id,resourceId:yt,actorId:Z?.id,type:`job.${Ne}`,payload:Ye});if(W.pathname==="/api/jobs/preview"&&L.method==="POST"){let Ne=await se(L);try{return M({ok:!0,productionExecutionCreated:!1,preview:ht(String(Ne.expression??""),String(Ne.timezone??"UTC"),new Date(Ne.from?String(Ne.from):Date.now()),Number(Ne.count)||5)})}catch(Ye){return M({ok:!1,error:Ye instanceof Error?Ye.message:"Schedule preview could not be generated.",productionExecutionCreated:!1},422)}}if(W.pathname==="/api/jobs"&&L.method==="GET")return M({ok:!0,jobs:Zr.list(E.project.id,{environmentId:T?.id}).filter((Ne)=>G(Ne.resourceId)).map((Ne)=>({...Ne,preview:ht(Ne.normalizedExpression,Ne.timezone,new Date,5),capability:Hr(Ne),lastExecution:Zr.listExecutions(Ne.id,1)[0]}))});if(W.pathname==="/api/jobs"&&L.method==="POST"){let Ne=await se(L),Ye=String(Ne.provider??(ke==="serverless"?"eventbridge":"server")),yt=ke==="serverless"?"eventbridge":"server";if(Ye!==yt)return M({ok:!1,error:`${ke} environments accept ${yt} schedules through this adapter.`},422);let Et=Ne.operationId?String(Ne.operationId):void 0;if(Ye==="server"&&(!Et||!Ae.some((Ar)=>Ar.id===Et)))return M({ok:!1,error:"Server jobs require an allowlisted operation target."},422);let Qt=Hr({provider:Ye,expression:String(Ne.expression??""),flexibleMinutes:Number(Ne.flexibleMinutes)||0,missedRunPolicy:Ne.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String(Ne.overlapPolicy))?Ne.overlapPolicy:"forbid"});if(!Qt.supported)return M({ok:!1,error:Qt.notes.join(" ")},422);let Tn=Ne.resourceId?D.find((Ar)=>Ar.id===Ne.resourceId||Ar.slug===Ne.resourceId):void 0;if(Ne.resourceId&&(!Tn||!G(Tn.id)))return M({ok:!1,error:"Job resource was not found."},404);try{let Ar=Ye==="server"?{kind:"dashboard_operation",operationId:Et}:{kind:"serverless_scheduler",action:"run"},io=Zr.create({organizationId:E.organization.id,projectId:E.project.id,environmentId:T?.id,resourceId:Tn?.id,name:String(Ne.name??""),provider:Ye,expression:String(Ne.expression??""),timezone:String(Ne.timezone??"UTC"),startsAt:Ne.startsAt?String(Ne.startsAt):void 0,endsAt:Ne.endsAt?String(Ne.endsAt):void 0,flexibleMinutes:Number(Ne.flexibleMinutes)||0,target:Ar,payloadRefs:Oe(Ne.payloadRefs),missedRunPolicy:Ne.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String(Ne.overlapPolicy))?Ne.overlapPolicy:"forbid",retryPolicy:{maxAttempts:Number(Ne.maxAttempts)||3,backoffSeconds:Number(Ne.backoffSeconds)||30,deadLetterRef:Ne.deadLetterRef?String(Ne.deadLetterRef):void 0},timeoutSeconds:Number(Ne.timeoutSeconds)||900,enabled:Ne.enabled!==!1,origin:"managed",ownerActorId:Z?.id,observedState:{},reconciliationStatus:"pending"});return et("created",{jobId:io.id,provider:io.provider,expression:io.normalizedExpression},io.resourceId),M({ok:!0,job:io,capability:Qt},201)}catch(Ar){return M({ok:!1,error:Ar instanceof Error?Ar.message:"Scheduled job could not be created."},422)}}if(W.pathname==="/api/jobs"&&L.method==="PATCH"){let Ne=await se(L),Ye=Zr.get(String(Ne.id??""));if(!Ye||!G(Ye.resourceId))return M({ok:!1,error:"Scheduled job was not found."},404);if(Ye.origin==="config")return M({ok:!1,error:"Config-defined schedules must be edited in cloud.config.ts and reconciled."},409);let yt=Ne.missedRunPolicy==null?void 0:String(Ne.missedRunPolicy),Et=Ne.overlapPolicy==null?void 0:String(Ne.overlapPolicy);if(yt&&!["skip","catch_up"].includes(yt))return M({ok:!1,error:"Missed-run policy must be skip or catch_up."},422);if(Et&&!["allow","forbid","replace"].includes(Et))return M({ok:!1,error:"Overlap policy must be allow, forbid, or replace."},422);try{let Qt=Zr.updateSchedule(Ye.id,{expression:Ne.expression?String(Ne.expression):void 0,timezone:Ne.timezone?String(Ne.timezone):void 0,missedRunPolicy:yt,overlapPolicy:Et,timeoutSeconds:Ne.timeoutSeconds==null?void 0:Number(Ne.timeoutSeconds)});return et("updated",{jobId:Qt.id,expression:Qt.normalizedExpression,version:Qt.version},Qt.resourceId),M({ok:!0,job:Qt})}catch(Qt){return M({ok:!1,error:Qt instanceof Error?Qt.message:"Scheduled job could not be updated."},422)}}if(W.pathname==="/api/jobs/action"&&L.method==="POST"){let Ne=await se(L),Ye=Zr.get(String(Ne.id??""));if(!Ye||!G(Ye.resourceId))return M({ok:!1,error:"Scheduled job was not found."},404);let yt=String(Ne.action??"");if(yt==="run"){let Et=sf.enqueue(Ye,{trigger:"manual",actorId:Z?.id});return et("run_queued",{jobId:Ye.id,executionId:Et.id},Ye.resourceId),M({ok:!0,execution:Et},202)}if(["disable","delete"].includes(yt)&&T?.kind==="production"){if(String(Ne.confirm??"")!==yt)return M({ok:!1,error:`Type "${yt}" to confirm this production change.`},409);if(!ot())return M({ok:!1,error:"Recent authentication is required for this production change.",stepUpRequired:!0},401)}if(yt==="enable"||yt==="disable"){let Et=Zr.setEnabled(Ye.id,yt==="enable");return et(yt==="enable"?"enabled":"disabled",{jobId:Ye.id},Ye.resourceId),M({ok:!0,job:Et})}if(yt==="delete")try{return Zr.remove(Ye.id),et("deleted",{jobId:Ye.id,name:Ye.name},Ye.resourceId),M({ok:!0,deleted:Ye.id})}catch(Et){return M({ok:!1,error:Et instanceof Error?Et.message:"Scheduled job could not be deleted."},409)}return M({ok:!1,error:"Action must be run, enable, disable, or delete."},422)}if(W.pathname==="/api/jobs/history"&&L.method==="GET"){let Ne=Zr.get(String(W.searchParams.get("jobId")??""));if(!Ne||!G(Ne.resourceId))return M({ok:!1,error:"Scheduled job was not found."},404);return M({ok:!0,executions:Zr.listExecutions(Ne.id,Number(W.searchParams.get("limit"))||100).map((Ye)=>({...Ye,logs:Ye.operationId?nr.logs(Ye.operationId,{limit:500}):[]}))})}if(W.pathname==="/api/jobs/reconcile"&&L.method==="POST"){if(!T)return M({ok:!1,error:"Environment was not found."},404);let Ne=Po(Zr,h,{organization:E.organization,project:E.project,environment:T,resources:D});return et("reconciled",Ne),M({ok:!0,reconciliation:Ne})}if(W.pathname==="/api/workers"&&L.method==="GET"){let Ne=Array.isArray(Q.workersDetail??Q.workers)?Q.workersDetail??Q.workers:[];return M({ok:!0,workers:Zr.listWorkers(E.project.id,T?.id).filter((Ye)=>G(Ye.resourceId)).map((Ye)=>{let yt=Ne.find((Et)=>Et.name===Ye.name||Et.site===Ye.target.site);return yt?{...Ye,observedState:{...Ye.observedState,status:yt.status??"configured",currentJob:yt.currentJob??null,failures:Number(yt.failed??yt.failures)||0,processed:Number(yt.processed)||0}}:Ye})})}if(W.pathname==="/api/workers/action"&&L.method==="POST"){let Ne=await se(L),Ye=Zr.getWorker(String(Ne.id??""));if(!Ye||!G(Ye.resourceId))return M({ok:!1,error:"Worker was not found."},404);let yt=String(Ne.action??"");if(yt==="restart"){if(String(Ne.confirm??"")!==Ye.name)return M({ok:!1,error:`Type "${Ye.name}" to restart this worker.`},409);let Et=ie.find((Ar)=>Ar.id===Ye.target.operationId);if(!Et)return M({ok:!1,error:"The allowlisted worker restart operation is unavailable."},409);let Qt=await $u(h,De,Et),Tn=Zr.reconcileWorker(Ye.id,Qt.ok?"in_sync":"unavailable",{...Ye.observedState,lastRestartAt:new Date().toISOString(),command:Qt.command??null,error:Qt.error??Qt.stderr??null});return et("worker_restarted",{workerId:Ye.id,ok:Qt.ok},Ye.resourceId),M({...Qt,worker:Tn},Qt.ok?200:409)}if(yt==="scale")return M({ok:!1,error:Ye.provider==="systemd"?"Systemd worker scale is config-managed; edit the worker definition and reconcile.":"This provider does not expose safe worker scaling through the current adapter."},422);return M({ok:!1,error:"Action must be restart or scale."},422)}}if(W.pathname.startsWith("/api/telemetry/")){let T=E.environments.get(De),D=new at(E.store),U=E.store.listResources(E.project.id,T?.id),q=["/api/telemetry/query","/api/telemetry/tail","/api/telemetry/export","/api/telemetry/saved-queries","/api/telemetry/refresh"].includes(W.pathname)?"runtime:logs":"runtime:read",G=Se.role==="admin"||!!T&&Ya(Se,T.id,q),Z=G?U:U.filter((Oe)=>rn(Se,Oe.id,q)),Q=(Oe)=>vS(Z,G,Oe),ie=(Oe)=>{let et=new Date,Ne={"1h":3600000,"6h":21600000,"24h":86400000,"7d":604800000,"30d":2592000000},Ye=String(Oe.to??et.toISOString()),yt=String(Oe.from??new Date(new Date(Ye).getTime()-(Ne[String(Oe.range??"1h")]??Ne["1h"])).toISOString()),Et=(Tn)=>{let Ar=(Array.isArray(Tn)?Tn:String(Tn??"").split(",")).map(String).filter(Boolean);return Ar.length?Ar:void 0},Qt=Et(Oe.kinds)?.filter((Tn)=>["metric","log","trace","request","event"].includes(Tn));return{projectId:E.project.id,environmentId:T?.id,resourceIds:Q(Oe.resources),kinds:Qt,names:Et(Oe.names),sources:Et(Oe.sources),levels:Et(Oe.levels),from:yt,to:Ye,text:String(Oe.text??"")||void 0,traceId:String(Oe.traceId??"")||void 0,requestId:String(Oe.requestId??"")||void 0,deploymentId:String(Oe.deploymentId??"")||void 0,releaseId:String(Oe.releaseId??"")||void 0,workloadId:String(Oe.workloadId??"")||void 0,cursor:String(Oe.cursor??"")||void 0,limit:Number(Oe.limit)||void 0}},Ae=Object.fromEntries(W.searchParams.entries()),ke=(Oe=!1)=>Fg({controlPlane:E.store,projectId:E.project.id,environmentId:T?.id,config:h,environment:De,force:Oe,lightweight:!Oe}),ot=()=>{let Oe=E.store.getSetting(`telemetry.collection:${E.project.id}:${T?.id??"all"}`)??{};return{generatedAt:String(Oe.generatedAt??new Date().toISOString()),cached:!0,statuses:Array.isArray(Oe.statuses)?Oe.statuses:[],errors:Array.isArray(Oe.errors)?Oe.errors:[],policy:Oe.policy??$t(E.store,E.project.id)}};if(W.pathname==="/api/telemetry/status"&&L.method==="GET"){ke(!1);let Oe=ot(),et=G?Oe.statuses:D.status(E.project.id,T?.id,Oe.policy.rawDays,Oe.policy.samplingRate,Z.map((Ye)=>Ye.id)),Ne=et.reduce((Ye,yt)=>Ye+yt.estimatedDailyBytes*30,0);return M({ok:!0,generatedAt:Oe.generatedAt,cached:Oe.cached,sources:et,errors:G?Oe.errors:[],policy:Oe.policy,retention:{rawDays:Oe.policy.rawDays,downsampleAfterDays:Oe.policy.downsampleAfterDays,downsampleBucketMs:Oe.policy.downsampleBucketMs,maxRecords:Oe.policy.maxRecords},estimatedMonthlyBytes:Ne,estimatedMonthlyCostUsd:Gc(Ne,Oe.policy),costEstimateConfigured:Oe.policy.estimatedStorageUsdPerGbMonth>0})}if(W.pathname==="/api/telemetry/settings"&&L.method==="GET")return M({ok:!0,policy:$t(E.store,E.project.id)});if(W.pathname==="/api/telemetry/settings"&&L.method==="PATCH"){let Oe=Hc(E.store,E.project.id,await se(L));return ES(E.project.id),M({ok:!0,policy:Oe})}if(W.pathname==="/api/telemetry/query"&&L.method==="GET"){ke(!1);let Oe=ot();return M({ok:!0,collection:{generatedAt:Oe.generatedAt,cached:Oe.cached},...D.query(ie(Ae))})}if(W.pathname==="/api/telemetry/tail"&&L.method==="GET"){ke(!1);let Oe=new TextEncoder,et=new Date,Ne=ie({...Ae,kinds:Ae.kinds||"log,request,event,trace",from:Ae.from||new Date(et.getTime()-120000).toISOString(),to:et.toISOString(),limit:Math.min(1000,Number(Ae.limit)||200),cursor:void 0}),Ye=L.headers.get("last-event-id")||String(Ae.cursor??"")||void 0,yt,Et=!1,Qt=!1,Tn=new ReadableStream({start(Ar){let io=()=>{if(Et)return;if(Et=!0,yt)clearInterval(yt);L.signal.removeEventListener("abort",io);try{Ar.close()}catch{}},bf=async()=>{if(Et||Qt)return;Qt=!0;try{let Ss=D.tail({...Ne,to:new Date(Date.now()+1000).toISOString()},Ye);for(let Sf of Ss.records)Ye=ci(Sf)??Ye,Ar.enqueue(Oe.encode(`id: ${Ye??""}
696
+ This replacement link expires ${U.invitation.expiresAt} and can be used once.`});return M({invitation:U.invitation,token:U.token,acceptUrl:q,delivered:G})}catch(U){return M({ok:!1,error:U instanceof Error?U.message:"Invitation could not be resent."},409)}}if(W.pathname==="/api/organization/memberships"&&L.method==="PATCH"){let T=await se(L),D=E.store.getMembership(String(T.id??"")),U=Mu(T.roleTemplate),q=Pc(T);if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Membership was not found."},404);if(!U||!q)return M({ok:!1,error:"Choose a valid role template and resource scope."},422);let G=Ze(Se);if((D.roleTemplate==="owner"||U==="owner")&&(!Yn(String(T.password??""),Se.passwordHash)||G.membership?.roleTemplate!=="owner"))return M({ok:!1,error:"Ownership changes require an owner to re-enter their password."},401);let Q=E.store.resolveAuthorizationTarget(E.organization.id,q)??E.store.resolveAuthorizationTarget(E.organization.id,{type:"project",id:E.project.id}),ie=E.store.listGrants(D.id),Ae=Bt({membership:D,grants:ie,target:Q}),ke={...D,roleTemplate:U,scope:q},ot=Bt({membership:ke,grants:ie,target:Q}),Oe={gained:ot.filter((et)=>!Ae.includes(et)),lost:Ae.filter((et)=>!ot.includes(et))};if(T.preview===!0)return M({membership:D,proposed:{roleTemplate:U,scope:q},accessDiff:Oe});if(String(T.confirm??"")!==D.id)return M({ok:!1,error:`Confirm this change with membership ID ${D.id}.`,accessDiff:Oe},409);try{return M({membership:E.store.updateMembership({id:D.id,roleTemplate:U,scope:q,actorId:G.actor?.id}),accessDiff:Oe})}catch(et){return M({ok:!1,error:et instanceof Error?et.message:"Membership could not be updated."},409)}}if(W.pathname==="/api/organization/memberships"&&L.method==="DELETE"){let T=await se(L),D=E.store.getMembership(String(T.id??""));if(!D||D.organizationId!==E.organization.id)return M({ok:!1,error:"Membership was not found."},404);if(String(T.confirm??"")!==D.id)return M({ok:!1,error:`Confirm removal with membership ID ${D.id}.`},409);let U=Ze(Se);if(D.roleTemplate==="owner"&&(U.membership?.roleTemplate!=="owner"||!Yn(String(T.password??""),Se.passwordHash)))return M({ok:!1,error:"Removing an owner requires an owner to re-enter their current password."},401);try{return M({membership:E.store.revokeMembership(D.id,U.actor?.id)})}catch(q){return M({ok:!1,error:q instanceof Error?q.message:"Membership could not be removed."},409)}}if(W.pathname==="/api/organization/grants"&&L.method==="POST"){let T=await se(L),D=String(T.capability??""),U=T.effect==="deny"?"deny":T.effect==="allow"?"allow":void 0,q=Pc(T),G=Ze(Se);if(!U||!q||!ae.includes(D))return M({ok:!1,error:"Choose a valid capability, effect, and resource scope."},422);try{return M({grant:E.store.upsertGrant({organizationId:E.organization.id,membershipId:String(T.membershipId??""),effect:U,capability:D,scope:q,actorId:G.actor?.id})},201)}catch(Z){return M({ok:!1,error:Z instanceof Error?Z.message:"Grant could not be created."},422)}}if(W.pathname==="/api/organization/grants"&&L.method==="DELETE"){let T=await se(L),D=Ze(Se),U=E.store.getGrant(String(T.id??""));if(!U||U.organizationId!==E.organization.id)return M({ok:!1,error:"Grant was not found."},404);return M({ok:E.store.removeGrant(U.id,D.actor?.id)})}if(W.pathname==="/api/tags"&&L.method==="GET")return M({tags:E.store.listTags(E.project.id),assignments:E.store.listResourceTags(E.project.id)});if(W.pathname==="/api/tags"&&L.method==="POST"){let T=await se(L),D=E.store.upsertTag(E.project.id,String(T.name??""),String(T.color??"#5a8be0"));if(T.resourceId)E.store.assignTag(String(T.resourceId),D.id);return M({tag:D},201)}if(W.pathname==="/api/tags"&&L.method==="DELETE"){let T=await se(L);return E.store.removeTag(String(T.resourceId??""),String(T.tagId??"")),M({ok:!0})}if(W.pathname==="/"&&!OS(W.pathname,jn))return new Response(null,{status:302,headers:{location:`/server/sites?env=${encodeURIComponent(De)}`}});if(W.pathname==="/"&&ur?.mode==="serverless")return new Response(null,{status:302,headers:{location:`/serverless?env=${encodeURIComponent(De)}`}});let jc=Pl(W.pathname);if(jc)return new Response(null,{status:308,headers:{location:`${jc}?env=${encodeURIComponent(De)}`}});if(W.pathname==="/api/env"&&L.method==="POST"){let T=await se(L),D=String(T.env??"");if(!x.includes(D))return M({ok:!1,error:`Unknown environment '${D}'.`,environments:x},404);return M({ok:!0,environment:D,environments:x,href:`?env=${encodeURIComponent(D)}`})}if(W.pathname==="/api/config"){let T={...Fi(h),environment:De,environments:x};return M(Kb(T,jn))}if(W.pathname==="/api/ssh-keys"&&L.method==="GET")return M({configPath:F,keys:gs(Ga(h))});if(W.pathname==="/api/ssh-keys"&&L.method==="POST"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=await pi(F,"utf8"),U=Ga(h),q=Yv({configText:D,name:String(T.name??""),publicKey:String(T.publicKey??""),existingKeys:U});return await Ws(F,q),_S(h,[...U,{name:String(T.name??"").trim(),publicKey:String(T.publicKey??"").trim().replace(/\s+/g," ")}]),M({ok:!0,configPath:F,keys:gs(Ga(h))})}if(W.pathname==="/api/ssh-keys"&&L.method==="DELETE"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??W.searchParams.get("name")??""),U=await pi(F,"utf8"),q=Ga(h),G=Zv({configText:U,name:D,existingKeys:q});return await Ws(F,G),_S(h,q.filter((Z)=>Z.name!==D.trim())),M({ok:!0,configPath:F,keys:gs(Ga(h))})}if(W.pathname==="/api/firewall"&&L.method==="GET")return M({configPath:F,alwaysOpen:[22,80,443],ports:Ug(h)});if(W.pathname==="/api/firewall"&&L.method==="POST"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=Number(T.port);if(!Rc(D))return M({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let U=Ug(h),q=await pi(F,"utf8");try{await Ws(F,tS(q,D,U))}catch(Q){return M({ok:!1,error:Q?.message??String(Q)},422)}let G=Vs([...U,D]);TS(h,G);let Z=T.apply===!1?null:await kc(h,De,`ufw allow ${D}/tcp`).catch((Q)=>({ok:!1,error:String(Q?.message??Q)}));return M({ok:!0,configPath:F,ports:G,apply:Z})}if(W.pathname==="/api/firewall"&&L.method==="DELETE"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=Number(T.port??W.searchParams.get("port"));if(!Rc(D))return M({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let U=Ug(h),q=await pi(F,"utf8");await Ws(F,rS(q,D,U));let G=Vs(U.filter((Q)=>Q!==D));TS(h,G);let Z=T.apply===!1?null:await kc(h,De,`ufw delete allow ${D}/tcp`).catch((Q)=>({ok:!1,error:String(Q?.message??Q)}));return M({ok:!0,configPath:F,ports:G,apply:Z})}if(W.pathname==="/api/sites"&&L.method==="POST"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??"").trim(),U=String(T.root??"").trim();if(!D||!U)return M({ok:!1,error:"Site name and root are required."},422);let q={deploy:T.deploy==="bucket"?"bucket":"server",root:U,path:String(T.path??"").trim()||void 0,domain:String(T.domain??"").trim()||void 0,build:String(T.build??"").trim()||void 0,start:String(T.start??"").trim()||void 0,port:T.port?Number(T.port):void 0,type:String(T.type??"").trim()||void 0};if(q.port!==void 0&&(!Number.isInteger(q.port)||q.port<1||q.port>65535))return M({ok:!1,error:"Port must be a number between 1 and 65535."},422);let G=await pi(F,"utf8"),Z=jr({configText:G,name:D,root:q.root,domain:q.domain,path:q.path,deploy:q.deploy,build:q.build,start:q.start,port:q.port,type:q.type});return await Ws(F,Z),H_(h,D,Object.fromEntries(Object.entries(q).filter(([,Q])=>Q!==void 0))),ur=await Ks(h,De),H.set(De,ur),M({ok:!0,configPath:F,site:D,data:ur})}if(W.pathname==="/api/sites"&&L.method==="DELETE"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??W.searchParams.get("name")??"").trim();if(!D||!h.sites?.[D])return M({ok:!1,error:`Site '${D}' was not found.`},404);let U=await pi(F,"utf8");return await Ws(F,zr({configText:U,name:D})),delete h.sites[D],ur=await Ks(h,De),H.set(De,ur),M({ok:!0,configPath:F,site:D,data:ur})}if(W.pathname==="/api/sites"&&L.method==="PATCH"){if(!F)return M({ok:!1,error:"No cloud config file was found in this checkout."},404);let T=await se(L),D=String(T.name??"").trim(),U=h.sites?.[D];if(!D||!U)return M({ok:!1,error:`Site '${D}' was not found.`},404);if(jn.role==="member"){let Z=Yb(T);if(!Z.ok)return M({ok:!1,error:Z.error},403);let Q=Zb({siteName:D,body:T,sites:h.sites??{},ownSites:Object.keys(jn.sites)});if(!Q.ok)return M({ok:!1,error:Q.error},409)}if(T.port!==void 0&&T.port!==null&&T.port!==""&&(!Number.isInteger(Number(T.port))||Number(T.port)<1||Number(T.port)>65535))return M({ok:!1,error:"Port must be a number between 1 and 65535."},422);if(typeof T.domain==="string"&&T.domain.trim()&&!Xo(T.domain.trim()))return M({ok:!1,error:`Domain '${T.domain.trim()}' is not a valid hostname.`},422);let q=await pi(F,"utf8"),G=(Z,Q)=>{q=_i({configText:q,siteName:D,key:Z,valueText:Q})};if(T.ssl!==void 0)G("ssl",Cl(T.ssl)),U.ssl=T.ssl;if(T.env!==void 0&&T.env&&typeof T.env==="object")G("env",El(T.env)),U.env=T.env;if(T.aliases!==void 0&&Array.isArray(T.aliases)){let Z=T.aliases.map((Q)=>String(Q));G("aliases",vl(Z)),U.aliases=Z.map((Q)=>Q.trim().toLowerCase()).filter(Boolean)}if(T.redirects!==void 0&&T.redirects&&typeof T.redirects==="object")G("redirects",Tl(T.redirects)),U.redirects=T.redirects;for(let Z of["domain","path","build","start","type","root","php"])if(typeof T[Z]==="string"&&T[Z].trim())G(Z,bl(String(T[Z]).trim())),U[Z]=String(T[Z]).trim();if(T.port!==void 0&&T.port!==null&&T.port!=="")G("port",String(Number(T.port))),U.port=Number(T.port);return await Ws(F,q),ur=await Ks(h,De),H.set(De,ur),M({ok:!0,configPath:F,site:D,data:ur})}if(W.pathname==="/api/sites/deploy"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim();if(!D||!h.sites?.[D])return M({ok:!1,error:`Site '${D}' was not found.`},404);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to deploy this site.`},409);let U=ee(E,String(De));await new ut(bt).run(new Qr,{...U,artifactRoot:t}),Di(bt,U,ur??{});let q=Pi(bt,{scope:U,desiredConfigHash:E.project.desiredConfigHash});if(q.decision.outcome==="block")return M({ok:!1,error:`Deployment blocked by security policy: ${q.decision.explanation}`,securityReview:q},409);let G={id:`deploy:${D}`,label:`Deploy ${D}`,description:`Deploy the ${D} site for ${De}.`,command:["deploy","--env",De,"--site",D,"--yes"],mutates:!0},Z=await we({controlPlane:E,environment:De,actor:Se,kind:"dashboard.site.deploy",resourceSlug:D,input:{site:D},execute:()=>Hg(G,{cwd:t,cliEntry:m})});return M({...Z.result,controlPlaneOperation:Z.operation,securityReview:q})}if(W.pathname==="/api/actions")return M(Yr(De));if(W.pathname==="/api/server/operations")return M(Ou(h,ur));if(W.pathname==="/api/runtime/workloads"&&L.method==="GET"){let T=await te(h,De);return M(T)}if(W.pathname==="/api/runtime/logs"&&L.method==="GET"){let T=String(W.searchParams.get("workload")??"");if(!T)return M({ok:!1,error:"A workload query parameter is required."},422);let D=Math.min(1000,Math.max(1,Number(W.searchParams.get("limit"))||200));try{return M(await new le(h,De).logs(T,{limit:D}))}catch(U){return M({ok:!1,error:String(U?.message??U)},404)}}if(W.pathname==="/api/runtime/log-sessions"&&L.method==="POST"){let T=await se(L),D=String(T.workloadId??"");if(!D)return M({ok:!1,error:"A workloadId is required."},422);let U=await te(h,De),q=U.workloads.find((Q)=>Q.id===D);if(!q)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);if(!q.capabilities.logs.supported)return M({ok:!1,error:q.capabilities.logs.reason??"Logs are unsupported for this workload."},409);let G=new le(h,De,{inventory:async()=>U}),Z=Rr.create("logs",D);return(async()=>{let Q=new Date(Date.now()-Math.min(3600000,Math.max(1000,Number(T.sinceMs)||60000)));try{for(let ie=0;ie<200&&!Rr.signal(Z.id)?.aborted;ie++){let Ae=await G.logs(D,{limit:Math.min(500,Math.max(1,Number(T.limit)||200)),since:Q});for(let ke of Ae.lines)if(Rr.append(Z.id,`${ke.timestamp?`${ke.timestamp} `:""}${ke.message}
697
+ `),ke.timestamp)Q=new Date(Math.max(Q.getTime(),new Date(ke.timestamp).getTime()+1));await Bun.sleep(3000)}if(!Rr.signal(Z.id)?.aborted)Rr.close(Z.id,"complete")}catch(ie){Rr.append(Z.id,ie instanceof Error?ie.message:String(ie),"stderr"),Rr.close(Z.id,"failed",ie instanceof Error?ie.message:String(ie))}})(),M({ok:!0,session:Z,streamUrl:`/api/runtime/log-stream?id=${encodeURIComponent(Z.id)}&workload=${encodeURIComponent(D)}`},201)}if((W.pathname==="/api/runtime/log-stream"||W.pathname==="/api/runtime/exec-stream")&&L.method==="GET"){let T=String(W.searchParams.get("id")??""),D=String(W.searchParams.get("workload")??""),U=Number(L.headers.get("last-event-id")??W.searchParams.get("after")??0)||0,q=Rr.read(T,D,U),G=W.pathname.includes("exec")?"exec":"logs";if(!q||q.kind!==G)return M({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return M_(Rr,q,U,L.signal)}if((W.pathname==="/api/runtime/log-sessions"||W.pathname==="/api/runtime/exec-sessions")&&L.method==="DELETE"){let T=await se(L),D=Rr.cancel(String(T.id??""),String(T.workloadId??""));if(!D)return M({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return M({ok:!0,session:D})}if(W.pathname==="/api/runtime/exec-sessions"&&L.method==="POST"){let T=await se(L),D=String(T.workloadId??""),U=await te(h,De),q=U.workloads.find((ie)=>ie.id===D);if(!q)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);let G=gr.resolveSession(L),Z=new le(h,De,{inventory:async()=>U}),Q=Rr.create("exec",D);return we({controlPlane:E,environment:De,actor:Se,kind:"runtime.exec",resourceSlug:q.links.service,input:{workloadId:D,provider:q.provider,preset:T.preset?String(T.preset):null,freeForm:!!String(T.command??"").trim()},execute:()=>Z.exec({workloadId:D,preset:["process","sockets","filesystem"].includes(String(T.preset))?String(T.preset):void 0,command:typeof T.command==="string"?T.command:void 0,confirm:String(T.confirm??""),recentAuth:!Ne||!!G&&Le.isRecentlyAuthenticated(G)})}).then(({result:ie,operation:Ae})=>{if(Rr.append(Q.id,`operation ${Ae.id}
698
+ `,"system"),ie.stdout)Rr.append(Q.id,ie.stdout,"stdout");if(ie.stderr)Rr.append(Q.id,ie.stderr,"stderr");Rr.close(Q.id,ie.ok?"complete":"failed",ie.error)}).catch((ie)=>{let Ae=ie instanceof Error?ie.message:String(ie);Rr.append(Q.id,Ae,"stderr"),Rr.close(Q.id,"failed",Ae)}),M({ok:!0,session:Q,streamUrl:`/api/runtime/exec-stream?id=${encodeURIComponent(Q.id)}&workload=${encodeURIComponent(D)}`},202)}if(W.pathname==="/api/runtime/files/read"&&L.method==="POST"){let T=await se(L),D=await te(h,De),U=gr.resolveSession(L),q=await new le(h,De,{inventory:async()=>D}).readFile({workloadId:String(T.workloadId??""),path:String(T.path??""),confirm:String(T.confirm??""),recentAuth:!Ne||!!U&&Le.isRecentlyAuthenticated(U)});return M(q,q.ok?200:409)}if(W.pathname==="/api/runtime/files/write"&&L.method==="POST"){let T=await se(L),D=await te(h,De),U=String(T.workloadId??""),q=D.workloads.find((ie)=>ie.id===U);if(!q)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);let G=gr.resolveSession(L),Z=new le(h,De,{inventory:async()=>D}),Q=await we({controlPlane:E,environment:De,actor:Se,kind:"runtime.file.write",resourceSlug:q.links.service,input:{workloadId:U,provider:q.provider,path:String(T.path??""),bytes:Buffer.from(String(T.contentBase64??""),"base64").byteLength},execute:()=>Z.writeFile({workloadId:U,path:String(T.path??""),contentBase64:String(T.contentBase64??""),confirm:String(T.confirm??""),recentAuth:!Ne||!!G&&Le.isRecentlyAuthenticated(G)})});return M({...Q.result,controlPlaneOperation:Q.operation},Q.result.ok?200:409)}if(W.pathname==="/api/runtime/operations"&&L.method==="POST"){let T=await se(L),D=String(T.workloadId??""),U=String(T.action??"");if(!D||!["start","stop","restart","redeploy","scale","inspect"].includes(U))return M({ok:!1,error:"A valid workloadId and lifecycle action are required."},422);let q=await te(h,De),G=q.workloads.find((Ae)=>Ae.id===D);if(!G)return M({ok:!1,error:"Workload was not found in the current project and environment."},404);let Z=gr.resolveSession(L),Q=new le(h,De,{inventory:async()=>q}),ie=await we({controlPlane:E,environment:De,actor:Se,kind:`runtime.${U}`,resourceSlug:G.links.service,input:{workloadId:D,provider:G.provider,action:U,replicas:T.replicas==null?null:Number(T.replicas)},execute:()=>Q.run({workloadId:D,action:U,replicas:T.replicas==null?void 0:Number(T.replicas),confirm:String(T.confirm??""),recentAuth:!Ne||!!Z&&Le.isRecentlyAuthenticated(Z)})});return M({...ie.result,controlPlaneOperation:ie.operation},ie.result.ok?200:409)}if(W.pathname.startsWith("/api/protection")){let T=Se.role==="admin"||Nc(Se,"security:read"),D=Se.role==="admin"||Nc(Se,"security:manage");if(!T)return M({ok:!1,error:"Protection controls require security:read."},403);let{ProtectionControlStore:U,describePosture:q}=await import("./protection/index.js"),G=new U(E.store),Z=()=>{if(!D)throw Error("Changing protection controls requires security:manage.")};if(W.pathname==="/api/protection"&&L.method==="GET"){let Q=G.current();return M({ok:!0,posture:q(Q),controls:Q,raw:G.raw()})}if(W.pathname==="/api/protection/attack-mode"&&L.method==="POST"){Z();let Q=await se(L);if(Q.enabled===!1)return M({ok:!0,disabled:G.disableAttackMode()});return M({ok:!0,control:G.enableAttackMode({hours:Q.hours==null?void 0:Number(Q.hours),reason:String(Q.reason??"Enabled from the dashboard."),actorId:Ze(Se).actor?.id})})}if(W.pathname==="/api/protection/pause"&&L.method==="POST"){Z();let Q=await se(L);if(Q.enabled===!1)return M({ok:!0,resumed:G.resumeMitigations()});return M({ok:!0,control:G.pauseMitigations({hours:Q.hours==null?void 0:Number(Q.hours),reason:String(Q.reason??""),actorId:Ze(Se).actor?.id})})}if(W.pathname==="/api/protection/ip-rules"&&L.method==="GET")return M({ok:!0,ipRules:G.current().ipRules});if(W.pathname==="/api/protection/ip-rules"&&(L.method==="POST"||L.method==="DELETE")){Z();let Q=await se(L),ie=Q.list==="allow"?"allow":"block",Ae=L.method==="POST"?G.addIpRule(ie,String(Q.cidr??"")):G.removeIpRule(ie,String(Q.cidr??""));return M({ok:!0,ipRules:Ae})}return M({ok:!1,error:"Protection endpoint was not found."},404)}if(W.pathname.startsWith("/api/spend/")||W.pathname==="/api/usage"){let T=await qS(),{store:D,service:U,gate:q}=T,G=Se.role==="admin"||Nc(Se,"billing:read"),Z=Se.role==="admin"||Nc(Se,"billing:manage");if(!G)return M({ok:!1,error:"Spend data requires the billing:read capability."},403);let Q=E.environments.get(De),ie={organizationId:E.organization.id,projectId:E.project.id,environmentId:Q?.id},Ae=()=>{if(!Z)throw Error("Changing a budget requires the billing:manage capability.")};if(W.pathname==="/api/usage"&&L.method==="GET")return M({ok:!0,...U.usageReport({organizationId:ie.organizationId,projectId:ie.projectId,period:W.searchParams.get("period")??"monthly",timezone:W.searchParams.get("timezone")??void 0})});if(W.pathname==="/api/spend/budgets"&&L.method==="GET")return M({ok:!0,budgets:D.listBudgets({organizationId:ie.organizationId,projectId:ie.projectId}).map((ke)=>({...ke,status:U.status(ke)}))});if(W.pathname==="/api/spend/budgets"&&L.method==="POST"){Ae();let ke=await se(L),ot=String(ke.scope??"project"),Oe=D.createBudget({organizationId:ie.organizationId,projectId:ot==="organization"?void 0:ie.projectId,environmentId:ot==="environment"?ie.environmentId:void 0,name:String(ke.name??"").trim(),period:ke.period??"monthly",timezone:ke.timezone?String(ke.timezone):void 0,softLimitCents:ke.softLimitCents==null?void 0:Math.round(Number(ke.softLimitCents)),hardLimitCents:ke.hardLimitCents==null?void 0:Math.round(Number(ke.hardLimitCents)),graceSeconds:ke.graceSeconds==null?void 0:Number(ke.graceSeconds),dryRun:ke.dryRun!==!1});return M({ok:!0,budget:Oe})}if(W.pathname==="/api/spend/budgets"&&L.method==="PATCH"){Ae();let ke=await se(L),ot=String(ke.id??""),Oe=D.getBudget(ot);if(!Oe||Oe.organizationId!==ie.organizationId)return M({ok:!1,error:"Budget was not found."},404);return M({ok:!0,budget:D.updateBudget(ot,{softLimitCents:ke.softLimitCents==null?Oe.softLimitCents:Math.round(Number(ke.softLimitCents)),hardLimitCents:ke.hardLimitCents==null?Oe.hardLimitCents:Math.round(Number(ke.hardLimitCents)),enabled:ke.enabled==null?Oe.enabled:ke.enabled===!0,dryRun:ke.dryRun==null?Oe.dryRun:ke.dryRun===!0},ke.expectedVersion==null?void 0:Number(ke.expectedVersion))})}if(W.pathname==="/api/spend/budgets"&&L.method==="DELETE"){Ae();let ke=await se(L),ot=String(ke.id??""),Oe=D.getBudget(ot);if(!Oe||Oe.organizationId!==ie.organizationId)return M({ok:!1,error:"Budget was not found."},404);let et=q.closeBudget(ot);return D.deleteBudget(ot),M({ok:!0,deleted:!0,lifted:et})}if(W.pathname==="/api/spend/check"&&L.method==="POST"){Ae();let ke=await se(L),{SpendRunner:ot}=await import("./spend/index.js"),Oe=new ot({controlPlane:E.store,store:D,alerts:ct});if(ke.apply!==!0){let $e=D.budgetsForScope(ie.organizationId,ie.projectId,ie.environmentId);return M({ok:!0,applied:!1,preview:$e.map((Qe)=>U.status(Qe))})}let et=await Oe.run({...ie,environmentKind:Q?.kind});return M({ok:!0,applied:!0,result:et})}if(W.pathname==="/api/spend/enforcement"&&L.method==="GET")return M({ok:!0,enforcement:q.listUnder({organizationId:ie.organizationId})});if(W.pathname==="/api/spend/release"&&L.method==="POST"){Ae();let ke=await se(L),ot=q.close(String(ke.budgetId??""),ke.action);return M({ok:ot,released:ot,note:ot?"The next spend cycle re-applies this if spend is still over the threshold.":"That action was not in force."})}if(W.pathname==="/api/spend/anomalies"&&L.method==="GET")return M({ok:!0,anomalies:D.listAnomalies({organizationId:ie.organizationId,projectId:ie.projectId,unacknowledgedOnly:W.searchParams.get("unacknowledged")==="true"})});if(W.pathname==="/api/spend/anomalies/acknowledge"&&L.method==="POST"){Ae();let ke=await se(L);return M({ok:!0,acknowledged:D.acknowledgeAnomaly(String(ke.id??""))})}return M({ok:!1,error:"Spend endpoint was not found."},404)}if(W.pathname.startsWith("/api/health/")||W.pathname.startsWith("/api/alerts")||W.pathname.startsWith("/api/notifications/")){let T=E.environments.get(De),D=E.store.listResources(E.project.id,T?.id),U=Se.role==="admin"||!!T&&Ya(Se,T.id,"runtime:read")?D:D.filter((Q)=>rn(Se,Q.id,"runtime:read")),q=(Q)=>!Q||U.some((ie)=>ie.id===Q),G=(Q)=>{if(!Q)return;let ie=D.find((Ae)=>Ae.id===Q||Ae.slug===Q);if(!ie)throw Error("Alert resource was not found.");if(!q(ie.id))throw Error("Alert resource is outside your authorized scope.");return ie.id},Z=Ze(Se).actor;if(W.pathname==="/api/health/checks"&&L.method==="GET")return M({ok:!0,checks:ct.listHealthChecks(E.project.id,T?.id).filter((Q)=>q(Q.resourceId)).map((Q)=>({...Q,results:ct.listHealthResults(Q.id,20)}))});if(W.pathname==="/api/health/checks"&&L.method==="POST"){let Q=await se(L),ie=String(Q.kind??"http");if(ie==="command"&&Se.role!=="admin")return M({ok:!1,error:"Command health checks require an administrator."},403);let Ae={method:String(Q.config?.method??"GET").toUpperCase().slice(0,10),path:Q.config?.path?String(Q.config.path).slice(0,500):void 0,port:Q.config?.port==null?void 0:Number(Q.config.port),command:Array.isArray(Q.config?.command)?Q.config.command.map(String).slice(0,20):void 0,expectedStatuses:Array.isArray(Q.config?.expectedStatuses)?Q.config.expectedStatuses.map(Number).filter(Number.isInteger).slice(0,20):void 0,expectedBody:Q.config?.expectedBody?String(Q.config.expectedBody).slice(0,500):void 0};return M({ok:!0,check:ct.createHealthCheck({projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource),name:String(Q.name??""),kind:ie,target:String(Q.target??""),config:Ae,intervalSeconds:Number(Q.intervalSeconds)||60,timeoutSeconds:Number(Q.timeoutSeconds)||10,failureThreshold:Number(Q.failureThreshold)||3,recoveryThreshold:Number(Q.recoveryThreshold)||2,regions:Array.isArray(Q.regions)?Q.regions.map(String):["local"],enabled:Q.enabled!==!1})},201)}if(W.pathname==="/api/health/checks"&&L.method==="PATCH"){let Q=await se(L),ie=ct.getHealthCheck(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Health check was not found."},404);return M({ok:!0,check:ct.setHealthCheckEnabled(ie.id,Q.enabled!==!1)})}if(W.pathname==="/api/health/checks/test"&&L.method==="POST"){let Q=await se(L),ie=ct.getHealthCheck(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Health check was not found."},404);return M({ok:!0,productionIncidentCreated:!1,result:await new Fe(ct).probe(ie)})}if(W.pathname==="/api/health/checks/run"&&L.method==="POST"){let Q=await se(L),ie=ct.getHealthCheck(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Health check was not found."},404);let Ae=await new Fe(ct).runAndEvaluate(ie),ke=[];for(let ot of Ae.evaluations.filter((Oe)=>Oe.notify&&Oe.alert)){let Oe=Nn.enqueue(E.organization.id,ot.alert,ot.transition);ke.push(...await Nn.deliverAll(Oe))}return M({ok:!0,...Ae,deliveries:ke})}if(W.pathname==="/api/alerts/rules"&&L.method==="GET")return M({ok:!0,rules:ct.listRules(E.project.id,T?.id).filter((Q)=>q(Q.resourceId))});if(W.pathname==="/api/alerts/rules"&&L.method==="POST"){let Q=await se(L),ie=Q.healthCheckId?ct.getHealthCheck(String(Q.healthCheckId)):void 0;if(Q.healthCheckId&&(!ie||!q(ie.resourceId)))return M({ok:!1,error:"Health check was not found."},404);return M({ok:!0,rule:ct.createRule({projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource)??ie?.resourceId,healthCheckId:ie?.id,name:String(Q.name??""),signal:String(Q.signal??(ie?"health":"")),operator:String(Q.operator??(ie?"unhealthy":"gt")),threshold:Q.threshold==null?void 0:Number(Q.threshold),recoveryThreshold:Q.recoveryThreshold==null?void 0:Number(Q.recoveryThreshold),windowMs:Number(Q.windowMs)||300000,consecutive:Number(Q.consecutive)||ie?.failureThreshold||3,recoveryConsecutive:Number(Q.recoveryConsecutive)||ie?.recoveryThreshold||2,noDataPolicy:["ignore","pending","firing"].includes(String(Q.noDataPolicy))?Q.noDataPolicy:"pending",severity:["info","warning","critical"].includes(String(Q.severity))?Q.severity:"warning",groupBy:Array.isArray(Q.groupBy)?Q.groupBy.map(String):[],labels:Q.labels&&typeof Q.labels==="object"?Q.labels:{},enabled:Q.enabled!==!1})},201)}if(W.pathname==="/api/alerts/rules"&&L.method==="PATCH"){let Q=await se(L),ie=ct.getRule(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Alert rule was not found."},404);return M({ok:!0,rule:ct.setRuleEnabled(ie.id,Q.enabled!==!1)})}if(W.pathname==="/api/alerts/evaluate"&&L.method==="POST")return M({ok:!0,...await af(T?.id)});if(W.pathname==="/api/alerts"&&L.method==="GET")return M({ok:!0,alerts:ct.listAlerts(E.project.id,{environmentId:T?.id,states:W.searchParams.getAll("state").length?W.searchParams.getAll("state"):void 0,limit:Number(W.searchParams.get("limit"))||200}).filter((Q)=>q(Q.resourceId)).map((Q)=>({...Q,deliveries:ct.listDeliveries({alertId:Q.id,limit:50})}))});if(W.pathname==="/api/alerts/action"&&L.method==="POST"){let Q=await se(L),ie=ct.getAlert(String(Q.id??""));if(!ie||!q(ie.resourceId))return M({ok:!1,error:"Alert was not found."},404);let Ae=String(Q.action??"");if(Ae==="acknowledge")return M({ok:!0,alert:ct.acknowledge(ie.id,Z?.id??"")});if(Ae==="assign")return M({ok:!0,alert:ct.assign(ie.id,Q.ownerActorId==="me"?Z?.id:Q.ownerActorId?String(Q.ownerActorId):void 0,Z?.id)});if(Ae==="silence"){if(Se.role!=="admin")return M({ok:!1,error:"Silencing production alerts requires an administrator."},403);let ke=gr.resolveSession(L);if(Ne&&(!ke||!Le.isRecentlyAuthenticated(ke)))return M({ok:!1,error:"Recent authentication is required to silence alerts.",stepUpRequired:!0},401);return M({ok:!0,alert:ct.silenceAlert(ie.id,String(Q.until??""),Z?.id)})}return M({ok:!1,error:"Action must be acknowledge, assign, or silence."},422)}if(W.pathname==="/api/alerts/silences"&&L.method==="POST"){let Q=await se(L);return M({ok:!0,id:ct.createSilence({projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource),matcher:Q.matcher,reason:String(Q.reason??""),startsAt:String(Q.startsAt??new Date().toISOString()),endsAt:String(Q.endsAt??""),timezone:String(Q.timezone??"UTC"),actorId:Z?.id})},201)}if(W.pathname==="/api/notifications/channels"&&L.method==="GET")return M({ok:!0,channels:ct.listChannels(E.organization.id)});if(W.pathname==="/api/notifications/channels"&&L.method==="POST"){let Q=await se(L),ie=String(Q.kind??""),Ae=ie==="email"?{to:Q.config?.to,from:Q.config?.from}:ie==="telegram"?{chatId:String(Q.config?.chatId??"")}:{};return M({ok:!0,channel:ct.createChannel({organizationId:E.organization.id,name:String(Q.name??""),kind:ie,config:Ae,credential:Q.credential?String(Q.credential):void 0,actorId:Z?.id})},201)}if(W.pathname==="/api/notifications/channels"&&L.method==="PATCH"){let Q=await se(L),ie=String(Q.id??"");if(Q.credential)return M({ok:!0,channel:ct.rotateChannel(ie,String(Q.credential))});let Ae=String(Q.status??"paused");if(!["active","paused","disabled"].includes(Ae))return M({ok:!1,error:"Channel status must be active, paused, or disabled."},422);return M({ok:!0,channel:ct.setChannelStatus(ie,Ae)})}if(W.pathname==="/api/notifications/channels/test"&&L.method==="POST"){let Q=await se(L);return M({ok:!0,productionIncidentCreated:!1,result:await Nn.testChannel(String(Q.id??""))})}if(W.pathname==="/api/notifications/routes"&&L.method==="GET")return M({ok:!0,routes:ct.listRoutes(E.organization.id)});if(W.pathname==="/api/notifications/routes"&&L.method==="POST"){let Q=await se(L),ie=Array.isArray(Q.channelIds)?Q.channelIds.map(String):[];if(ie.some((Ae)=>ct.getChannel(Ae)?.organizationId!==E.organization.id))return M({ok:!1,error:"Route contains an unavailable channel."},422);return M({ok:!0,route:ct.createRoute({organizationId:E.organization.id,name:String(Q.name??""),priority:Number(Q.priority)||0,matcher:Q.matcher&&typeof Q.matcher==="object"?Q.matcher:{},channelIds:ie,quietHours:Q.quietHours,groupWaitSeconds:Number(Q.groupWaitSeconds)||30,reminderSeconds:Q.reminderSeconds==null?void 0:Number(Q.reminderSeconds),escalation:Array.isArray(Q.escalation)?Q.escalation:[],template:Q.template?String(Q.template):void 0,rateLimitPerMinute:Number(Q.rateLimitPerMinute)||60,enabled:Q.enabled!==!1})},201)}if(W.pathname==="/api/notifications/routes"&&L.method==="PATCH"){let Q=await se(L),ie=ct.getRoute(String(Q.id??""));if(!ie||ie.organizationId!==E.organization.id)return M({ok:!1,error:"Notification route was not found."},404);return M({ok:!0,route:ct.setRouteEnabled(ie.id,Q.enabled!==!1)})}if(W.pathname==="/api/notifications/routes/preview"&&L.method==="POST"){let Q=await se(L),Ae=(Q.alertId?ct.getAlert(String(Q.alertId)):void 0)??{id:"preview",ruleId:"preview",projectId:E.project.id,environmentId:T?.id,resourceId:G(Q.resourceId??Q.resource),dedupKey:"preview",groupKey:String(Q.groupKey??"default"),state:"firing",severity:["info","warning","critical"].includes(String(Q.severity))?Q.severity:"warning",title:String(Q.title??"Rule preview"),evidence:{},failureCount:1,recoveryCount:0,occurrenceCount:1,firstSeenAt:new Date().toISOString(),lastSeenAt:new Date().toISOString(),firingAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return M({ok:!0,productionIncidentCreated:!1,matches:Nn.preview(E.organization.id,Ae,String(Q.eventType??"firing")).map((ke)=>({route:ke.route,channels:ke.channels,quiet:ke.quiet}))})}if(W.pathname==="/api/notifications/deliveries"&&L.method==="GET")return M({ok:!0,deliveries:ct.listDeliveries({alertId:W.searchParams.get("alertId")??void 0,states:W.searchParams.getAll("state"),limit:Number(W.searchParams.get("limit"))||200})});if(W.pathname==="/api/notifications/deliveries/retry"&&L.method==="POST"){let Q=await se(L),ie=ct.getDelivery(String(Q.id??""));if(!ie)return M({ok:!1,error:"Delivery was not found."},404);return ct.updateDelivery(ie.id,{state:"retrying",attempt:Math.max(0,ie.attempt-1),nextAttemptAt:new Date().toISOString()}),M({ok:!0,delivery:await Nn.deliver(ie.id)})}}if(W.pathname.startsWith("/api/jobs")||W.pathname.startsWith("/api/workers")){let T=E.environments.get(De),D=E.store.listResources(E.project.id,T?.id),q=Se.role==="admin"||!!T&&Ya(Se,T.id,"automation:read")?D:D.filter(($e)=>rn(Se,$e.id,"automation:read")),G=($e)=>!$e||q.some((Qe)=>Qe.id===$e),Z=Ze(Se).actor,Q=H.get(De)??z,ie=Ou(h,Q),Ae=ie.filter(($e)=>!$e.danger&&["scheduler","backup","worker"].includes($e.group)),ke=O(h),ot=()=>{let $e=gr.resolveSession(L);return!Ne||!!$e&&Le.isRecentlyAuthenticated($e)},Oe=($e)=>{if(!$e||typeof $e!=="object"||Array.isArray($e))return{};let Qe=Object.entries($e).slice(0,50);if(Qe.some(([,yt])=>typeof yt!=="string"||!/^(?:secret|ssm|arn|env):\/\//.test(yt)))throw Error("Job payload values must be secret or environment references, never inline values.");return Object.fromEntries(Qe)},et=($e,Qe,yt)=>E.store.appendEvent({organizationId:E.organization.id,projectId:E.project.id,resourceId:yt,actorId:Z?.id,type:`job.${$e}`,payload:Qe});if(W.pathname==="/api/jobs/preview"&&L.method==="POST"){let $e=await se(L);try{return M({ok:!0,productionExecutionCreated:!1,preview:ht(String($e.expression??""),String($e.timezone??"UTC"),new Date($e.from?String($e.from):Date.now()),Number($e.count)||5)})}catch(Qe){return M({ok:!1,error:Qe instanceof Error?Qe.message:"Schedule preview could not be generated.",productionExecutionCreated:!1},422)}}if(W.pathname==="/api/jobs"&&L.method==="GET")return M({ok:!0,jobs:Zr.list(E.project.id,{environmentId:T?.id}).filter(($e)=>G($e.resourceId)).map(($e)=>({...$e,preview:ht($e.normalizedExpression,$e.timezone,new Date,5),capability:Hr($e),lastExecution:Zr.listExecutions($e.id,1)[0]}))});if(W.pathname==="/api/jobs"&&L.method==="POST"){let $e=await se(L),Qe=String($e.provider??(ke==="serverless"?"eventbridge":"server")),yt=ke==="serverless"?"eventbridge":"server";if(Qe!==yt)return M({ok:!1,error:`${ke} environments accept ${yt} schedules through this adapter.`},422);let Et=$e.operationId?String($e.operationId):void 0;if(Qe==="server"&&(!Et||!Ae.some((Ar)=>Ar.id===Et)))return M({ok:!1,error:"Server jobs require an allowlisted operation target."},422);let Qt=Hr({provider:Qe,expression:String($e.expression??""),flexibleMinutes:Number($e.flexibleMinutes)||0,missedRunPolicy:$e.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String($e.overlapPolicy))?$e.overlapPolicy:"forbid"});if(!Qt.supported)return M({ok:!1,error:Qt.notes.join(" ")},422);let Tn=$e.resourceId?D.find((Ar)=>Ar.id===$e.resourceId||Ar.slug===$e.resourceId):void 0;if($e.resourceId&&(!Tn||!G(Tn.id)))return M({ok:!1,error:"Job resource was not found."},404);try{let Ar=Qe==="server"?{kind:"dashboard_operation",operationId:Et}:{kind:"serverless_scheduler",action:"run"},io=Zr.create({organizationId:E.organization.id,projectId:E.project.id,environmentId:T?.id,resourceId:Tn?.id,name:String($e.name??""),provider:Qe,expression:String($e.expression??""),timezone:String($e.timezone??"UTC"),startsAt:$e.startsAt?String($e.startsAt):void 0,endsAt:$e.endsAt?String($e.endsAt):void 0,flexibleMinutes:Number($e.flexibleMinutes)||0,target:Ar,payloadRefs:Oe($e.payloadRefs),missedRunPolicy:$e.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String($e.overlapPolicy))?$e.overlapPolicy:"forbid",retryPolicy:{maxAttempts:Number($e.maxAttempts)||3,backoffSeconds:Number($e.backoffSeconds)||30,deadLetterRef:$e.deadLetterRef?String($e.deadLetterRef):void 0},timeoutSeconds:Number($e.timeoutSeconds)||900,enabled:$e.enabled!==!1,origin:"managed",ownerActorId:Z?.id,observedState:{},reconciliationStatus:"pending"});return et("created",{jobId:io.id,provider:io.provider,expression:io.normalizedExpression},io.resourceId),M({ok:!0,job:io,capability:Qt},201)}catch(Ar){return M({ok:!1,error:Ar instanceof Error?Ar.message:"Scheduled job could not be created."},422)}}if(W.pathname==="/api/jobs"&&L.method==="PATCH"){let $e=await se(L),Qe=Zr.get(String($e.id??""));if(!Qe||!G(Qe.resourceId))return M({ok:!1,error:"Scheduled job was not found."},404);if(Qe.origin==="config")return M({ok:!1,error:"Config-defined schedules must be edited in cloud.config.ts and reconciled."},409);let yt=$e.missedRunPolicy==null?void 0:String($e.missedRunPolicy),Et=$e.overlapPolicy==null?void 0:String($e.overlapPolicy);if(yt&&!["skip","catch_up"].includes(yt))return M({ok:!1,error:"Missed-run policy must be skip or catch_up."},422);if(Et&&!["allow","forbid","replace"].includes(Et))return M({ok:!1,error:"Overlap policy must be allow, forbid, or replace."},422);try{let Qt=Zr.updateSchedule(Qe.id,{expression:$e.expression?String($e.expression):void 0,timezone:$e.timezone?String($e.timezone):void 0,missedRunPolicy:yt,overlapPolicy:Et,timeoutSeconds:$e.timeoutSeconds==null?void 0:Number($e.timeoutSeconds)});return et("updated",{jobId:Qt.id,expression:Qt.normalizedExpression,version:Qt.version},Qt.resourceId),M({ok:!0,job:Qt})}catch(Qt){return M({ok:!1,error:Qt instanceof Error?Qt.message:"Scheduled job could not be updated."},422)}}if(W.pathname==="/api/jobs/action"&&L.method==="POST"){let $e=await se(L),Qe=Zr.get(String($e.id??""));if(!Qe||!G(Qe.resourceId))return M({ok:!1,error:"Scheduled job was not found."},404);let yt=String($e.action??"");if(yt==="run"){let Et=sf.enqueue(Qe,{trigger:"manual",actorId:Z?.id});return et("run_queued",{jobId:Qe.id,executionId:Et.id},Qe.resourceId),M({ok:!0,execution:Et},202)}if(["disable","delete"].includes(yt)&&T?.kind==="production"){if(String($e.confirm??"")!==yt)return M({ok:!1,error:`Type "${yt}" to confirm this production change.`},409);if(!ot())return M({ok:!1,error:"Recent authentication is required for this production change.",stepUpRequired:!0},401)}if(yt==="enable"||yt==="disable"){let Et=Zr.setEnabled(Qe.id,yt==="enable");return et(yt==="enable"?"enabled":"disabled",{jobId:Qe.id},Qe.resourceId),M({ok:!0,job:Et})}if(yt==="delete")try{return Zr.remove(Qe.id),et("deleted",{jobId:Qe.id,name:Qe.name},Qe.resourceId),M({ok:!0,deleted:Qe.id})}catch(Et){return M({ok:!1,error:Et instanceof Error?Et.message:"Scheduled job could not be deleted."},409)}return M({ok:!1,error:"Action must be run, enable, disable, or delete."},422)}if(W.pathname==="/api/jobs/history"&&L.method==="GET"){let $e=Zr.get(String(W.searchParams.get("jobId")??""));if(!$e||!G($e.resourceId))return M({ok:!1,error:"Scheduled job was not found."},404);return M({ok:!0,executions:Zr.listExecutions($e.id,Number(W.searchParams.get("limit"))||100).map((Qe)=>({...Qe,logs:Qe.operationId?nr.logs(Qe.operationId,{limit:500}):[]}))})}if(W.pathname==="/api/jobs/reconcile"&&L.method==="POST"){if(!T)return M({ok:!1,error:"Environment was not found."},404);let $e=Po(Zr,h,{organization:E.organization,project:E.project,environment:T,resources:D});return et("reconciled",$e),M({ok:!0,reconciliation:$e})}if(W.pathname==="/api/workers"&&L.method==="GET"){let $e=Array.isArray(Q.workersDetail??Q.workers)?Q.workersDetail??Q.workers:[];return M({ok:!0,workers:Zr.listWorkers(E.project.id,T?.id).filter((Qe)=>G(Qe.resourceId)).map((Qe)=>{let yt=$e.find((Et)=>Et.name===Qe.name||Et.site===Qe.target.site);return yt?{...Qe,observedState:{...Qe.observedState,status:yt.status??"configured",currentJob:yt.currentJob??null,failures:Number(yt.failed??yt.failures)||0,processed:Number(yt.processed)||0}}:Qe})})}if(W.pathname==="/api/workers/action"&&L.method==="POST"){let $e=await se(L),Qe=Zr.getWorker(String($e.id??""));if(!Qe||!G(Qe.resourceId))return M({ok:!1,error:"Worker was not found."},404);let yt=String($e.action??"");if(yt==="restart"){if(String($e.confirm??"")!==Qe.name)return M({ok:!1,error:`Type "${Qe.name}" to restart this worker.`},409);let Et=ie.find((Ar)=>Ar.id===Qe.target.operationId);if(!Et)return M({ok:!1,error:"The allowlisted worker restart operation is unavailable."},409);let Qt=await $u(h,De,Et),Tn=Zr.reconcileWorker(Qe.id,Qt.ok?"in_sync":"unavailable",{...Qe.observedState,lastRestartAt:new Date().toISOString(),command:Qt.command??null,error:Qt.error??Qt.stderr??null});return et("worker_restarted",{workerId:Qe.id,ok:Qt.ok},Qe.resourceId),M({...Qt,worker:Tn},Qt.ok?200:409)}if(yt==="scale")return M({ok:!1,error:Qe.provider==="systemd"?"Systemd worker scale is config-managed; edit the worker definition and reconcile.":"This provider does not expose safe worker scaling through the current adapter."},422);return M({ok:!1,error:"Action must be restart or scale."},422)}}if(W.pathname.startsWith("/api/telemetry/")){let T=E.environments.get(De),D=new at(E.store),U=E.store.listResources(E.project.id,T?.id),q=["/api/telemetry/query","/api/telemetry/tail","/api/telemetry/export","/api/telemetry/saved-queries","/api/telemetry/refresh"].includes(W.pathname)?"runtime:logs":"runtime:read",G=Se.role==="admin"||!!T&&Ya(Se,T.id,q),Z=G?U:U.filter((Oe)=>rn(Se,Oe.id,q)),Q=(Oe)=>vS(Z,G,Oe),ie=(Oe)=>{let et=new Date,$e={"1h":3600000,"6h":21600000,"24h":86400000,"7d":604800000,"30d":2592000000},Qe=String(Oe.to??et.toISOString()),yt=String(Oe.from??new Date(new Date(Qe).getTime()-($e[String(Oe.range??"1h")]??$e["1h"])).toISOString()),Et=(Tn)=>{let Ar=(Array.isArray(Tn)?Tn:String(Tn??"").split(",")).map(String).filter(Boolean);return Ar.length?Ar:void 0},Qt=Et(Oe.kinds)?.filter((Tn)=>["metric","log","trace","request","event"].includes(Tn));return{projectId:E.project.id,environmentId:T?.id,resourceIds:Q(Oe.resources),kinds:Qt,names:Et(Oe.names),sources:Et(Oe.sources),levels:Et(Oe.levels),from:yt,to:Qe,text:String(Oe.text??"")||void 0,traceId:String(Oe.traceId??"")||void 0,requestId:String(Oe.requestId??"")||void 0,deploymentId:String(Oe.deploymentId??"")||void 0,releaseId:String(Oe.releaseId??"")||void 0,workloadId:String(Oe.workloadId??"")||void 0,cursor:String(Oe.cursor??"")||void 0,limit:Number(Oe.limit)||void 0}},Ae=Object.fromEntries(W.searchParams.entries()),ke=(Oe=!1)=>Fg({controlPlane:E.store,projectId:E.project.id,environmentId:T?.id,config:h,environment:De,force:Oe,lightweight:!Oe}),ot=()=>{let Oe=E.store.getSetting(`telemetry.collection:${E.project.id}:${T?.id??"all"}`)??{};return{generatedAt:String(Oe.generatedAt??new Date().toISOString()),cached:!0,statuses:Array.isArray(Oe.statuses)?Oe.statuses:[],errors:Array.isArray(Oe.errors)?Oe.errors:[],policy:Oe.policy??$t(E.store,E.project.id)}};if(W.pathname==="/api/telemetry/status"&&L.method==="GET"){ke(!1);let Oe=ot(),et=G?Oe.statuses:D.status(E.project.id,T?.id,Oe.policy.rawDays,Oe.policy.samplingRate,Z.map((Qe)=>Qe.id)),$e=et.reduce((Qe,yt)=>Qe+yt.estimatedDailyBytes*30,0);return M({ok:!0,generatedAt:Oe.generatedAt,cached:Oe.cached,sources:et,errors:G?Oe.errors:[],policy:Oe.policy,retention:{rawDays:Oe.policy.rawDays,downsampleAfterDays:Oe.policy.downsampleAfterDays,downsampleBucketMs:Oe.policy.downsampleBucketMs,maxRecords:Oe.policy.maxRecords},estimatedMonthlyBytes:$e,estimatedMonthlyCostUsd:Gc($e,Oe.policy),costEstimateConfigured:Oe.policy.estimatedStorageUsdPerGbMonth>0})}if(W.pathname==="/api/telemetry/settings"&&L.method==="GET")return M({ok:!0,policy:$t(E.store,E.project.id)});if(W.pathname==="/api/telemetry/settings"&&L.method==="PATCH"){let Oe=Hc(E.store,E.project.id,await se(L));return ES(E.project.id),M({ok:!0,policy:Oe})}if(W.pathname==="/api/telemetry/query"&&L.method==="GET"){ke(!1);let Oe=ot();return M({ok:!0,collection:{generatedAt:Oe.generatedAt,cached:Oe.cached},...D.query(ie(Ae))})}if(W.pathname==="/api/telemetry/tail"&&L.method==="GET"){ke(!1);let Oe=new TextEncoder,et=new Date,$e=ie({...Ae,kinds:Ae.kinds||"log,request,event,trace",from:Ae.from||new Date(et.getTime()-120000).toISOString(),to:et.toISOString(),limit:Math.min(1000,Number(Ae.limit)||200),cursor:void 0}),Qe=L.headers.get("last-event-id")||String(Ae.cursor??"")||void 0,yt,Et=!1,Qt=!1,Tn=new ReadableStream({start(Ar){let io=()=>{if(Et)return;if(Et=!0,yt)clearInterval(yt);L.signal.removeEventListener("abort",io);try{Ar.close()}catch{}},bf=async()=>{if(Et||Qt)return;Qt=!0;try{let Ss=D.tail({...$e,to:new Date(Date.now()+1000).toISOString()},Qe);for(let Sf of Ss.records)Qe=ci(Sf)??Qe,Ar.enqueue(Oe.encode(`id: ${Qe??""}
699
699
  event: record
700
700
  data: ${JSON.stringify(Sf)}
701
701
 
702
- `));if(Ss.cursor)Ye=Ss.cursor}catch(Ss){Ar.enqueue(Oe.encode(`event: error
702
+ `));if(Ss.cursor)Qe=Ss.cursor}catch(Ss){Ar.enqueue(Oe.encode(`event: error
703
703
  data: ${JSON.stringify({message:Ss instanceof Error?Ss.message:String(Ss)})}
704
704
 
705
705
  `))}finally{Qt=!1}};bf(),yt=setInterval(()=>{if(bf(),!Et)Ar.enqueue(Oe.encode(`event: heartbeat
706
- data: ${JSON.stringify({cursor:Ye,at:new Date().toISOString()})}
706
+ data: ${JSON.stringify({cursor:Qe,at:new Date().toISOString()})}
707
707
 
708
- `))},5000),yt.unref?.(),L.signal.addEventListener("abort",io,{once:!0})},cancel(){if(Et=!0,yt)clearInterval(yt)}});return new Response(Tn,{headers:{"cache-control":"no-cache, no-transform",connection:"keep-alive","content-type":"text/event-stream; charset=utf-8","x-accel-buffering":"no"}})}if(W.pathname==="/api/telemetry/series"&&L.method==="GET"){ke(!1);let Oe=ot(),et=["sum","avg","min","max","count","p50","p90","p95","p99"].includes(String(Ae.aggregation))?Ae.aggregation:"avg",Ne=ie({...Ae,kinds:"metric",limit:5000}),Ye=D.series({...Ne,bucketMs:Number(Ae.bucketMs)||60000,aggregation:et,timezone:String(Ae.timezone??"UTC"),compareFrom:Ae.compareFrom,compareTo:Ae.compareTo});return M({ok:!0,collection:{generatedAt:Oe.generatedAt,cached:Oe.cached},query:{aggregation:et,bucketMs:Number(Ae.bucketMs)||60000,timezone:String(Ae.timezone??"UTC")},series:Ye})}if(W.pathname==="/api/telemetry/refresh"&&L.method==="POST")return M({ok:!0,...await ke(!0)});if(W.pathname==="/api/telemetry/export"&&L.method==="POST"){let Oe=await se(L);await ke(!1);let et=D.query({...ie(Oe),limit:Math.min(5000,Number(Oe.limit)||5000),cursor:void 0});if((Oe.format==="csv"?"csv":"json")==="json")return new Response(JSON.stringify({exportedAt:new Date().toISOString(),query:ie(Oe),...et},null,2),{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.json"',"content-type":"application/json; charset=utf-8"}});let Ye=["timestamp","kind","source","name","level","value","unit","message","traceId","requestId","deploymentId","releaseId","workloadId"],yt=[Ye.join(","),...et.records.map((Et)=>Ye.map((Qt)=>`"${String(Et[Qt]??"").replaceAll('"','""')}"`).join(","))].join(`
709
- `);return new Response(yt,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(W.pathname==="/api/telemetry/saved-queries"&&L.method==="GET"){let Oe=Xe(Se);return M({ok:!0,queries:D.listSavedQueries(E.project.id,Oe.actor?.id)})}if(W.pathname==="/api/telemetry/saved-queries"&&L.method==="POST"){let Oe=await se(L),et=Xe(Se);return M({ok:!0,query:D.saveQuery(E.project.id,et.actor?.id,String(Oe.name??""),ie(Oe.query??Oe))},201)}if(W.pathname==="/api/telemetry/saved-queries"&&L.method==="DELETE"){let Oe=await se(L),et=Xe(Se),Ne=D.deleteSavedQuery(E.project.id,et.actor?.id,String(Oe.id??""));return M({ok:Ne},Ne?200:404)}}if(W.pathname.startsWith("/api/configuration")){let T=E.environments.get(De),D=Se.role==="admin"||!!jn.capabilities?.includes("secrets:read"),U=Se.role==="admin"||!!jn.capabilities?.includes("secrets:write"),q={projectId:E.project.id,environmentId:T?.id},G={"cache-control":"no-store"};if(W.pathname==="/api/configuration"&&L.method==="GET"){let Z=Object.fromEntries(W.searchParams),Q=Z.scopeType||Z.scopeId?Ka(Z,q):void 0,ie=["variable","secret"].includes(String(Z.kind))?Z.kind:void 0,Ae=Q?.type==="preview"?wr.previews.getInstance(Q.id):void 0,ke=Ae?wr.previews.getDefinition(Ae.definitionId):void 0,ot=Q?await Rn.resolve({projectId:E.project.id,environmentId:Q.environmentId,resourceId:Q.resourceId,functionId:Q.type==="function"?Q.id:void 0,previewId:Q.previewId,trustedPreview:!!Ae&&!Ae.fork,allowedPreviewSecrets:ke?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:D}):void 0,Oe=E.store.listResources(E.project.id);return M({ok:!0,entries:Rn.list({projectId:E.project.id,scope:Q,kind:ie,search:Z.search,canReadSecretMetadata:D}),effectiveEntries:ot?Object.values(ot.entries).filter((et)=>!ie||et.kind===ie).filter((et)=>!Z.search||et.key.toLowerCase().includes(String(Z.search).toLowerCase())):[],configurationHash:ot?.configurationHash,warnings:ot?.warnings??[],scopes:{project:E.project,environments:E.store.listEnvironments(E.project.id),resources:Oe.filter((et)=>et.kind!=="function"),functions:Oe.filter((et)=>et.kind==="function"),previews:wr.previews.listInstances({projectId:E.project.id}).filter((et)=>et.status!=="destroyed").map((et)=>({id:et.id,name:et.name,environmentId:et.baseEnvironmentId,resourceId:et.resourceId,fork:et.fork,status:et.status}))}},200,G)}if(W.pathname==="/api/configuration/export"&&L.method==="GET"){let Z=Ka(Object.fromEntries(W.searchParams),q);return new Response(Rn.exportVariables({projectId:E.project.id,scope:Z}),{headers:{...G,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(W.pathname==="/api/configuration/plan"&&L.method==="POST"){let Z=await se(L),Q=Ka(Z,q),ie=Z.values&&typeof Z.values==="object"&&!Array.isArray(Z.values)?Object.fromEntries(Object.entries(Z.values).map(([Ae,ke])=>[Ae,String(ke)])):{};return M({ok:!0,plan:Rn.plan({projectId:E.project.id,scope:Q,values:ie,removeMissing:Z.removeMissing===!0})},200,G)}if(W.pathname==="/api/configuration"&&L.method==="POST"){let Z=await se(L),Q=Ka(Z,q),ie=Z.kind==="secret"?"secret":"variable",Ae=String(Z.key??"");if(ie==="secret"&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);try{let ke=await Rn.set({organizationId:E.organization.id,projectId:E.project.id,scope:Q,key:Ae,kind:ie,value:Z.value==null?void 0:String(Z.value),reference:Z.reference==null?void 0:String(Z.reference),backend:Z.backend,required:Z.required===!0,expectedVersion:Z.expectedVersion==null?void 0:Number(Z.expectedVersion),confirmed:String(Z.confirm??"")===Ae,idempotencyKey:L.headers.get("idempotency-key")??Z.idempotencyKey,actorId:Xe(Se).actor?.id});return M({ok:!0,entry:Rn.list({projectId:E.project.id,scope:Q,canReadSecretMetadata:D}).find((ot)=>ot.id===ke.entry.id),mutation:ke.mutation,warnings:ke.warnings},ke.mutation.added.length?201:200,G)}catch(ke){return M({ok:!1,error:ke instanceof Error?ke.message:String(ke)},409,G)}}if(W.pathname==="/api/configuration/import"&&L.method==="POST"){let Z=await se(L),Q=Ka(Z,q),ie=Array.isArray(Z.secretKeys)?Z.secretKeys.map(String):[];if(ie.length&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);try{let Ae=await Rn.importDotenv({organizationId:E.organization.id,projectId:E.project.id,scope:Q,source:String(Z.source??""),secretKeys:ie,backend:Z.backend,confirmed:Z.confirm==="import",idempotencyKey:L.headers.get("idempotency-key")??Z.idempotencyKey,actorId:Xe(Se).actor?.id});return M({ok:Ae.document.valid,diagnostics:Ae.document.diagnostics,mutation:Ae.mutation,warnings:Ae.warnings},Ae.document.valid?200:422,G)}catch(Ae){return M({ok:!1,error:Ae instanceof Error?Ae.message:String(Ae)},409,G)}}if(W.pathname==="/api/configuration/dependencies"&&L.method==="POST"){let Z=await se(L),Q=Xi.get(String(Z.entryId??"")),ie=E.store.getResource(String(Z.resourceId??""));if(!Q||Q.projectId!==E.project.id||!ie||ie.projectId!==E.project.id)return M({ok:!1,error:"Configuration entry or dependent resource was not found."},404,G);return M({ok:!0,dependency:Xi.setDependency({entryId:Q.id,resourceId:ie.id,injectionTarget:["native_reference","file"].includes(String(Z.injectionTarget))?Z.injectionTarget:"environment",required:Z.required!==!1,requiresRedeploy:Z.requiresRedeploy!==!1,lastDeployedVersion:Z.lastDeployedVersion==null?void 0:Number(Z.lastDeployedVersion)})},200,G)}if(W.pathname==="/api/configuration/transfer"&&L.method==="POST"){let Z=await se(L),Q=Xi.get(String(Z.id??"")),ie=Ka({...Z,scopeType:Z.targetScopeType,scopeId:Z.targetScopeId},q);if(!Q||Q.projectId!==E.project.id)return M({ok:!1,error:"Configuration entry was not found."},404,G);if(Q.kind==="secret"&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);try{let Ae=await Rn.transfer({entryId:Q.id,targetScope:ie,mode:Z.mode==="move"?"move":"copy",confirmed:Z.confirm===Q.key,actorId:Xe(Se).actor?.id,idempotencyKey:L.headers.get("idempotency-key")??Z.idempotencyKey});return M({ok:!0,entry:Rn.list({projectId:E.project.id,scope:ie,canReadSecretMetadata:D}).find((ke)=>ke.id===Ae.entry.id),mutation:Ae.mutation},200,G)}catch(Ae){return M({ok:!1,error:Ae instanceof Error?Ae.message:String(Ae)},409,G)}}if(W.pathname==="/api/configuration/bulk"&&L.method==="POST"){let Z=await se(L),Q=Array.isArray(Z.ids)?Z.ids.map(String).slice(0,500):[],ie=Q.map((ke)=>Xi.get(ke)).filter((ke)=>!!ke&&ke.projectId===E.project.id);if(ie.length!==Q.length)return M({ok:!1,error:"One or more configuration entries were not found."},404,G);if(ie.some((ke)=>ke.kind==="secret")&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);if(Z.action!=="delete"||Z.confirm!=="bulk")return M({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,G);let Ae=[];try{for(let ke of ie)Ae.push(await Rn.remove({entryId:ke.id,expectedVersion:ke.version,confirmed:!0,actorId:Xe(Se).actor?.id}));return M({ok:!0,removed:Ae.flatMap((ke)=>ke.removed),affectedResourceIds:[...new Set(Ae.flatMap((ke)=>ke.affectedResourceIds))].sort()},200,G)}catch(ke){return M({ok:!1,error:ke instanceof Error?ke.message:String(ke),partial:Ae.flatMap((ot)=>ot.removed)},409,G)}}if(W.pathname==="/api/configuration/reveal"&&L.method==="POST"){let Z=await se(L),Q=gr.resolveSession(L);try{return M({ok:!0,value:await Rn.reveal({entryId:String(Z.id??""),canRevealSecrets:D,recentlyAuthenticated:!Be||!!Q&&Fe.isRecentlyAuthenticated(Q),actorId:Xe(Se).actor?.id})},200,G)}catch(ie){return M({ok:!1,error:ie instanceof Error?ie.message:String(ie)},403,G)}}if(W.pathname==="/api/configuration"&&L.method==="DELETE"){let Z=await se(L),Q=Xi.get(String(Z.id??""));if(Q?.kind==="secret"&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);if(!Q||Q.projectId!==E.project.id)return M({ok:!1,error:"Configuration entry was not found."},404,G);try{return M({ok:!0,mutation:await Rn.remove({entryId:Q.id,expectedVersion:Number(Z.expectedVersion),confirmed:String(Z.confirm??"")===Q.key,actorId:Xe(Se).actor?.id})},200,G)}catch(ie){return M({ok:!1,error:ie instanceof Error?ie.message:String(ie)},409,G)}}}if(W.pathname.startsWith("/api/fleet")){let T=Xe(Se).actor?.id,D=(U,q=409)=>M({ok:!1,error:U instanceof Error?U.message:String(U)},q,{"cache-control":"no-store"});if(W.pathname==="/api/fleet"&&L.method==="GET")return M({ok:!0,servers:Qa.list(E.project.id),resources:E.store.listResources(E.project.id),operations:nr.list({projectId:E.project.id,limit:200}).filter((U)=>U.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(W.pathname==="/api/fleet"&&L.method==="POST"){let U=await se(L);try{return M({ok:!0,server:ti.enroll({organizationId:E.organization.id,projectId:E.project.id,name:String(U.name??""),provider:["aws","hetzner"].includes(String(U.provider))?U.provider:"ssh",providerId:U.providerId?String(U.providerId):void 0,region:U.region?String(U.region):void 0,zone:U.zone?String(U.zone):void 0,endpoint:String(U.endpoint??""),sshUser:String(U.sshUser??"deploy"),sshPort:U.sshPort?Number(U.sshPort):22,credentialRef:String(U.credentialRef??""),roles:Array.isArray(U.roles)?U.roles:[],labels:U.labels&&typeof U.labels==="object"?U.labels:{}})},201)}catch(q){return D(q,422)}}if(W.pathname==="/api/fleet/action"&&L.method==="POST"){let U=await se(L),q=String(U.id??""),G=String(U.action??"");try{if(G==="test")return M({ok:!0,server:await ti.test(q)});if(G==="validate")return M({ok:!0,server:await ti.validate(q)});if(G==="review_host_key")return M({ok:!0,server:ti.reviewHostKey(q,String(U.fingerprint??""))});if(G==="bootstrap")return M({ok:!0,...ti.bootstrap(q,U.confirmed===!0)},U.confirmed===!0?202:200);if(G==="heartbeat")return M({ok:!0,server:ti.heartbeat(q,{usage:U.usage&&typeof U.usage==="object"?U.usage:{}})});if(G==="drain")return M({ok:!0,server:ti.drain(q,U.completed===!0)});if(G==="uncordon")return M({ok:!0,server:ti.uncordon(q)});if(G==="archive")return M({ok:!0,server:ti.archive(q,String(U.confirmation??""))});return D("Unsupported fleet action.",422)}catch(Z){return D(Z)}}}if(W.pathname.startsWith("/api/capacity")){let T=(D,U=409)=>M({ok:!1,error:D instanceof Error?D.message:String(D)},U,{"cache-control":"no-store"});if(W.pathname==="/api/capacity"&&L.method==="GET")return M({ok:!0,pools:to.listPools(E.project.id),placements:to.listPlacements(E.project.id),servers:Qa.list(E.project.id)},200,{"cache-control":"no-store"});if(W.pathname==="/api/capacity"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,pool:to.createPool({organizationId:E.organization.id,projectId:E.project.id,name:String(D.name??""),purpose:String(D.purpose??"application"),backend:String(D.backend??"server"),region:D.region?String(D.region):void 0,architecture:D.architecture?String(D.architecture):void 0,labels:D.labels&&typeof D.labels==="object"?D.labels:{},requiredServerLabels:D.requiredServerLabels&&typeof D.requiredServerLabels==="object"?D.requiredServerLabels:{},toleratedTaints:Array.isArray(D.toleratedTaints)?D.toleratedTaints.map(String):[],capacity:D.capacity&&typeof D.capacity==="object"?D.capacity:{},maxWorkloads:Number(D.maxWorkloads??10),costWeight:Number(D.costWeight??1),spreadKey:D.spreadKey?String(D.spreadKey):void 0,concurrency:Number(D.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/capacity/member"&&L.method==="POST"){let D=await se(L);try{return to.addMember(String(D.poolId??""),String(D.serverId??"")),M({ok:!0,pool:to.getPool(String(D.poolId??""))})}catch(U){return T(U,422)}}if(W.pathname==="/api/capacity/explain"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,decisions:rf.explain(E.project.id,{purpose:String(D.purpose??"application"),resources:D.resources&&typeof D.resources==="object"?D.resources:{},region:D.region?String(D.region):void 0,architecture:D.architecture?String(D.architecture):void 0,labels:D.labels&&typeof D.labels==="object"?D.labels:{}})})}catch(U){return T(U,422)}}if(W.pathname==="/api/capacity/action"&&L.method==="POST"){let D=await se(L);try{if(D.action==="drain")return M({ok:!0,...rf.drainPool(String(D.poolId??""))});if(D.action==="enable")return M({ok:!0,pool:to.updatePool(String(D.poolId??""),{status:"active"})});if(D.action==="disable")return M({ok:!0,pool:to.updatePool(String(D.poolId??""),{status:"disabled"})});return T("Unsupported capacity action.",422)}catch(U){return T(U,422)}}}if(W.pathname.startsWith("/api/regions")){let T=(D,U=409)=>M({ok:!1,error:D instanceof Error?D.message:String(D)},U,{"cache-control":"no-store"});if(W.pathname==="/api/regions"&&L.method==="GET")return M({ok:!0,topologies:hs.list(E.project.id).map((D)=>({topology:D,targets:hs.targets(D.id),channels:hs.channels(D.id),route:hs.route(D.id),executions:hs.executions(D.id)}))},200,{"cache-control":"no-store"});if(W.pathname==="/api/regions"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,topology:nf.create({organizationId:E.organization.id,projectId:E.project.id,environmentId:E.environments.get(De)?.id,name:String(D.name??""),hostname:String(D.hostname??""),regions:Array.isArray(D.regions)?D.regions:[],trafficPolicy:D.trafficPolicy==="weighted"||D.trafficPolicy==="latency"?D.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(D.replicate)?D.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(D.maxLagSeconds??30),retainOnDestroy:D.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:D.cdnEnabled===!0,wafEnabled:D.wafEnabled===!0})},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/regions/action"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,...nf.enqueue({topologyId:String(D.topologyId??""),kind:String(D.action??""),targetRegion:D.targetRegion?String(D.targetRegion):void 0,revision:D.revision?String(D.revision):void 0,manifest:D.manifest&&typeof D.manifest==="object"?D.manifest:{},confirmation:D.confirmation?String(D.confirmation):void 0,deleteData:D.deleteData===!0})},202)}catch(U){return T(U,422)}}}if(W.pathname.startsWith("/api/maintenance")){let T=(D,U=409)=>M({ok:!1,error:D instanceof Error?D.message:String(D)},U,{"cache-control":"no-store"});if(W.pathname==="/api/maintenance"&&L.method==="GET")return M({ok:!0,manifests:fi.manifests(E.organization.id),windows:fi.windows(E.project.id),campaigns:fi.campaigns(E.project.id).map((D)=>({campaign:D,targets:fi.targets(D.id)})),cleanups:fi.cleanups(E.project.id),drills:fi.drills(E.project.id)},200,{"cache-control":"no-store"});if(W.pathname==="/api/maintenance/cleanup-preview"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,plan:await Vu.previewCleanup({projectId:E.project.id,kind:String(D.kind??"operations"),criteria:{olderThanDays:Number(D.olderThanDays??30)}},of)},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/maintenance/cleanup-apply"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,...Vu.enqueueCleanup(String(D.planId??""),String(D.confirmation??""))},202)}catch(U){return T(U,422)}}if(W.pathname==="/api/maintenance/drill"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,drill:fi.createDrill({projectId:E.project.id,scenario:String(D.scenario??"control_plane"),isolatedTarget:String(D.isolatedTarget??""),expectedRpoMinutes:Number(D.expectedRpoMinutes??60),expectedRtoMinutes:Number(D.expectedRtoMinutes??30),recoveryPointId:D.recoveryPointId?String(D.recoveryPointId):void 0,topologyId:D.topologyId?String(D.topologyId):void 0})},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/maintenance/drill-run"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,...Vu.enqueueDrill(String(D.drillId??""))},202)}catch(U){return T(U,422)}}}if(W.pathname.startsWith("/api/volumes")){let T=E.environments.get(De),D=Xe(Se).actor?.id,U=(q,G=409)=>M({ok:!1,error:q instanceof Error?q.message:String(q)},G,{"cache-control":"no-store"});if(W.pathname==="/api/volumes"&&L.method==="GET"){let q=Uu.inventory(E.project.id,T?.id),G=E.store.listResources(E.project.id,T?.id).map((Z)=>({id:Z.id,name:Z.name,slug:Z.slug,kind:Z.kind,provider:Z.provider,providerId:Z.providerId}));return M({ok:!0,volumes:q,resources:G,operations:nr.list({projectId:E.project.id,limit:100}).filter((Z)=>Z.operation.kind.startsWith("volume.")),recoveryPoints:Er.listRecoveryPoints(E.project.id).filter((Z)=>Z.kind==="volume"),providers:qu.map((Z)=>({provider:Z.provider,type:Z.type,capabilities:Z.capabilities()}))},200,{"cache-control":"no-store"})}if(W.pathname==="/api/volumes"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.create({organizationId:E.organization.id,projectId:E.project.id,environmentId:T?.id,resourceId:q.resourceId?String(q.resourceId):void 0,name:String(q.name??""),provider:String(q.provider??"docker"),type:q.type==="docker"?"docker":q.type,capacityBytes:q.capacityBytes==null?void 0:Number(q.capacityBytes),filesystem:q.filesystem?String(q.filesystem):void 0,encrypted:q.encrypted===!0,desiredState:q.desiredState&&typeof q.desiredState==="object"?q.desiredState:{},actorId:D})},202,{"cache-control":"no-store"})}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/attach"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.attach(String(q.volumeId??""),{resourceId:String(q.resourceId??""),targetPath:String(q.targetPath??""),readOnly:q.readOnly===!0,uid:q.uid==null?void 0:Number(q.uid),gid:q.gid==null?void 0:Number(q.gid),mode:q.mode?String(q.mode):void 0,propagation:q.propagation,driverOptions:q.driverOptions&&typeof q.driverOptions==="object"?q.driverOptions:{},actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/detach"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.detach(String(q.volumeId??""),String(q.attachmentId??""),{force:q.force===!0,drained:q.drained===!0,unmounted:q.unmounted===!0,confirmation:q.confirmation?String(q.confirmation):void 0,actorId:D})},202)}catch(G){return U(G)}}if(W.pathname==="/api/volumes/resize"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.resize(String(q.volumeId??""),Number(q.capacityBytes),{drained:q.drained===!0,actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/snapshot"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.snapshot(String(q.volumeId??""),{name:q.name?String(q.name):void 0,actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/restore"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.restore(String(q.snapshotId??""),{name:String(q.name??""),actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/discover"&&L.method==="POST")try{return M({ok:!0,volumes:await gi.discover({organizationId:E.organization.id,projectId:E.project.id,environmentId:T?.id,actorId:D})})}catch(q){return U(q,502)}if(W.pathname==="/api/volumes/adopt"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,volume:gi.adopt(String(q.volumeId??""),{name:String(q.name??""),actorId:D})})}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes"&&L.method==="DELETE"){let q=await se(L),G=gr.resolveSession(L);try{return M({ok:!0,...gi.delete(String(q.volumeId??""),{recentAuthAt:!Be||G&&Fe.isRecentlyAuthenticated(G)?new Date().toISOString():void 0,confirmation:q.confirmation?String(q.confirmation):void 0,backupOverride:q.backupOverride===!0,backupOverrideConfirmation:q.backupOverrideConfirmation?String(q.backupOverrideConfirmation):void 0,actorId:D})},202)}catch(Z){return U(Z)}}}if(W.pathname==="/api/backups"&&L.method==="GET"){let T=E.environments.get(De),D=Er.listPolicies(E.project.id,T?.id),U=new Set(D.map((ie)=>ie.id)),q=Er.listRecoveryPoints(E.project.id).filter((ie)=>!ie.policyId||U.has(ie.policyId)),G=Er.listJobs(E.project.id).filter((ie)=>!ie.policyId||U.has(ie.policyId)),Z=(ie)=>({...ie,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!ie.credentialRef,clientEncryptionConfigured:!!ie.encryptionKeyRef}),Q=await Promise.all(Er.listDestinations(E.project.id).map(async(ie)=>({...Z(ie),credentialStatus:await xl(ie,mi)})));return M({ok:!0,destinations:Q,policies:D,recoveryPoints:q,jobs:G,coverage:Er.coverage(E.project.id).filter((ie)=>U.has(ie.policy.id)),resources:T?E.store.listResources(E.project.id,T.id).map((ie)=>({id:ie.id,name:ie.name,slug:ie.slug,kind:ie.kind})):[]})}if(W.pathname==="/api/backups/destinations"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim(),U=String(T.provider??""),q=String(T.encryption??"provider"),G=`secret://data-services/backups/${E.project.id}/${D}`,Z=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(U))return M({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(q))return M({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let Q,ie;if(T.credentials&&typeof T.credentials==="object"&&!Array.isArray(T.credentials))Q=`${G}/credentials`,await mi.put(Q,JSON.stringify(T.credentials)),Z.push(Q);if(q!=="provider"){let ke=String(T.encryptionKey??"");if(ke.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");ie=`${G}/encryption-key`,await mi.put(ie,ke),Z.push(ie)}let Ae=Er.createDestination({organizationId:E.organization.id,projectId:E.project.id,name:D,provider:U,endpoint:T.endpoint?String(T.endpoint):void 0,endpointPolicy:T.endpointPolicy==="allow_private"?"allow_private":"public_https",bucket:T.bucket?String(T.bucket):void 0,prefix:String(T.prefix??""),region:T.region?String(T.region):eo,forcePathStyle:T.forcePathStyle===!0,credentialRef:Q,encryption:q,encryptionKeyRef:ie,immutability:T.immutability&&typeof T.immutability==="object"&&!Array.isArray(T.immutability)?T.immutability:{},status:"untested"});return M({ok:!0,destination:{...Ae,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!Q,clientEncryptionConfigured:!!ie}},201)}catch(Q){for(let ie of Z)await mi.remove(ie).catch(()=>{});return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},422)}}if(W.pathname==="/api/backups/destinations/test"&&L.method==="POST"){let T=await se(L),D=Er.getDestination(String(T.id??""));if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Backup destination was not found."},404);if(D.provider==="aws_backup")return M({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await tf.test(D),M({ok:!0,destination:Er.recordDestinationTest(D.id,{ok:!0})})}catch(U){let q=U instanceof Error?U.message:String(U);return Er.recordDestinationTest(D.id,{ok:!1,error:q}),M({ok:!1,error:q},502)}}if(W.pathname==="/api/backups/policies"&&L.method==="POST"){let T=await se(L),D=E.environments.get(De),U=Er.getDestination(String(T.destinationId??"")),q=String(T.resourceKind??""),G=T.dataServiceId?String(T.dataServiceId):void 0,Z=G?lr.get(G):void 0,Q=T.resourceId?String(T.resourceId):void 0,ie=Q?E.store.getResource(Q):void 0;if(!D)return M({ok:!1,error:"Environment was not found."},404);if(!U||U.projectId!==E.project.id)return M({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(q))return M({ok:!1,error:"A supported backup resource kind is required."},422);if(G&&(!Z||Z.projectId!==E.project.id||Z.environmentId!==D.id))return M({ok:!1,error:"Data service was not found in this environment."},404);if(Q&&(!ie||ie.projectId!==E.project.id||ie.environmentId!==D.id))return M({ok:!1,error:"Resource was not found in this environment."},404);if(q==="managed_database"&&!Z)return M({ok:!1,error:"Managed database policies require a data service."},422);if(q==="logical_database"&&(!Z||!["container","server"].includes(Z.provider)))return M({ok:!1,error:"Logical database policies require an on-box data service."},422);if(q==="volume"&&(!ie||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(T.volumeName??""))))return M({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let Ae=Array.isArray(T.includePatterns)?T.includePatterns.map(String).filter(Boolean):[];if(q==="files"&&(!ie||!Ae.length))return M({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(q==="control_plane"&&U.encryption==="provider")return M({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(q==="infrastructure"&&(U.provider!=="aws_backup"||!Ae.some((ke)=>ke.startsWith("resource:arn:"))||!Ae.some((ke)=>ke.startsWith("role:arn:"))))return M({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let ke=Er.createPolicy({organizationId:E.organization.id,projectId:E.project.id,environmentId:D.id,resourceId:Q,dataServiceId:G,destinationId:U.id,name:String(T.name??"").trim(),resourceKind:q,schedule:String(T.schedule??"daily"),timezone:String(T.timezone??"UTC"),retention:T.retention&&typeof T.retention==="object"&&!Array.isArray(T.retention)?T.retention:{keepLast:7,expireAfterDays:30},compression:["none","gzip","zstd"].includes(String(T.compression))?T.compression:"gzip",encryption:["destination","client_side","both"].includes(String(T.encryption))?T.encryption:"destination",includePatterns:q==="volume"?[String(T.volumeName),...Ae]:Ae,excludePatterns:Array.isArray(T.excludePatterns)?T.excludePatterns.map(String):[],expectedRpoMinutes:Math.max(1,Number(T.expectedRpoMinutes)||1440),expectedRtoMinutes:Math.max(1,Number(T.expectedRtoMinutes)||120),healthCheckId:T.healthCheckId?String(T.healthCheckId):void 0,enabled:T.enabled!==!1});return M({ok:!0,policy:ke},201)}catch(ke){return M({ok:!1,error:ke instanceof Error?ke.message:String(ke)},422)}}if(W.pathname==="/api/backups/run"&&L.method==="POST"){let T=await se(L),D=Er.getPolicy(String(T.policyId??"")),U=E.environments.get(De);if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Backup policy was not found in this environment."},404);try{let q=fs.enqueueBackup(D,new Date().toISOString(),Xe(Se).actor?.id);return M({ok:!0,job:q},202)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:String(q)},409)}}if(W.pathname==="/api/backups/verify"&&L.method==="POST"){let T=await se(L),D=Er.getRecoveryPoint(String(T.recoveryPointId??""));if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Recovery point was not found."},404);return M({ok:!0,job:fs.enqueueVerification(D)},202)}if(W.pathname==="/api/backups/restore"&&L.method==="POST"){let T=await se(L),D=Er.getRecoveryPoint(String(T.recoveryPointId??"")),U=T.mode==="in_place"?"in_place":"isolated",q=T.target&&typeof T.target==="object"&&!Array.isArray(T.target)?{...T.target,inPlace:U==="in_place"}:{inPlace:U==="in_place"},G=gr.resolveSession(L),Z={mode:U,target:q,targetName:String(T.targetName??""),confirm:T.confirm?String(T.confirm):void 0,recentAuth:!Be||!!G&&Fe.isRecentlyAuthenticated(G),downtimeAcknowledged:T.downtimeAcknowledged===!0,safetyBackupId:T.safetyBackupId?String(T.safetyBackupId):void 0};if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Recovery point was not found."},404);if(T.drill===!0&&U!=="isolated")return M({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let Q=fs.planRestore(D,Z);if(T.execute!==!0)return M({ok:!0,plan:Q,executionCreated:!1});let ie=fs.enqueueRestore(D,{...Z,drill:T.drill===!0,actorId:Xe(Se).actor?.id});return M({ok:!0,plan:Q,job:ie},202)}catch(Q){return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},409)}}if(W.pathname==="/api/backups/recovery-points"&&L.method==="POST"){let T=await se(L),D=Er.getRecoveryPoint(String(T.id??""));if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Recovery point was not found."},404);if(T.held==null&&T.pinned==null)return M({ok:!1,error:"held or pinned must be provided."},422);return M({ok:!0,recoveryPoint:Er.updateRecoveryPoint(D.id,{held:T.held==null?D.held:T.held===!0,pinned:T.pinned==null?D.pinned:T.pinned===!0})})}if(W.pathname==="/api/backups/retention"&&L.method==="POST")return M({ok:!0,jobs:fs.enqueueRetention()},202);if(W.pathname==="/api/data-services/capabilities"&&L.method==="GET"){let T=String(W.searchParams.get("engine")??""),D=String(W.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(T)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(D))return M({ok:!1,error:"A supported engine and provider are required."},422);return M({ok:!0,engine:T,provider:D,capabilities:Gr(T,D)})}if(W.pathname==="/api/data-services"&&L.method==="GET"){let T=E.environments.get(De),D=lr.list(E.project.id,T?.id).map((U)=>{let q=lr.credential(U.id);return{...U,credentialRef:void 0,credential:q?{configured:!0,username:q.username,version:q.version,rotatedAt:q.rotatedAt}:void 0,dependencies:lr.dependencies(U.id).map((G)=>({resourceId:G.resourceId,requiresRedeploy:G.requiresRedeploy}))}});return M({ok:!0,services:D})}if(W.pathname==="/api/data-services/preview"&&L.method==="POST"){let T=await se(L);if(T.id){let q=lr.get(String(T.id)),G=E.environments.get(De),Z=String(T.action??"");if(!q||q.projectId!==E.project.id||q.environmentId!==G?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!Bu.includes(Z))return M({ok:!1,error:`Action must be one of: ${Bu.join(", ")}.`},422);try{return M({ok:!0,plan:Tc.plan(q,Z,T.changes??{})})}catch(Q){return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},422)}}let D=String(T.engine??""),U=String(T.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(D)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(U))return M({ok:!1,error:"A supported engine and provider are required."},422);return M({ok:!0,capabilities:Gr(D,U),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(W.pathname==="/api/data-services"&&L.method==="POST"){let T=await se(L),D=String(T.engine??""),U=String(T.provider??""),q=E.environments.get(De),G=Xe(Se);if(!q)return M({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(D)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(U))return M({ok:!1,error:"A supported engine and provider are required."},422);let Z={organizationId:E.organization.id,projectId:E.project.id,environmentId:q.id,resourceId:T.resourceId?String(T.resourceId):void 0,name:String(T.name??"").trim(),engine:D,provider:U,placement:String(T.placement??T.name??"").trim(),engineVersion:T.engineVersion?String(T.engineVersion):void 0,plan:String(T.plan??(U==="aws_elasticache"?"cache.t4g.micro":U==="aws_aurora"?"db.serverless":"db.t4g.micro")),storageGb:T.storageGb==null?void 0:Number(T.storageGb),highAvailability:T.highAvailability===!0,publicExposure:T.publicExposure===!0,allowedCidrs:Array.isArray(T.allowedCidrs)?T.allowedCidrs.map(String):[],desiredState:T.desiredState&&typeof T.desiredState==="object"&&!Array.isArray(T.desiredState)?T.desiredState:{},observedState:{},origin:T.adopt===!0?"adopted":"managed",managementEnabled:T.adopt!==!0,ownerActorId:G.actor?.id,username:T.username?String(T.username):void 0};try{if(T.adopt===!0){let ie=lr.create({...Z,status:"adopted",credentialRef:void 0});return M({ok:!0,service:ie,readOnly:!0},201)}if(!ef({provider:U,engine:D}))return M({ok:!1,error:`No ${U}/${D} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let Q=await Tc.create(Z);return M({ok:!0,service:Q.service,operationId:Q.operationId,oneTimeCredential:Q.credential},201)}catch(Q){return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},422)}}if(W.pathname==="/api/data-services/connections"&&L.method==="GET"){let T=lr.get(String(W.searchParams.get("id")??"")),D=E.environments.get(De);if(!T||T.projectId!==E.project.id||T.environmentId!==D?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);let U=typeof T.observedState.endpoint==="string"?T.observedState.endpoint:void 0,q=typeof T.observedState.readerEndpoint==="string"?T.observedState.readerEndpoint:void 0,G=Number(T.observedState.port)||(T.engine==="postgres"?5432:T.engine==="redis"?6379:T.engine==="mongodb"?27017:T.engine==="libsql"?8080:3306),Z=typeof T.observedState.database==="string"?T.observedState.database:void 0,Q=typeof T.observedState.tls==="boolean"?T.observedState.tls:T.provider.startsWith("aws_"),ie=[...U?[{type:T.publicExposure?"external":"internal",host:U,port:G,database:Z,tls:Q}]:[],...q?[{type:"internal",host:q,port:G,database:Z,tls:Q}]:[],{type:"tunnel",host:U??T.placement,port:G,database:Z,tls:Q}];return M({ok:!0,serviceId:T.id,guidance:cl(T,ie)})}if(W.pathname==="/api/data-services/action"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De),q=String(T.action??"");if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!Bu.includes(q))return M({ok:!1,error:`Action must be one of: ${Bu.join(", ")}.`},422);let G=T.changes&&typeof T.changes==="object"&&!Array.isArray(T.changes)?T.changes:{};try{let Z=Tc.plan(D,q,G);if(T.execute!==!0)return M({ok:!0,plan:Z,productionExecutionCreated:!1});let Q=Tc.enqueue(D,q,G,Xe(Se).actor?.id);return M({ok:!0,plan:Z,operationId:Q},202)}catch(Z){return M({ok:!1,error:Z instanceof Error?Z.message:String(Z)},409)}}if(W.pathname==="/api/data-services/dependencies"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De),q=E.store.getResource(String(T.resourceId??""));if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!q||q.projectId!==E.project.id||q.environmentId!==U?.id)return M({ok:!1,error:"Dependent resource was not found in this environment."},404);if(T.remove===!0)return M({ok:lr.removeDependency(D.id,q.id)});return lr.addDependency({serviceId:D.id,resourceId:q.id,secretRef:D.credentialRef??`secret://data-services/${D.projectId}/${D.name}`,requiresRedeploy:T.requiresRedeploy!==!1}),M({ok:!0,dependencies:lr.dependencies(D.id).map((G)=>({resourceId:G.resourceId,requiresRedeploy:G.requiresRedeploy}))})}if(W.pathname==="/api/data-services/management"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De);if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(D.origin!=="adopted"||T.reviewed!==!0||T.confirm!==D.name)return M({ok:!1,error:`Enabling management requires reviewed=true and typing ${D.name}.`},409);return M({ok:!0,service:lr.update(D.id,D.version,{managementEnabled:!0})})}if(W.pathname==="/api/data-services/reveal"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De),q=D?lr.credential(D.id):void 0;if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!q)return M({ok:!1,error:"No managed credential is configured."},404);return M({ok:!0,credential:{username:q.username,password:await mi.resolve(q.secretRef),version:q.version}},200,{"cache-control":"no-store"})}if(W.pathname==="/api/databases"&&L.method==="GET")return M(await lb(h,De));if(W.pathname==="/api/databases"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim();if(!Yi(D))return M({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return M({...await ub(h,De,D),name:D})}if(W.pathname==="/api/databases/vitess"&&L.method==="GET"){let T=await fb(h,De);return M({...T,unhealthy:hb(T.tablets),missingPrimary:yb(T)})}if(W.pathname==="/api/databases/vitess/provision"&&L.method==="POST"){let T=await se(L);try{return M(await Ab(h,De,{keyspace:String(T.keyspace??""),username:String(T.username??""),password:String(T.password??""),sharded:T.sharded===!0,confirm:String(T.confirm??"")}))}catch(D){return M({ok:!1,error:D instanceof Error?D.message:String(D)},422)}}if(W.pathname==="/api/databases/vitess/migrations"&&L.method==="GET"){let T=W.searchParams.get("keyspace")??void 0;return M(await Eb(h,De,T))}if(W.pathname==="/api/databases/vitess/migrations/action"&&L.method==="POST"){let T=await se(L),D=String(T.uuid??"").trim(),U=String(T.action??"");if(!["retry","cancel","cleanup","complete"].includes(U))return M({ok:!1,error:"Unknown migration action."},422);return M(await Rb(h,De,D,U))}if(W.pathname==="/api/databases/vitess/keyspaces"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim(),U=T.sharded===!0;return M(await wb(h,De,D,{sharded:U}))}if(W.pathname==="/api/databases/vitess/vschema"&&L.method==="POST"){let T=await se(L),D=String(T.keyspace??"").trim(),U=typeof T.vschema==="string"?T.vschema:JSON.stringify(T.vschema??null);return M(await kb(h,De,D,U))}if(W.pathname==="/api/databases/vitess/schema"&&L.method==="POST"){let T=await se(L),D=String(T.sql??"");return M(await Ib(h,De,D))}if(W.pathname==="/api/databases/vitess/install-client"&&L.method==="POST")return M(await Sb(h,De));if(W.pathname==="/api/databases/backups"&&L.method==="GET")return M(await gb(h,De));if(W.pathname==="/api/databases/backup"&&L.method==="POST"){let T=await se(L),D=String(T.database??"").trim();if(!Yi(D))return M({ok:!1,error:"Database name must be a valid identifier."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to back up this database.`},409);return M(await mb(h,De,D))}if(W.pathname==="/api/databases/users"&&L.method==="POST"){let T=await se(L),D=String(T.username??"").trim(),U=String(T.password??""),q=String(T.database??"").trim()||void 0,G=T.access==="readonly"?"readonly":"all";if(!Yi(D))return M({ok:!1,error:"Username must be a valid identifier."},422);if(!U)return M({ok:!1,error:"Password is required."},422);if(q&&!Yi(q))return M({ok:!1,error:"Database must be a valid identifier."},422);return M({...await pb(h,De,{username:D,password:U,database:q,access:G}),username:D})}if(W.pathname==="/api/dashboard-data")return ur=H.get(De)??await Ce(De),Ce(De),M(Tg(ur,{user:jn,slug:h.project.slug}));if(W.pathname==="/api/users"&&L.method==="GET")return M({ok:!0,users:En(t).map(Wa)});if(W.pathname==="/api/users"&&L.method==="POST"){let T=await se(L),D=String(T.username??"").trim();if(!Tu(D))return M({ok:!1,error:"Username must be 2-32 characters: letters, numbers, dot, dash or underscore."},422);let U=T.sites&&typeof T.sites==="object"?T.sites:{},q=new Set(Object.keys(h.sites??{})),G={};for(let[ie,Ae]of Object.entries(U)){if(!q.has(ie))return M({ok:!1,error:`Site '${ie}' was not found.`},404);if(Ae!=="owner"&&Ae!=="collaborator")return M({ok:!1,error:`Unknown site role '${Ae}'. Use 'owner' or 'collaborator'.`},422);G[ie]=Ae}let Z=typeof T.password==="string"&&T.password.trim()?T.password.trim():void 0;if(Z&&Z.length<12)return M({ok:!1,error:"Password must be at least 12 characters."},422);let Q=wc(t,{username:D,password:Z,name:typeof T.name==="string"?T.name:void 0,sites:G});return Oi(E,En(t)),st(),M({ok:!0,user:Wa(Q.user),password:Q.password})}if(W.pathname==="/api/users"&&L.method==="DELETE"){let T=await se(L),D=String(T.username??"").trim();if(D.toLowerCase()===Se.username.toLowerCase())return M({ok:!1,error:"You cannot remove your own account."},409);let U=Un(En(t),D),q=U?E.store.getActorByExternalId("user",`dashboard:${U.username.toLowerCase()}`):void 0,G=q?E.store.getMembershipForActor(E.organization.id,q.id):void 0;if(G&&G.source!=="legacy")return M({ok:!1,error:"Organization members must be removed from Organization access."},409);let Z=Cg(t,D);if(!Z.ok)return M(Z,409);return Oi(E,En(t)),me.clear(),M({ok:!0,username:D})}if(W.pathname==="/api/actions/run"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=T.action?Ui(T.action,De):void 0;if(!D)return M({ok:!1,error:"Unknown dashboard action."},404);if(D.mutates&&T.confirm!==D.confirm)return M({ok:!1,error:`Type "${D.confirm}" to run this action.`},409);let U=await we({controlPlane:E,environment:De,actor:Se,kind:`dashboard.action.${D.id}`,input:{action:D.id},execute:()=>Hg(D,{cwd:t,cliEntry:m})});return M({...U.result,controlPlaneOperation:U.operation})}if(W.pathname==="/api/server/operations/run"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=T.operation?_g(T.operation,h,ur):void 0;if(!D)return M({ok:!1,error:"Unknown or unavailable server operation."},404);if(D.mutates&&T.confirm!==D.confirm)return M({ok:!1,error:`Type "${D.confirm}" to run this operation.`},409);let U=ee(E,String(De));await new ut(bt).run(new Qr,{...U,artifactRoot:t});let q=Pi(bt,{scope:U,desiredConfigHash:E.project.desiredConfigHash});if(q.decision.outcome==="block")return M({ok:!1,error:`Operation blocked by security policy: ${q.decision.explanation}`,securityReview:q},409);let G=await we({controlPlane:E,environment:De,actor:Se,kind:`dashboard.server.${D.id}`,resourceSlug:D.target,input:{operation:D.id,target:D.target,to:T.to??null},execute:()=>$u(h,De,D,{to:T.to})});return M({...G.result,controlPlaneOperation:G.operation,securityReview:q})}if(W.pathname==="/api/server/command"&&L.method==="POST"){let T=await L.json().catch(()=>({}));if(T.confirm!=="run")return M({ok:!1,error:'Type "run" to execute this command on the server.'},409);let D=await we({controlPlane:E,environment:De,actor:Se,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>kc(h,De,String(T.command??""))});return M({...D.result,controlPlaneOperation:D.operation})}if(W.pathname==="/api/serverless/operations")return M(Ng(h,De,ur));if(W.pathname==="/api/serverless/operations/run"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=T.operation?oS(T.operation,h,De,ur):void 0;if(!D)return M({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(D.mutates&&T.confirm!==D.confirm)return M({ok:!1,error:`Type "${D.confirm}" to run this operation.`},409);let U=await we({controlPlane:E,environment:De,actor:Se,kind:`dashboard.serverless.${D.id}`,input:{operation:D.id,min:T.min??null,max:T.max??null},execute:()=>sS(h,De,D,{min:T.min,max:T.max})});return ur=await Ks(h,De),H.set(De,ur),M({...U.result,controlPlaneOperation:U.operation})}if(W.pathname==="/api/serverless/command"&&L.method==="POST"){let T=await L.json().catch(()=>({}));if(T.confirm!=="run")return M({ok:!1,error:'Type "run" to execute this command.'},409);return M(await aS(h,De,String(T.command??"")))}if(W.pathname==="/api/serverless/dlq"&&L.method==="GET"){let T=Number(W.searchParams.get("max"))||10;return M(await cS(h,De,T))}if(W.pathname==="/api/serverless/dlq/redrive"&&L.method==="POST"){let T=await L.json().catch(()=>({}));if(T.confirm!=="redrive")return M({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return M(await dS(h,De,{max:T.max,targetQueue:T.targetQueue}))}if(W.pathname==="/api/serverless/dlq/purge"&&L.method==="POST"){if((await L.json().catch(()=>({}))).confirm!=="purge")return M({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return M(await lS(h,De))}if(W.pathname==="/api/serverless/secrets"&&L.method==="GET")return M({secrets:uS(h,De)});if(W.pathname==="/api/serverless/secrets"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.secretId??"").trim();if(!D)return M({ok:!1,error:"A secret id is required."},422);if(typeof T.value!=="string"||T.value==="")return M({ok:!1,error:"A non-empty value is required."},422);return M(await pS(h,De,D,T.value))}if(W.pathname==="/api/serverless/secrets"&&L.method==="DELETE"){let T=await L.json().catch(()=>({})),D=String(T.secretId??"").trim();if(!D)return M({ok:!1,error:"A secret id is required."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to delete this secret.`},409);return M(await mS(h,De,D))}if(W.pathname==="/api/serverless/functions/config"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.mode??"").trim();if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to update this function.`},409);return M(await gS(h,De,D,{memory:T.memory,timeout:T.timeout}))}if(W.pathname==="/api/serverless/alarms"&&L.method==="GET")return M(await fS(h,De));if(W.pathname==="/api/serverless/alarms"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.preset??"").trim(),U=Number(T.threshold);if(!D)return M({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(U))return M({ok:!1,error:"A numeric threshold is required."},422);return M(await hS(h,De,D,U))}if(W.pathname==="/api/serverless/alarms"&&L.method==="DELETE"){let T=await L.json().catch(()=>({})),D=String(T.name??"").trim();if(!D)return M({ok:!1,error:"An alarm name is required."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to delete this alarm.`},409);return M(await yS(h,De,D))}if(W.pathname==="/api/serverless/traces"&&L.method==="GET"){let T=Number(W.searchParams.get("minutes"))||30;return M(await ju(h,De,T))}if(W.pathname==="/api/serverless/scheduler"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.action??"").trim();if(D!=="enable"&&D!=="disable"&&D!=="run")return M({ok:!1,error:"Unknown scheduler action."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to ${D} the scheduler.`},409);return M(await Lg(h,De,D))}if(!OS(W.pathname,jn))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(De)}`}});let ma=await dr(Se,De);if(!ma)return Fu("ts-cloud dashboard UI is unavailable.",503);return $S(ma,W.pathname)}catch(bs){if(e.verbose)console.error(bs);return M({ok:!1,error:bs?.message??String(bs)},500)}})();if(!kr)return kr;if(Tt&&(W.pathname.startsWith("/api/")||W.pathname.startsWith("/auth/"))){let dt;if((He.headers.get("content-type")||"").includes("application/json"))dt=await He.json().catch(()=>{return});let nn=gr.resolveUser(L),Dr=nn?Xe(nn).actor:void 0;E.store.appendEvent({organizationId:E.organization.id,projectId:E.project.id,actorId:Dr?.id,correlationId:it,type:kr.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:kr.status<400?"info":"warning",payload:L_(L.method,W.pathname,dt,kr.status,Date.now()-Ze)})}return kr.headers.set("x-request-id",it),kr}});xc?.start();let GS=e.spendLoop??!0,vf;if(GS)(async()=>{let{SpendRunner:L,SpendLoopLease:Qe,startSpendLoop:Ze}=await import("./spend/index.js"),{store:He}=await jS(E.store),it=new L({controlPlane:E.store,store:He,alerts:ct});vf=Ze(it,{lease:new Qe(E.store,{owner:`dashboard:${process.pid}`}),onError:(Tt)=>console.error(`[ts-cloud] spend cycle failed: ${Tt instanceof Error?Tt.message:String(Tt)}`)})})();let QS=Zs.stop.bind(Zs);return Zs.stop=(L)=>{clearInterval(gf),clearInterval(ff),clearInterval(hf),clearInterval(mf),clearInterval(pf),clearInterval(cf),clearInterval(df),clearInterval(lf),clearInterval(uf),st(),Rr.clear(),xc?.stop(),vf?.();let Qe=QS(L);if(xc)xc.settled().finally(()=>E.store.close());else E.store.close();return Qe},{server:Zs,url:`http://${r}:${Zs.port}/`}}export{co,qg,wd,pA,Ci,Rd,lo,Vg,jg,Or,uo,Dd,Ge,Pd,Nd,kd,bi,Lr,zg,qe,Bd,po,go,mo,xd,_d,Od,Ei,ho,Ld,$r,vi,fo,lt,Kg,$d,Md,Wg,Fd,Ao,qt,Ud,Qd,Hd,Gd,Ve,Jg,qd,Vt,yo,Io,So,Ti,wi,Mr,Vd,Ri,Co,bo,Fr,jd,Ur,Xg,Yg,ut,Qr,Eo,Zg,zd,Kd,vo,Wd,Jd,Xd,gA,ee,Yd,mA,hA,Di,Pi,fA,de,em,pt,ve,Te,gt,Zd,el,tl,rl,tm,rm,To,nm,im,wo,nl,il,sm,te,om,sl,le,Ro,je,mt,ht,Hr,Ni,ol,AA,Do,am,cm,dm,lm,Po,No,al,Gr,ko,cl,ki,dl,Bo,xo,_o,Oo,Lo,$o,Mo,Fo,ll,jt,Uo,ul,qr,pl,Qo,Ho,gl,zt,Go,qo,um,yA,Bi,IA,SA,CA,Vo,jo,ml,pm,zo,Vr,hl,xi,fl,Al,yl,Ko,gm,Wo,Il,mm,Jo,hm,jr,zr,Sl,_i,Cl,bl,El,Xo,vl,Tl,fm,wl,S,Rl,Oi,we,Dl,Pl,bA,Nl,Am,EA,vA,TA,ym,Im,wA,RA,Sm,Cm,DA,Li,Kt,Yo,Kr,Wr,Wt,ze,ft,$i,bm,Jr,kl,Bl,Zo,Em,ea,vm,Tm,xl,ta,Mi,_l,ra,At,Re,Ol,na,ia,Ll,sa,oa,aa,ca,$l,Ml,Xr,da,la,ua,pa,Fl,Fi,Yr,Ui,ga};
708
+ `))},5000),yt.unref?.(),L.signal.addEventListener("abort",io,{once:!0})},cancel(){if(Et=!0,yt)clearInterval(yt)}});return new Response(Tn,{headers:{"cache-control":"no-cache, no-transform",connection:"keep-alive","content-type":"text/event-stream; charset=utf-8","x-accel-buffering":"no"}})}if(W.pathname==="/api/telemetry/series"&&L.method==="GET"){ke(!1);let Oe=ot(),et=["sum","avg","min","max","count","p50","p90","p95","p99"].includes(String(Ae.aggregation))?Ae.aggregation:"avg",$e=ie({...Ae,kinds:"metric",limit:5000}),Qe=D.series({...$e,bucketMs:Number(Ae.bucketMs)||60000,aggregation:et,timezone:String(Ae.timezone??"UTC"),compareFrom:Ae.compareFrom,compareTo:Ae.compareTo});return M({ok:!0,collection:{generatedAt:Oe.generatedAt,cached:Oe.cached},query:{aggregation:et,bucketMs:Number(Ae.bucketMs)||60000,timezone:String(Ae.timezone??"UTC")},series:Qe})}if(W.pathname==="/api/telemetry/refresh"&&L.method==="POST")return M({ok:!0,...await ke(!0)});if(W.pathname==="/api/telemetry/export"&&L.method==="POST"){let Oe=await se(L);await ke(!1);let et=D.query({...ie(Oe),limit:Math.min(5000,Number(Oe.limit)||5000),cursor:void 0});if((Oe.format==="csv"?"csv":"json")==="json")return new Response(JSON.stringify({exportedAt:new Date().toISOString(),query:ie(Oe),...et},null,2),{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.json"',"content-type":"application/json; charset=utf-8"}});let Qe=["timestamp","kind","source","name","level","value","unit","message","traceId","requestId","deploymentId","releaseId","workloadId"],yt=[Qe.join(","),...et.records.map((Et)=>Qe.map((Qt)=>`"${String(Et[Qt]??"").replaceAll('"','""')}"`).join(","))].join(`
709
+ `);return new Response(yt,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(W.pathname==="/api/telemetry/saved-queries"&&L.method==="GET"){let Oe=Ze(Se);return M({ok:!0,queries:D.listSavedQueries(E.project.id,Oe.actor?.id)})}if(W.pathname==="/api/telemetry/saved-queries"&&L.method==="POST"){let Oe=await se(L),et=Ze(Se);return M({ok:!0,query:D.saveQuery(E.project.id,et.actor?.id,String(Oe.name??""),ie(Oe.query??Oe))},201)}if(W.pathname==="/api/telemetry/saved-queries"&&L.method==="DELETE"){let Oe=await se(L),et=Ze(Se),$e=D.deleteSavedQuery(E.project.id,et.actor?.id,String(Oe.id??""));return M({ok:$e},$e?200:404)}}if(W.pathname.startsWith("/api/configuration")){let T=E.environments.get(De),D=Se.role==="admin"||!!jn.capabilities?.includes("secrets:read"),U=Se.role==="admin"||!!jn.capabilities?.includes("secrets:write"),q={projectId:E.project.id,environmentId:T?.id},G={"cache-control":"no-store"};if(W.pathname==="/api/configuration"&&L.method==="GET"){let Z=Object.fromEntries(W.searchParams),Q=Z.scopeType||Z.scopeId?Ka(Z,q):void 0,ie=["variable","secret"].includes(String(Z.kind))?Z.kind:void 0,Ae=Q?.type==="preview"?wr.previews.getInstance(Q.id):void 0,ke=Ae?wr.previews.getDefinition(Ae.definitionId):void 0,ot=Q?await Rn.resolve({projectId:E.project.id,environmentId:Q.environmentId,resourceId:Q.resourceId,functionId:Q.type==="function"?Q.id:void 0,previewId:Q.previewId,trustedPreview:!!Ae&&!Ae.fork,allowedPreviewSecrets:ke?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:D}):void 0,Oe=E.store.listResources(E.project.id);return M({ok:!0,entries:Rn.list({projectId:E.project.id,scope:Q,kind:ie,search:Z.search,canReadSecretMetadata:D}),effectiveEntries:ot?Object.values(ot.entries).filter((et)=>!ie||et.kind===ie).filter((et)=>!Z.search||et.key.toLowerCase().includes(String(Z.search).toLowerCase())):[],configurationHash:ot?.configurationHash,warnings:ot?.warnings??[],scopes:{project:E.project,environments:E.store.listEnvironments(E.project.id),resources:Oe.filter((et)=>et.kind!=="function"),functions:Oe.filter((et)=>et.kind==="function"),previews:wr.previews.listInstances({projectId:E.project.id}).filter((et)=>et.status!=="destroyed").map((et)=>({id:et.id,name:et.name,environmentId:et.baseEnvironmentId,resourceId:et.resourceId,fork:et.fork,status:et.status}))}},200,G)}if(W.pathname==="/api/configuration/export"&&L.method==="GET"){let Z=Ka(Object.fromEntries(W.searchParams),q);return new Response(Rn.exportVariables({projectId:E.project.id,scope:Z}),{headers:{...G,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(W.pathname==="/api/configuration/plan"&&L.method==="POST"){let Z=await se(L),Q=Ka(Z,q),ie=Z.values&&typeof Z.values==="object"&&!Array.isArray(Z.values)?Object.fromEntries(Object.entries(Z.values).map(([Ae,ke])=>[Ae,String(ke)])):{};return M({ok:!0,plan:Rn.plan({projectId:E.project.id,scope:Q,values:ie,removeMissing:Z.removeMissing===!0})},200,G)}if(W.pathname==="/api/configuration"&&L.method==="POST"){let Z=await se(L),Q=Ka(Z,q),ie=Z.kind==="secret"?"secret":"variable",Ae=String(Z.key??"");if(ie==="secret"&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);try{let ke=await Rn.set({organizationId:E.organization.id,projectId:E.project.id,scope:Q,key:Ae,kind:ie,value:Z.value==null?void 0:String(Z.value),reference:Z.reference==null?void 0:String(Z.reference),backend:Z.backend,required:Z.required===!0,expectedVersion:Z.expectedVersion==null?void 0:Number(Z.expectedVersion),confirmed:String(Z.confirm??"")===Ae,idempotencyKey:L.headers.get("idempotency-key")??Z.idempotencyKey,actorId:Ze(Se).actor?.id});return M({ok:!0,entry:Rn.list({projectId:E.project.id,scope:Q,canReadSecretMetadata:D}).find((ot)=>ot.id===ke.entry.id),mutation:ke.mutation,warnings:ke.warnings},ke.mutation.added.length?201:200,G)}catch(ke){return M({ok:!1,error:ke instanceof Error?ke.message:String(ke)},409,G)}}if(W.pathname==="/api/configuration/import"&&L.method==="POST"){let Z=await se(L),Q=Ka(Z,q),ie=Array.isArray(Z.secretKeys)?Z.secretKeys.map(String):[];if(ie.length&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);try{let Ae=await Rn.importDotenv({organizationId:E.organization.id,projectId:E.project.id,scope:Q,source:String(Z.source??""),secretKeys:ie,backend:Z.backend,confirmed:Z.confirm==="import",idempotencyKey:L.headers.get("idempotency-key")??Z.idempotencyKey,actorId:Ze(Se).actor?.id});return M({ok:Ae.document.valid,diagnostics:Ae.document.diagnostics,mutation:Ae.mutation,warnings:Ae.warnings},Ae.document.valid?200:422,G)}catch(Ae){return M({ok:!1,error:Ae instanceof Error?Ae.message:String(Ae)},409,G)}}if(W.pathname==="/api/configuration/dependencies"&&L.method==="POST"){let Z=await se(L),Q=Xi.get(String(Z.entryId??"")),ie=E.store.getResource(String(Z.resourceId??""));if(!Q||Q.projectId!==E.project.id||!ie||ie.projectId!==E.project.id)return M({ok:!1,error:"Configuration entry or dependent resource was not found."},404,G);return M({ok:!0,dependency:Xi.setDependency({entryId:Q.id,resourceId:ie.id,injectionTarget:["native_reference","file"].includes(String(Z.injectionTarget))?Z.injectionTarget:"environment",required:Z.required!==!1,requiresRedeploy:Z.requiresRedeploy!==!1,lastDeployedVersion:Z.lastDeployedVersion==null?void 0:Number(Z.lastDeployedVersion)})},200,G)}if(W.pathname==="/api/configuration/transfer"&&L.method==="POST"){let Z=await se(L),Q=Xi.get(String(Z.id??"")),ie=Ka({...Z,scopeType:Z.targetScopeType,scopeId:Z.targetScopeId},q);if(!Q||Q.projectId!==E.project.id)return M({ok:!1,error:"Configuration entry was not found."},404,G);if(Q.kind==="secret"&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);try{let Ae=await Rn.transfer({entryId:Q.id,targetScope:ie,mode:Z.mode==="move"?"move":"copy",confirmed:Z.confirm===Q.key,actorId:Ze(Se).actor?.id,idempotencyKey:L.headers.get("idempotency-key")??Z.idempotencyKey});return M({ok:!0,entry:Rn.list({projectId:E.project.id,scope:ie,canReadSecretMetadata:D}).find((ke)=>ke.id===Ae.entry.id),mutation:Ae.mutation},200,G)}catch(Ae){return M({ok:!1,error:Ae instanceof Error?Ae.message:String(Ae)},409,G)}}if(W.pathname==="/api/configuration/bulk"&&L.method==="POST"){let Z=await se(L),Q=Array.isArray(Z.ids)?Z.ids.map(String).slice(0,500):[],ie=Q.map((ke)=>Xi.get(ke)).filter((ke)=>!!ke&&ke.projectId===E.project.id);if(ie.length!==Q.length)return M({ok:!1,error:"One or more configuration entries were not found."},404,G);if(ie.some((ke)=>ke.kind==="secret")&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);if(Z.action!=="delete"||Z.confirm!=="bulk")return M({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,G);let Ae=[];try{for(let ke of ie)Ae.push(await Rn.remove({entryId:ke.id,expectedVersion:ke.version,confirmed:!0,actorId:Ze(Se).actor?.id}));return M({ok:!0,removed:Ae.flatMap((ke)=>ke.removed),affectedResourceIds:[...new Set(Ae.flatMap((ke)=>ke.affectedResourceIds))].sort()},200,G)}catch(ke){return M({ok:!1,error:ke instanceof Error?ke.message:String(ke),partial:Ae.flatMap((ot)=>ot.removed)},409,G)}}if(W.pathname==="/api/configuration/reveal"&&L.method==="POST"){let Z=await se(L),Q=gr.resolveSession(L);try{return M({ok:!0,value:await Rn.reveal({entryId:String(Z.id??""),canRevealSecrets:D,recentlyAuthenticated:!Ne||!!Q&&Le.isRecentlyAuthenticated(Q),actorId:Ze(Se).actor?.id})},200,G)}catch(ie){return M({ok:!1,error:ie instanceof Error?ie.message:String(ie)},403,G)}}if(W.pathname==="/api/configuration"&&L.method==="DELETE"){let Z=await se(L),Q=Xi.get(String(Z.id??""));if(Q?.kind==="secret"&&!U)return M({ok:!1,error:"Secret write permission is required."},403,G);if(!Q||Q.projectId!==E.project.id)return M({ok:!1,error:"Configuration entry was not found."},404,G);try{return M({ok:!0,mutation:await Rn.remove({entryId:Q.id,expectedVersion:Number(Z.expectedVersion),confirmed:String(Z.confirm??"")===Q.key,actorId:Ze(Se).actor?.id})},200,G)}catch(ie){return M({ok:!1,error:ie instanceof Error?ie.message:String(ie)},409,G)}}}if(W.pathname.startsWith("/api/fleet")){let T=Ze(Se).actor?.id,D=(U,q=409)=>M({ok:!1,error:U instanceof Error?U.message:String(U)},q,{"cache-control":"no-store"});if(W.pathname==="/api/fleet"&&L.method==="GET")return M({ok:!0,servers:Qa.list(E.project.id),resources:E.store.listResources(E.project.id),operations:nr.list({projectId:E.project.id,limit:200}).filter((U)=>U.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(W.pathname==="/api/fleet"&&L.method==="POST"){let U=await se(L);try{return M({ok:!0,server:ti.enroll({organizationId:E.organization.id,projectId:E.project.id,name:String(U.name??""),provider:["aws","hetzner"].includes(String(U.provider))?U.provider:"ssh",providerId:U.providerId?String(U.providerId):void 0,region:U.region?String(U.region):void 0,zone:U.zone?String(U.zone):void 0,endpoint:String(U.endpoint??""),sshUser:String(U.sshUser??"deploy"),sshPort:U.sshPort?Number(U.sshPort):22,credentialRef:String(U.credentialRef??""),roles:Array.isArray(U.roles)?U.roles:[],labels:U.labels&&typeof U.labels==="object"?U.labels:{}})},201)}catch(q){return D(q,422)}}if(W.pathname==="/api/fleet/action"&&L.method==="POST"){let U=await se(L),q=String(U.id??""),G=String(U.action??"");try{if(G==="test")return M({ok:!0,server:await ti.test(q)});if(G==="validate")return M({ok:!0,server:await ti.validate(q)});if(G==="review_host_key")return M({ok:!0,server:ti.reviewHostKey(q,String(U.fingerprint??""))});if(G==="bootstrap")return M({ok:!0,...ti.bootstrap(q,U.confirmed===!0)},U.confirmed===!0?202:200);if(G==="heartbeat")return M({ok:!0,server:ti.heartbeat(q,{usage:U.usage&&typeof U.usage==="object"?U.usage:{}})});if(G==="drain")return M({ok:!0,server:ti.drain(q,U.completed===!0)});if(G==="uncordon")return M({ok:!0,server:ti.uncordon(q)});if(G==="archive")return M({ok:!0,server:ti.archive(q,String(U.confirmation??""))});return D("Unsupported fleet action.",422)}catch(Z){return D(Z)}}}if(W.pathname.startsWith("/api/capacity")){let T=(D,U=409)=>M({ok:!1,error:D instanceof Error?D.message:String(D)},U,{"cache-control":"no-store"});if(W.pathname==="/api/capacity"&&L.method==="GET")return M({ok:!0,pools:to.listPools(E.project.id),placements:to.listPlacements(E.project.id),servers:Qa.list(E.project.id)},200,{"cache-control":"no-store"});if(W.pathname==="/api/capacity"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,pool:to.createPool({organizationId:E.organization.id,projectId:E.project.id,name:String(D.name??""),purpose:String(D.purpose??"application"),backend:String(D.backend??"server"),region:D.region?String(D.region):void 0,architecture:D.architecture?String(D.architecture):void 0,labels:D.labels&&typeof D.labels==="object"?D.labels:{},requiredServerLabels:D.requiredServerLabels&&typeof D.requiredServerLabels==="object"?D.requiredServerLabels:{},toleratedTaints:Array.isArray(D.toleratedTaints)?D.toleratedTaints.map(String):[],capacity:D.capacity&&typeof D.capacity==="object"?D.capacity:{},maxWorkloads:Number(D.maxWorkloads??10),costWeight:Number(D.costWeight??1),spreadKey:D.spreadKey?String(D.spreadKey):void 0,concurrency:Number(D.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/capacity/member"&&L.method==="POST"){let D=await se(L);try{return to.addMember(String(D.poolId??""),String(D.serverId??"")),M({ok:!0,pool:to.getPool(String(D.poolId??""))})}catch(U){return T(U,422)}}if(W.pathname==="/api/capacity/explain"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,decisions:rf.explain(E.project.id,{purpose:String(D.purpose??"application"),resources:D.resources&&typeof D.resources==="object"?D.resources:{},region:D.region?String(D.region):void 0,architecture:D.architecture?String(D.architecture):void 0,labels:D.labels&&typeof D.labels==="object"?D.labels:{}})})}catch(U){return T(U,422)}}if(W.pathname==="/api/capacity/action"&&L.method==="POST"){let D=await se(L);try{if(D.action==="drain")return M({ok:!0,...rf.drainPool(String(D.poolId??""))});if(D.action==="enable")return M({ok:!0,pool:to.updatePool(String(D.poolId??""),{status:"active"})});if(D.action==="disable")return M({ok:!0,pool:to.updatePool(String(D.poolId??""),{status:"disabled"})});return T("Unsupported capacity action.",422)}catch(U){return T(U,422)}}}if(W.pathname.startsWith("/api/regions")){let T=(D,U=409)=>M({ok:!1,error:D instanceof Error?D.message:String(D)},U,{"cache-control":"no-store"});if(W.pathname==="/api/regions"&&L.method==="GET")return M({ok:!0,topologies:hs.list(E.project.id).map((D)=>({topology:D,targets:hs.targets(D.id),channels:hs.channels(D.id),route:hs.route(D.id),executions:hs.executions(D.id)}))},200,{"cache-control":"no-store"});if(W.pathname==="/api/regions"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,topology:nf.create({organizationId:E.organization.id,projectId:E.project.id,environmentId:E.environments.get(De)?.id,name:String(D.name??""),hostname:String(D.hostname??""),regions:Array.isArray(D.regions)?D.regions:[],trafficPolicy:D.trafficPolicy==="weighted"||D.trafficPolicy==="latency"?D.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(D.replicate)?D.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(D.maxLagSeconds??30),retainOnDestroy:D.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:D.cdnEnabled===!0,wafEnabled:D.wafEnabled===!0})},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/regions/action"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,...nf.enqueue({topologyId:String(D.topologyId??""),kind:String(D.action??""),targetRegion:D.targetRegion?String(D.targetRegion):void 0,revision:D.revision?String(D.revision):void 0,manifest:D.manifest&&typeof D.manifest==="object"?D.manifest:{},confirmation:D.confirmation?String(D.confirmation):void 0,deleteData:D.deleteData===!0})},202)}catch(U){return T(U,422)}}}if(W.pathname.startsWith("/api/maintenance")){let T=(D,U=409)=>M({ok:!1,error:D instanceof Error?D.message:String(D)},U,{"cache-control":"no-store"});if(W.pathname==="/api/maintenance"&&L.method==="GET")return M({ok:!0,manifests:fi.manifests(E.organization.id),windows:fi.windows(E.project.id),campaigns:fi.campaigns(E.project.id).map((D)=>({campaign:D,targets:fi.targets(D.id)})),cleanups:fi.cleanups(E.project.id),drills:fi.drills(E.project.id)},200,{"cache-control":"no-store"});if(W.pathname==="/api/maintenance/cleanup-preview"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,plan:await Vu.previewCleanup({projectId:E.project.id,kind:String(D.kind??"operations"),criteria:{olderThanDays:Number(D.olderThanDays??30)}},of)},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/maintenance/cleanup-apply"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,...Vu.enqueueCleanup(String(D.planId??""),String(D.confirmation??""))},202)}catch(U){return T(U,422)}}if(W.pathname==="/api/maintenance/drill"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,drill:fi.createDrill({projectId:E.project.id,scenario:String(D.scenario??"control_plane"),isolatedTarget:String(D.isolatedTarget??""),expectedRpoMinutes:Number(D.expectedRpoMinutes??60),expectedRtoMinutes:Number(D.expectedRtoMinutes??30),recoveryPointId:D.recoveryPointId?String(D.recoveryPointId):void 0,topologyId:D.topologyId?String(D.topologyId):void 0})},201)}catch(U){return T(U,422)}}if(W.pathname==="/api/maintenance/drill-run"&&L.method==="POST"){let D=await se(L);try{return M({ok:!0,...Vu.enqueueDrill(String(D.drillId??""))},202)}catch(U){return T(U,422)}}}if(W.pathname.startsWith("/api/volumes")){let T=E.environments.get(De),D=Ze(Se).actor?.id,U=(q,G=409)=>M({ok:!1,error:q instanceof Error?q.message:String(q)},G,{"cache-control":"no-store"});if(W.pathname==="/api/volumes"&&L.method==="GET"){let q=Uu.inventory(E.project.id,T?.id),G=E.store.listResources(E.project.id,T?.id).map((Z)=>({id:Z.id,name:Z.name,slug:Z.slug,kind:Z.kind,provider:Z.provider,providerId:Z.providerId}));return M({ok:!0,volumes:q,resources:G,operations:nr.list({projectId:E.project.id,limit:100}).filter((Z)=>Z.operation.kind.startsWith("volume.")),recoveryPoints:Er.listRecoveryPoints(E.project.id).filter((Z)=>Z.kind==="volume"),providers:qu.map((Z)=>({provider:Z.provider,type:Z.type,capabilities:Z.capabilities()}))},200,{"cache-control":"no-store"})}if(W.pathname==="/api/volumes"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.create({organizationId:E.organization.id,projectId:E.project.id,environmentId:T?.id,resourceId:q.resourceId?String(q.resourceId):void 0,name:String(q.name??""),provider:String(q.provider??"docker"),type:q.type==="docker"?"docker":q.type,capacityBytes:q.capacityBytes==null?void 0:Number(q.capacityBytes),filesystem:q.filesystem?String(q.filesystem):void 0,encrypted:q.encrypted===!0,desiredState:q.desiredState&&typeof q.desiredState==="object"?q.desiredState:{},actorId:D})},202,{"cache-control":"no-store"})}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/attach"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.attach(String(q.volumeId??""),{resourceId:String(q.resourceId??""),targetPath:String(q.targetPath??""),readOnly:q.readOnly===!0,uid:q.uid==null?void 0:Number(q.uid),gid:q.gid==null?void 0:Number(q.gid),mode:q.mode?String(q.mode):void 0,propagation:q.propagation,driverOptions:q.driverOptions&&typeof q.driverOptions==="object"?q.driverOptions:{},actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/detach"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.detach(String(q.volumeId??""),String(q.attachmentId??""),{force:q.force===!0,drained:q.drained===!0,unmounted:q.unmounted===!0,confirmation:q.confirmation?String(q.confirmation):void 0,actorId:D})},202)}catch(G){return U(G)}}if(W.pathname==="/api/volumes/resize"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.resize(String(q.volumeId??""),Number(q.capacityBytes),{drained:q.drained===!0,actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/snapshot"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.snapshot(String(q.volumeId??""),{name:q.name?String(q.name):void 0,actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/restore"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,...gi.restore(String(q.snapshotId??""),{name:String(q.name??""),actorId:D})},202)}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes/discover"&&L.method==="POST")try{return M({ok:!0,volumes:await gi.discover({organizationId:E.organization.id,projectId:E.project.id,environmentId:T?.id,actorId:D})})}catch(q){return U(q,502)}if(W.pathname==="/api/volumes/adopt"&&L.method==="POST"){let q=await se(L);try{return M({ok:!0,volume:gi.adopt(String(q.volumeId??""),{name:String(q.name??""),actorId:D})})}catch(G){return U(G,422)}}if(W.pathname==="/api/volumes"&&L.method==="DELETE"){let q=await se(L),G=gr.resolveSession(L);try{return M({ok:!0,...gi.delete(String(q.volumeId??""),{recentAuthAt:!Ne||G&&Le.isRecentlyAuthenticated(G)?new Date().toISOString():void 0,confirmation:q.confirmation?String(q.confirmation):void 0,backupOverride:q.backupOverride===!0,backupOverrideConfirmation:q.backupOverrideConfirmation?String(q.backupOverrideConfirmation):void 0,actorId:D})},202)}catch(Z){return U(Z)}}}if(W.pathname==="/api/backups"&&L.method==="GET"){let T=E.environments.get(De),D=Er.listPolicies(E.project.id,T?.id),U=new Set(D.map((ie)=>ie.id)),q=Er.listRecoveryPoints(E.project.id).filter((ie)=>!ie.policyId||U.has(ie.policyId)),G=Er.listJobs(E.project.id).filter((ie)=>!ie.policyId||U.has(ie.policyId)),Z=(ie)=>({...ie,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!ie.credentialRef,clientEncryptionConfigured:!!ie.encryptionKeyRef}),Q=await Promise.all(Er.listDestinations(E.project.id).map(async(ie)=>({...Z(ie),credentialStatus:await xl(ie,mi)})));return M({ok:!0,destinations:Q,policies:D,recoveryPoints:q,jobs:G,coverage:Er.coverage(E.project.id).filter((ie)=>U.has(ie.policy.id)),resources:T?E.store.listResources(E.project.id,T.id).map((ie)=>({id:ie.id,name:ie.name,slug:ie.slug,kind:ie.kind})):[]})}if(W.pathname==="/api/backups/destinations"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim(),U=String(T.provider??""),q=String(T.encryption??"provider"),G=`secret://data-services/backups/${E.project.id}/${D}`,Z=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(U))return M({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(q))return M({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let Q,ie;if(T.credentials&&typeof T.credentials==="object"&&!Array.isArray(T.credentials))Q=`${G}/credentials`,await mi.put(Q,JSON.stringify(T.credentials)),Z.push(Q);if(q!=="provider"){let ke=String(T.encryptionKey??"");if(ke.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");ie=`${G}/encryption-key`,await mi.put(ie,ke),Z.push(ie)}let Ae=Er.createDestination({organizationId:E.organization.id,projectId:E.project.id,name:D,provider:U,endpoint:T.endpoint?String(T.endpoint):void 0,endpointPolicy:T.endpointPolicy==="allow_private"?"allow_private":"public_https",bucket:T.bucket?String(T.bucket):void 0,prefix:String(T.prefix??""),region:T.region?String(T.region):eo,forcePathStyle:T.forcePathStyle===!0,credentialRef:Q,encryption:q,encryptionKeyRef:ie,immutability:T.immutability&&typeof T.immutability==="object"&&!Array.isArray(T.immutability)?T.immutability:{},status:"untested"});return M({ok:!0,destination:{...Ae,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!Q,clientEncryptionConfigured:!!ie}},201)}catch(Q){for(let ie of Z)await mi.remove(ie).catch(()=>{});return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},422)}}if(W.pathname==="/api/backups/destinations/test"&&L.method==="POST"){let T=await se(L),D=Er.getDestination(String(T.id??""));if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Backup destination was not found."},404);if(D.provider==="aws_backup")return M({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await tf.test(D),M({ok:!0,destination:Er.recordDestinationTest(D.id,{ok:!0})})}catch(U){let q=U instanceof Error?U.message:String(U);return Er.recordDestinationTest(D.id,{ok:!1,error:q}),M({ok:!1,error:q},502)}}if(W.pathname==="/api/backups/policies"&&L.method==="POST"){let T=await se(L),D=E.environments.get(De),U=Er.getDestination(String(T.destinationId??"")),q=String(T.resourceKind??""),G=T.dataServiceId?String(T.dataServiceId):void 0,Z=G?lr.get(G):void 0,Q=T.resourceId?String(T.resourceId):void 0,ie=Q?E.store.getResource(Q):void 0;if(!D)return M({ok:!1,error:"Environment was not found."},404);if(!U||U.projectId!==E.project.id)return M({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(q))return M({ok:!1,error:"A supported backup resource kind is required."},422);if(G&&(!Z||Z.projectId!==E.project.id||Z.environmentId!==D.id))return M({ok:!1,error:"Data service was not found in this environment."},404);if(Q&&(!ie||ie.projectId!==E.project.id||ie.environmentId!==D.id))return M({ok:!1,error:"Resource was not found in this environment."},404);if(q==="managed_database"&&!Z)return M({ok:!1,error:"Managed database policies require a data service."},422);if(q==="logical_database"&&(!Z||!["container","server"].includes(Z.provider)))return M({ok:!1,error:"Logical database policies require an on-box data service."},422);if(q==="volume"&&(!ie||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(T.volumeName??""))))return M({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let Ae=Array.isArray(T.includePatterns)?T.includePatterns.map(String).filter(Boolean):[];if(q==="files"&&(!ie||!Ae.length))return M({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(q==="control_plane"&&U.encryption==="provider")return M({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(q==="infrastructure"&&(U.provider!=="aws_backup"||!Ae.some((ke)=>ke.startsWith("resource:arn:"))||!Ae.some((ke)=>ke.startsWith("role:arn:"))))return M({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let ke=Er.createPolicy({organizationId:E.organization.id,projectId:E.project.id,environmentId:D.id,resourceId:Q,dataServiceId:G,destinationId:U.id,name:String(T.name??"").trim(),resourceKind:q,schedule:String(T.schedule??"daily"),timezone:String(T.timezone??"UTC"),retention:T.retention&&typeof T.retention==="object"&&!Array.isArray(T.retention)?T.retention:{keepLast:7,expireAfterDays:30},compression:["none","gzip","zstd"].includes(String(T.compression))?T.compression:"gzip",encryption:["destination","client_side","both"].includes(String(T.encryption))?T.encryption:"destination",includePatterns:q==="volume"?[String(T.volumeName),...Ae]:Ae,excludePatterns:Array.isArray(T.excludePatterns)?T.excludePatterns.map(String):[],expectedRpoMinutes:Math.max(1,Number(T.expectedRpoMinutes)||1440),expectedRtoMinutes:Math.max(1,Number(T.expectedRtoMinutes)||120),healthCheckId:T.healthCheckId?String(T.healthCheckId):void 0,enabled:T.enabled!==!1});return M({ok:!0,policy:ke},201)}catch(ke){return M({ok:!1,error:ke instanceof Error?ke.message:String(ke)},422)}}if(W.pathname==="/api/backups/run"&&L.method==="POST"){let T=await se(L),D=Er.getPolicy(String(T.policyId??"")),U=E.environments.get(De);if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Backup policy was not found in this environment."},404);try{let q=fs.enqueueBackup(D,new Date().toISOString(),Ze(Se).actor?.id);return M({ok:!0,job:q},202)}catch(q){return M({ok:!1,error:q instanceof Error?q.message:String(q)},409)}}if(W.pathname==="/api/backups/verify"&&L.method==="POST"){let T=await se(L),D=Er.getRecoveryPoint(String(T.recoveryPointId??""));if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Recovery point was not found."},404);return M({ok:!0,job:fs.enqueueVerification(D)},202)}if(W.pathname==="/api/backups/restore"&&L.method==="POST"){let T=await se(L),D=Er.getRecoveryPoint(String(T.recoveryPointId??"")),U=T.mode==="in_place"?"in_place":"isolated",q=T.target&&typeof T.target==="object"&&!Array.isArray(T.target)?{...T.target,inPlace:U==="in_place"}:{inPlace:U==="in_place"},G=gr.resolveSession(L),Z={mode:U,target:q,targetName:String(T.targetName??""),confirm:T.confirm?String(T.confirm):void 0,recentAuth:!Ne||!!G&&Le.isRecentlyAuthenticated(G),downtimeAcknowledged:T.downtimeAcknowledged===!0,safetyBackupId:T.safetyBackupId?String(T.safetyBackupId):void 0};if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Recovery point was not found."},404);if(T.drill===!0&&U!=="isolated")return M({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let Q=fs.planRestore(D,Z);if(T.execute!==!0)return M({ok:!0,plan:Q,executionCreated:!1});let ie=fs.enqueueRestore(D,{...Z,drill:T.drill===!0,actorId:Ze(Se).actor?.id});return M({ok:!0,plan:Q,job:ie},202)}catch(Q){return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},409)}}if(W.pathname==="/api/backups/recovery-points"&&L.method==="POST"){let T=await se(L),D=Er.getRecoveryPoint(String(T.id??""));if(!D||D.projectId!==E.project.id)return M({ok:!1,error:"Recovery point was not found."},404);if(T.held==null&&T.pinned==null)return M({ok:!1,error:"held or pinned must be provided."},422);return M({ok:!0,recoveryPoint:Er.updateRecoveryPoint(D.id,{held:T.held==null?D.held:T.held===!0,pinned:T.pinned==null?D.pinned:T.pinned===!0})})}if(W.pathname==="/api/backups/retention"&&L.method==="POST")return M({ok:!0,jobs:fs.enqueueRetention()},202);if(W.pathname==="/api/data-services/capabilities"&&L.method==="GET"){let T=String(W.searchParams.get("engine")??""),D=String(W.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(T)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(D))return M({ok:!1,error:"A supported engine and provider are required."},422);return M({ok:!0,engine:T,provider:D,capabilities:Gr(T,D)})}if(W.pathname==="/api/data-services"&&L.method==="GET"){let T=E.environments.get(De),D=lr.list(E.project.id,T?.id).map((U)=>{let q=lr.credential(U.id);return{...U,credentialRef:void 0,credential:q?{configured:!0,username:q.username,version:q.version,rotatedAt:q.rotatedAt}:void 0,dependencies:lr.dependencies(U.id).map((G)=>({resourceId:G.resourceId,requiresRedeploy:G.requiresRedeploy}))}});return M({ok:!0,services:D})}if(W.pathname==="/api/data-services/preview"&&L.method==="POST"){let T=await se(L);if(T.id){let q=lr.get(String(T.id)),G=E.environments.get(De),Z=String(T.action??"");if(!q||q.projectId!==E.project.id||q.environmentId!==G?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!Bu.includes(Z))return M({ok:!1,error:`Action must be one of: ${Bu.join(", ")}.`},422);try{return M({ok:!0,plan:Tc.plan(q,Z,T.changes??{})})}catch(Q){return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},422)}}let D=String(T.engine??""),U=String(T.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(D)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(U))return M({ok:!1,error:"A supported engine and provider are required."},422);return M({ok:!0,capabilities:Gr(D,U),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(W.pathname==="/api/data-services"&&L.method==="POST"){let T=await se(L),D=String(T.engine??""),U=String(T.provider??""),q=E.environments.get(De),G=Ze(Se);if(!q)return M({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(D)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(U))return M({ok:!1,error:"A supported engine and provider are required."},422);let Z={organizationId:E.organization.id,projectId:E.project.id,environmentId:q.id,resourceId:T.resourceId?String(T.resourceId):void 0,name:String(T.name??"").trim(),engine:D,provider:U,placement:String(T.placement??T.name??"").trim(),engineVersion:T.engineVersion?String(T.engineVersion):void 0,plan:String(T.plan??(U==="aws_elasticache"?"cache.t4g.micro":U==="aws_aurora"?"db.serverless":"db.t4g.micro")),storageGb:T.storageGb==null?void 0:Number(T.storageGb),highAvailability:T.highAvailability===!0,publicExposure:T.publicExposure===!0,allowedCidrs:Array.isArray(T.allowedCidrs)?T.allowedCidrs.map(String):[],desiredState:T.desiredState&&typeof T.desiredState==="object"&&!Array.isArray(T.desiredState)?T.desiredState:{},observedState:{},origin:T.adopt===!0?"adopted":"managed",managementEnabled:T.adopt!==!0,ownerActorId:G.actor?.id,username:T.username?String(T.username):void 0};try{if(T.adopt===!0){let ie=lr.create({...Z,status:"adopted",credentialRef:void 0});return M({ok:!0,service:ie,readOnly:!0},201)}if(!ef({provider:U,engine:D}))return M({ok:!1,error:`No ${U}/${D} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let Q=await Tc.create(Z);return M({ok:!0,service:Q.service,operationId:Q.operationId,oneTimeCredential:Q.credential},201)}catch(Q){return M({ok:!1,error:Q instanceof Error?Q.message:String(Q)},422)}}if(W.pathname==="/api/data-services/connections"&&L.method==="GET"){let T=lr.get(String(W.searchParams.get("id")??"")),D=E.environments.get(De);if(!T||T.projectId!==E.project.id||T.environmentId!==D?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);let U=typeof T.observedState.endpoint==="string"?T.observedState.endpoint:void 0,q=typeof T.observedState.readerEndpoint==="string"?T.observedState.readerEndpoint:void 0,G=Number(T.observedState.port)||(T.engine==="postgres"?5432:T.engine==="redis"?6379:T.engine==="mongodb"?27017:T.engine==="libsql"?8080:3306),Z=typeof T.observedState.database==="string"?T.observedState.database:void 0,Q=typeof T.observedState.tls==="boolean"?T.observedState.tls:T.provider.startsWith("aws_"),ie=[...U?[{type:T.publicExposure?"external":"internal",host:U,port:G,database:Z,tls:Q}]:[],...q?[{type:"internal",host:q,port:G,database:Z,tls:Q}]:[],{type:"tunnel",host:U??T.placement,port:G,database:Z,tls:Q}];return M({ok:!0,serviceId:T.id,guidance:cl(T,ie)})}if(W.pathname==="/api/data-services/action"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De),q=String(T.action??"");if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!Bu.includes(q))return M({ok:!1,error:`Action must be one of: ${Bu.join(", ")}.`},422);let G=T.changes&&typeof T.changes==="object"&&!Array.isArray(T.changes)?T.changes:{};try{let Z=Tc.plan(D,q,G);if(T.execute!==!0)return M({ok:!0,plan:Z,productionExecutionCreated:!1});let Q=Tc.enqueue(D,q,G,Ze(Se).actor?.id);return M({ok:!0,plan:Z,operationId:Q},202)}catch(Z){return M({ok:!1,error:Z instanceof Error?Z.message:String(Z)},409)}}if(W.pathname==="/api/data-services/dependencies"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De),q=E.store.getResource(String(T.resourceId??""));if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!q||q.projectId!==E.project.id||q.environmentId!==U?.id)return M({ok:!1,error:"Dependent resource was not found in this environment."},404);if(T.remove===!0)return M({ok:lr.removeDependency(D.id,q.id)});return lr.addDependency({serviceId:D.id,resourceId:q.id,secretRef:D.credentialRef??`secret://data-services/${D.projectId}/${D.name}`,requiresRedeploy:T.requiresRedeploy!==!1}),M({ok:!0,dependencies:lr.dependencies(D.id).map((G)=>({resourceId:G.resourceId,requiresRedeploy:G.requiresRedeploy}))})}if(W.pathname==="/api/data-services/management"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De);if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(D.origin!=="adopted"||T.reviewed!==!0||T.confirm!==D.name)return M({ok:!1,error:`Enabling management requires reviewed=true and typing ${D.name}.`},409);return M({ok:!0,service:lr.update(D.id,D.version,{managementEnabled:!0})})}if(W.pathname==="/api/data-services/reveal"&&L.method==="POST"){let T=await se(L),D=lr.get(String(T.id??"")),U=E.environments.get(De),q=D?lr.credential(D.id):void 0;if(!D||D.projectId!==E.project.id||D.environmentId!==U?.id)return M({ok:!1,error:"Data service was not found in this environment."},404);if(!q)return M({ok:!1,error:"No managed credential is configured."},404);return M({ok:!0,credential:{username:q.username,password:await mi.resolve(q.secretRef),version:q.version}},200,{"cache-control":"no-store"})}if(W.pathname==="/api/databases"&&L.method==="GET")return M(await lb(h,De));if(W.pathname==="/api/databases"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim();if(!Yi(D))return M({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return M({...await ub(h,De,D),name:D})}if(W.pathname==="/api/databases/vitess"&&L.method==="GET"){let T=await fb(h,De);return M({...T,unhealthy:hb(T.tablets),missingPrimary:yb(T)})}if(W.pathname==="/api/databases/vitess/provision"&&L.method==="POST"){let T=await se(L);try{return M(await Ab(h,De,{keyspace:String(T.keyspace??""),username:String(T.username??""),password:String(T.password??""),sharded:T.sharded===!0,confirm:String(T.confirm??"")}))}catch(D){return M({ok:!1,error:D instanceof Error?D.message:String(D)},422)}}if(W.pathname==="/api/databases/vitess/migrations"&&L.method==="GET"){let T=W.searchParams.get("keyspace")??void 0;return M(await Eb(h,De,T))}if(W.pathname==="/api/databases/vitess/migrations/action"&&L.method==="POST"){let T=await se(L),D=String(T.uuid??"").trim(),U=String(T.action??"");if(!["retry","cancel","cleanup","complete"].includes(U))return M({ok:!1,error:"Unknown migration action."},422);return M(await Rb(h,De,D,U))}if(W.pathname==="/api/databases/vitess/keyspaces"&&L.method==="POST"){let T=await se(L),D=String(T.name??"").trim(),U=T.sharded===!0;return M(await wb(h,De,D,{sharded:U}))}if(W.pathname==="/api/databases/vitess/vschema"&&L.method==="POST"){let T=await se(L),D=String(T.keyspace??"").trim(),U=typeof T.vschema==="string"?T.vschema:JSON.stringify(T.vschema??null);return M(await kb(h,De,D,U))}if(W.pathname==="/api/databases/vitess/schema"&&L.method==="POST"){let T=await se(L),D=String(T.sql??"");return M(await Ib(h,De,D))}if(W.pathname==="/api/databases/vitess/install-client"&&L.method==="POST")return M(await Sb(h,De));if(W.pathname==="/api/databases/backups"&&L.method==="GET")return M(await gb(h,De));if(W.pathname==="/api/databases/backup"&&L.method==="POST"){let T=await se(L),D=String(T.database??"").trim();if(!Yi(D))return M({ok:!1,error:"Database name must be a valid identifier."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to back up this database.`},409);return M(await mb(h,De,D))}if(W.pathname==="/api/databases/users"&&L.method==="POST"){let T=await se(L),D=String(T.username??"").trim(),U=String(T.password??""),q=String(T.database??"").trim()||void 0,G=T.access==="readonly"?"readonly":"all";if(!Yi(D))return M({ok:!1,error:"Username must be a valid identifier."},422);if(!U)return M({ok:!1,error:"Password is required."},422);if(q&&!Yi(q))return M({ok:!1,error:"Database must be a valid identifier."},422);return M({...await pb(h,De,{username:D,password:U,database:q,access:G}),username:D})}if(W.pathname==="/api/dashboard-data")return ur=H.get(De)??await Ce(De),Ce(De),M(Tg(ur,{user:jn,slug:h.project.slug}));if(W.pathname==="/api/users"&&L.method==="GET")return M({ok:!0,users:En(t).map(Wa)});if(W.pathname==="/api/users"&&L.method==="POST"){let T=await se(L),D=String(T.username??"").trim();if(!Tu(D))return M({ok:!1,error:"Username must be 2-32 characters: letters, numbers, dot, dash or underscore."},422);let U=T.sites&&typeof T.sites==="object"?T.sites:{},q=new Set(Object.keys(h.sites??{})),G={};for(let[ie,Ae]of Object.entries(U)){if(!q.has(ie))return M({ok:!1,error:`Site '${ie}' was not found.`},404);if(Ae!=="owner"&&Ae!=="collaborator")return M({ok:!1,error:`Unknown site role '${Ae}'. Use 'owner' or 'collaborator'.`},422);G[ie]=Ae}let Z=typeof T.password==="string"&&T.password.trim()?T.password.trim():void 0;if(Z&&Z.length<12)return M({ok:!1,error:"Password must be at least 12 characters."},422);let Q=wc(t,{username:D,password:Z,name:typeof T.name==="string"?T.name:void 0,sites:G});return Oi(E,En(t)),st(),M({ok:!0,user:Wa(Q.user),password:Q.password})}if(W.pathname==="/api/users"&&L.method==="DELETE"){let T=await se(L),D=String(T.username??"").trim();if(D.toLowerCase()===Se.username.toLowerCase())return M({ok:!1,error:"You cannot remove your own account."},409);let U=Un(En(t),D),q=U?E.store.getActorByExternalId("user",`dashboard:${U.username.toLowerCase()}`):void 0,G=q?E.store.getMembershipForActor(E.organization.id,q.id):void 0;if(G&&G.source!=="legacy")return M({ok:!1,error:"Organization members must be removed from Organization access."},409);let Z=Cg(t,D);if(!Z.ok)return M(Z,409);return Oi(E,En(t)),me.clear(),M({ok:!0,username:D})}if(W.pathname==="/api/actions/run"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=T.action?Ui(T.action,De):void 0;if(!D)return M({ok:!1,error:"Unknown dashboard action."},404);if(D.mutates&&T.confirm!==D.confirm)return M({ok:!1,error:`Type "${D.confirm}" to run this action.`},409);let U=await we({controlPlane:E,environment:De,actor:Se,kind:`dashboard.action.${D.id}`,input:{action:D.id},execute:()=>Hg(D,{cwd:t,cliEntry:m})});return M({...U.result,controlPlaneOperation:U.operation})}if(W.pathname==="/api/server/operations/run"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=T.operation?_g(T.operation,h,ur):void 0;if(!D)return M({ok:!1,error:"Unknown or unavailable server operation."},404);if(D.mutates&&T.confirm!==D.confirm)return M({ok:!1,error:`Type "${D.confirm}" to run this operation.`},409);let U=ee(E,String(De));await new ut(bt).run(new Qr,{...U,artifactRoot:t});let q=Pi(bt,{scope:U,desiredConfigHash:E.project.desiredConfigHash});if(q.decision.outcome==="block")return M({ok:!1,error:`Operation blocked by security policy: ${q.decision.explanation}`,securityReview:q},409);let G=await we({controlPlane:E,environment:De,actor:Se,kind:`dashboard.server.${D.id}`,resourceSlug:D.target,input:{operation:D.id,target:D.target,to:T.to??null},execute:()=>$u(h,De,D,{to:T.to})});return M({...G.result,controlPlaneOperation:G.operation,securityReview:q})}if(W.pathname==="/api/server/command"&&L.method==="POST"){let T=await L.json().catch(()=>({}));if(T.confirm!=="run")return M({ok:!1,error:'Type "run" to execute this command on the server.'},409);let D=await we({controlPlane:E,environment:De,actor:Se,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>kc(h,De,String(T.command??""))});return M({...D.result,controlPlaneOperation:D.operation})}if(W.pathname==="/api/serverless/operations")return M(Ng(h,De,ur));if(W.pathname==="/api/serverless/operations/run"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=T.operation?oS(T.operation,h,De,ur):void 0;if(!D)return M({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(D.mutates&&T.confirm!==D.confirm)return M({ok:!1,error:`Type "${D.confirm}" to run this operation.`},409);let U=await we({controlPlane:E,environment:De,actor:Se,kind:`dashboard.serverless.${D.id}`,input:{operation:D.id,min:T.min??null,max:T.max??null},execute:()=>sS(h,De,D,{min:T.min,max:T.max})});return ur=await Ks(h,De),H.set(De,ur),M({...U.result,controlPlaneOperation:U.operation})}if(W.pathname==="/api/serverless/command"&&L.method==="POST"){let T=await L.json().catch(()=>({}));if(T.confirm!=="run")return M({ok:!1,error:'Type "run" to execute this command.'},409);return M(await aS(h,De,String(T.command??"")))}if(W.pathname==="/api/serverless/dlq"&&L.method==="GET"){let T=Number(W.searchParams.get("max"))||10;return M(await cS(h,De,T))}if(W.pathname==="/api/serverless/dlq/redrive"&&L.method==="POST"){let T=await L.json().catch(()=>({}));if(T.confirm!=="redrive")return M({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return M(await dS(h,De,{max:T.max,targetQueue:T.targetQueue}))}if(W.pathname==="/api/serverless/dlq/purge"&&L.method==="POST"){if((await L.json().catch(()=>({}))).confirm!=="purge")return M({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return M(await lS(h,De))}if(W.pathname==="/api/serverless/secrets"&&L.method==="GET")return M({secrets:uS(h,De)});if(W.pathname==="/api/serverless/secrets"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.secretId??"").trim();if(!D)return M({ok:!1,error:"A secret id is required."},422);if(typeof T.value!=="string"||T.value==="")return M({ok:!1,error:"A non-empty value is required."},422);return M(await pS(h,De,D,T.value))}if(W.pathname==="/api/serverless/secrets"&&L.method==="DELETE"){let T=await L.json().catch(()=>({})),D=String(T.secretId??"").trim();if(!D)return M({ok:!1,error:"A secret id is required."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to delete this secret.`},409);return M(await mS(h,De,D))}if(W.pathname==="/api/serverless/functions/config"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.mode??"").trim();if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to update this function.`},409);return M(await gS(h,De,D,{memory:T.memory,timeout:T.timeout}))}if(W.pathname==="/api/serverless/alarms"&&L.method==="GET")return M(await fS(h,De));if(W.pathname==="/api/serverless/alarms"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.preset??"").trim(),U=Number(T.threshold);if(!D)return M({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(U))return M({ok:!1,error:"A numeric threshold is required."},422);return M(await hS(h,De,D,U))}if(W.pathname==="/api/serverless/alarms"&&L.method==="DELETE"){let T=await L.json().catch(()=>({})),D=String(T.name??"").trim();if(!D)return M({ok:!1,error:"An alarm name is required."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to delete this alarm.`},409);return M(await yS(h,De,D))}if(W.pathname==="/api/serverless/traces"&&L.method==="GET"){let T=Number(W.searchParams.get("minutes"))||30;return M(await ju(h,De,T))}if(W.pathname==="/api/serverless/scheduler"&&L.method==="POST"){let T=await L.json().catch(()=>({})),D=String(T.action??"").trim();if(D!=="enable"&&D!=="disable"&&D!=="run")return M({ok:!1,error:"Unknown scheduler action."},422);if(T.confirm!==D)return M({ok:!1,error:`Type "${D}" to ${D} the scheduler.`},409);return M(await Lg(h,De,D))}if(!OS(W.pathname,jn))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(De)}`}});let ma=await dr(Se,De);if(!ma)return Fu("ts-cloud dashboard UI is unavailable.",503);return $S(ma,W.pathname)}catch(bs){if(e.verbose)console.error(bs);return M({ok:!1,error:bs?.message??String(bs)},500)}})();if(!kr)return kr;if(Tt&&(W.pathname.startsWith("/api/")||W.pathname.startsWith("/auth/"))){let dt;if((Je.headers.get("content-type")||"").includes("application/json"))dt=await Je.json().catch(()=>{return});let nn=gr.resolveUser(L),Dr=nn?Ze(nn).actor:void 0;E.store.appendEvent({organizationId:E.organization.id,projectId:E.project.id,actorId:Dr?.id,correlationId:it,type:kr.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:kr.status<400?"info":"warning",payload:L_(L.method,W.pathname,dt,kr.status,Date.now()-Ye)})}return kr.headers.set("x-request-id",it),kr}});xc?.start();let GS=e.spendLoop??!0,vf;if(GS)(async()=>{let{SpendRunner:L,SpendLoopLease:Ge,startSpendLoop:Ye}=await import("./spend/index.js"),{store:Je}=await jS(E.store),it=new L({controlPlane:E.store,store:Je,alerts:ct});vf=Ye(it,{lease:new Ge(E.store,{owner:`dashboard:${process.pid}`}),onError:(Tt)=>console.error(`[ts-cloud] spend cycle failed: ${Tt instanceof Error?Tt.message:String(Tt)}`)})})();let QS=Zs.stop.bind(Zs);return Zs.stop=(L)=>{clearInterval(gf),clearInterval(ff),clearInterval(hf),clearInterval(mf),clearInterval(pf),clearInterval(cf),clearInterval(df),clearInterval(lf),clearInterval(uf),st(),Rr.clear(),xc?.stop(),vf?.();let Ge=QS(L);if(xc)xc.settled().finally(()=>E.store.close());else E.store.close();return Ge},{server:Zs,url:`http://${r}:${Zs.port}/`}}export{co,qg,wd,pA,Ci,Rd,lo,Vg,jg,Or,uo,Dd,qe,Pd,Nd,kd,bi,Lr,zg,Ve,Bd,po,go,mo,xd,_d,Od,Ei,ho,Ld,$r,vi,fo,lt,Kg,$d,Md,Wg,Fd,Ao,qt,Ud,Qd,Hd,Gd,je,Jg,qd,Vt,yo,Io,So,Ti,wi,Mr,Vd,Ri,Co,bo,Fr,jd,Ur,Xg,Yg,ut,Qr,Eo,Zg,zd,Kd,vo,Wd,Jd,Xd,gA,ee,Yd,mA,hA,Di,Pi,fA,de,em,pt,ve,Te,gt,Zd,el,tl,rl,tm,rm,To,nm,im,wo,nl,il,sm,te,om,sl,le,Ro,ze,mt,ht,Hr,Ni,ol,AA,Do,am,cm,dm,lm,Po,No,al,Gr,ko,cl,ki,dl,Bo,xo,_o,Oo,Lo,$o,Mo,Fo,ll,jt,Uo,ul,qr,pl,Qo,Ho,gl,zt,Go,qo,um,yA,Bi,IA,SA,CA,Vo,jo,ml,pm,zo,Vr,hl,xi,fl,Al,yl,Ko,gm,Wo,Il,mm,Jo,hm,jr,zr,Sl,_i,Cl,bl,El,Xo,vl,Tl,fm,wl,S,Rl,Oi,we,Dl,Pl,bA,Nl,Am,EA,vA,TA,ym,Im,wA,RA,Sm,Cm,DA,Li,Kt,Yo,Kr,Wr,Wt,Ke,ft,$i,bm,Jr,kl,Bl,Zo,Em,ea,vm,Tm,xl,ta,Mi,_l,ra,At,Re,Ol,na,ia,Ll,sa,oa,aa,ca,$l,Ml,Xr,da,la,ua,pa,Fl,Fi,Yr,Ui,ga};